MYSQL[快问快答系列]

4核16GB内存1TB固态硬盘,请给我mysql8.0的最优配置my.cnf

[mysqld]
# 基本设置
port = 3306
user = mysql
default_storage_engine = InnoDB
socket = /var/lib/mysql/mysql.sock
pid-file = /var/lib/mysql/mysql.pid

# 日志文件设置
log-error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2
log_queries_not_using_indexes = 1

# 缓存设置
thread_cache_size = 128
table_open_cache = 2048
table_definition_cache = 2048
table_open_cache_instances = 64
query_cache_type = 1
query_cache_size = 64M
query_cache_limit = 4M

# InnoDB存储引擎设置
innodb_buffer_pool_size = 12G //缓冲池大小
innodb_log_file_size = 2G //事务日志文件大小
innodb_flush_log_at_trx_commit = 1 //2为异步,有风险;1为同步,性能较差
innodb_file_per_table = 1 //每个InnoDB表创建单独的数据文件。
innodb_flush_method = O_DIRECT //指定InnoDB使用的磁盘刷新方法。O_DIRECT参数表示数据被直接写入磁盘而不是被缓存到操作系统缓存中。
innodb_io_capacity = 2000 //指定InnoDB磁盘IO容量的预估值。
innodb_io_capacity_max = 4000 //指定InnoDB磁盘IO容量的上限值。

# 线程和连接设置
max_connections = 500 //允许的最大客户端连接数
max_user_connections = 1000 //每个mysql用户允许的最大连接数。如果没有单独设置,则使用全局max_connections值。
thread_stack = 512K //线程分配的堆栈空间
thread_cache_size = 128 //MySQL线程缓存的大小。
wait_timeout = 600 //连接在没有活动操作时被关闭之前的等待时间。
interactive_timeout = 600
connect_timeout = 60

# 其他设置
character_set_server = utf8mb4
collation_server = utf8mb4_unicode_ci

执行一条 select 语句,期间发生了什么?

  • Mysql客户端与Mysql服务端通过三次握手建立TCP连接
  • 验证账号密码
  • 查询缓存,如果命中直接返回(MySQL 8.0 版本直接将查询缓存删掉了)
  • 解析器阶段,进行词法分析,生成语法树
  • 预处理阶段,检查SQL语句中的表或者字段是否存在,将 select * 中的 * 符号扩展为表上的所有列
  • 优化器阶段,基于查询成本的考虑,决定使用什么索引
  • 执行器阶段,开始与存储引擎交互,从存储引擎读取记录,返回给客户端

如何查看 MySQL 服务被多少个客户端连接了?

show processlist;

空闲连接会一直占用着吗?

MySQL 定义了空闲连接的最大空闲时长,由 wait_timeout 参数控制的,默认值是 8 小时(28880秒),如果空闲连接超过了这个时间,连接器就会自动将它断开。

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+

MySQL 的连接数有限制吗?

最大连接数由 max_connections 参数控制,超过这个值,系统就会拒绝接下来的连接请求,并报错提示“Too many connections”。

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 500   |
+-----------------+-------+

怎么解决长连接占用内存的问题?

  • 定期断开长连接
  • 客户端主动重置连接

explain命令

  • possible_keys 字段表示可能用到的索引
  • key 字段表示实际用的索引,如果这一项为 NULL,说明没有使用索引;
  • key_len 表示索引的长度,根据key_len长度来分析联合索引使用了几个
  • rows 表示扫描的数据行数。
  • type 表示数据扫描类型
  • extra 额外信息

type 执行效率从低到高的顺序为:

  • All全表扫描
  • index全索引扫描 比全表扫描好一些,好处是不用再排序
  • range索引范围扫描 尽量让 SQL 查询可以使用到 range 这一级别及以上的 type 访问方式
  • ref非唯一索引扫描
  • eq_ref主键或唯一索引扫描,通常使用在多表联查中
  • const结果只有一条的主键或唯一索引扫描

extra:

  • 覆盖索引 Extra:Using index 效率不错
  • 索引下推 Extra:Using index condition
  • 文件排序 Extra:Using filesort 常见于group by操作 效率低
  • 临时表 Extra:Using temporary 常见于group by/order by操作 效率低

查询一次数据最多需要多少次IO

B+Tree 存储千万级的数据只需要 3-4 层高度就可以满足,即使在数据量很大的情况,查询一个数据的磁盘 I/O 依然维持在 3-4次

什么是回表

先检二级索引中的 B+Tree 的索引值,找到对应的叶子节点,然后获取主键值,然后再通过主键索引中的 B+Tree 树查询到对应的叶子节点,然后获取整行数据。这个过程叫回表,也就是说要查两个 B+Tree 才能查到数据。

什么是覆盖索引

在二级索引的 B+Tree 就能查询到结果的过程就叫作覆盖索引,不需要回表。

什么是索引下推

MySQL 5.6 引入的索引下推优化, 可以在联合索引遍历过程中,对联合索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

字符集utf8,utf8mb4,ascii一个字符分别占用多少字节?

  • utf8 3个
  • utf8mb4 4个 允许存储emoji表情
  • ascii 1个

怎么提高这条SQL效率

select * from order where status = 1 order by create_time asc

建立 status,create_time 联合索引,避免文件排序

什么时候使用索引

  • 字段有唯一性限制的
  • 经常用于 WHERE 查询条件的字段
  • 经常用于 GROUP BY 和 ORDER BY 的字段

什么时候不使用索引

  • WHERE 条件,GROUP BY,ORDER BY 里用不到的字段
  • 字段中存在大量重复数据,不需要创建索引
  • 表数据太少的时候,不需要创建索引
  • 经常更新的字段不用创建索引

索引列为什么最好设置为Not Null

  • 索引列存在 NULL 就会导致优化器在做索引选择的时候更加复杂,更加难以优化
  • NULL 值是一个没意义的值,但是它会占用物理空间,至少每行都会用1字节空间存储 NULL 值列表

索引什么时候失效

  • like %xx 或者 like %xx%
  • 对索引列做了计算、函数、类型转换操作
  • 没有按照最左优先的方式进行索引的匹配
  • 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列

Innodb为什么选择B+tree

  • Hash
    Hash 在做等值查询的时候效率贼快,搜索复杂度为 O(1)。
    但是 Hash 表不适合做范围查询,它更适合做等值的查询
  • 二叉树
    数据量越大,二叉树高越高,磁盘IO越多,B+Tree再千万级别的数据量下只用3-4层
  • B Tree
    相同数据量时,B+Tree树高比BTree低,磁盘IO次数更少
    B+Tree叶子节点用双向链表串起来,适合范围查询,BTree无法做到这点

如何添加测试数据

CREATE TABLE person(
    id int NOT NULL AUTO_INCREMENT PRIMARY KEY comment '主键',
    person_id tinyint not null comment '用户id',
    person_name VARCHAR(200) comment '用户名称',
    gmt_create datetime comment '创建时间',
    gmt_modified datetime comment '修改时间'
) comment '人员信息表';

添加一条数据

insert into person values(1, 1,'user_1', NOW(), now());

以下sql执行20次 约等于100万条数据执行24次1600万条数据

INSERT INTO person ( person_id, person_name, gmt_create, gmt_modified ) SELECT LEFT
( rand()* 10, 10 ) AS person_id,
concat( 'user_', LEFT ( rand()* 10, 10 ) % 2048 ),
date_add( gmt_create, INTERVAL + @i * cast( rand()* 100 AS signed ) SECOND ),
date_add(
    date_add( gmt_modified, INTERVAL + @i * cast( rand()* 100 AS signed ) SECOND ),
    INTERVAL + cast( rand()* 1000000 AS signed ) SECOND 
) 
FROM
    person;

MySQL单表为什么最好不要超过2000W

超过了这个值可能会导致 B + 树层级更高,影响查询性能。

MySQL 使用 like “%x“,索引一定会失效吗?

不一定,如果扫描了二级索引就能得到结果,就不用回表,直接返回数据,这个时候 explain的type是 index

count(*) 和 count(1) 有什么区别?哪个性能最好?

count() 执行过程跟 count(1) 执行过程基本一样的,性能没有什么差异。而且 MySQL 会对 count() 和 count(1) 有个优化,如果有多个二级索引的时候,优化器会使用key_len 最小的二级索引进行扫描。只有当没有二级索引的时候,才会采用主键索引来进行统计。

如何优化 count(*)?

  • 近似值
    explain select count(*) from t_order
    会返回一个近似值rows
  • 额外表保存计数值
    插入一条记录的同时,将计数表字段+1,新增和删除的时候需要额外维护这个计数器,存在redis也行

事务有哪些特性?

  • 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成
  • 一致性(Consistency):事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。
  • 隔离性(Isolation):每个事务都有一个完整的数据空间,对其他并发事务是隔离的。
  • 持久性(Durability):事务处理结束后,对数据的修改就是永久的

InnoDB 引擎通过什么技术来保证事务的这四个特性的呢?

  • 持久性是通过 redo log (重做日志)来保证的;
  • 原子性是通过 undo log(回滚日志) 来保证的;
  • 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
  • 一致性则是通过持久性+原子性+隔离性来保证;

事务的隔离级别有哪些?

  • 读未提交(read uncommitted,指一个事务还没提交时,它做的变更就能被其他事务看到;
  • 读提交(read committed,指一个事务提交之后,它做的变更才能被其他事务看到;
  • 可重复读(repeatable read,指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别
  • 串行化(serializable;会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

MySQL InnoDB 怎么避免幻读现象?

  • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。
  • 针对当前读(select … for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select … for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。

快照读和当前读有什么区别?

MySQL 里除了普通查询是快照读,其他都是当前读,比如 update、insert、delete,这些语句执行前都会查询最新版本的数据。
另外,select ... for update 这种查询语句是当前读,每次执行的时候都是读取最新的数据。

既然备份数据库数据的时候,使用全局锁会影响业务,那有什么其他方式可以避免?

在使用 mysqldump 时加上 –single-transaction 参数的时候,就会在备份数据库之前先开启事务。因为在可重复读的隔离级别下,即使其他事务更新了表的数据,也不会影响备份数据库时的 Read View,这就是事务四大特性中的隔离性,这样备份期间备份的数据一直是在开启事务时的数据。

MySQL 死锁了,怎么办?

  • 设置事务等待锁的超时时间,当一个事务的等待时间超过该值后,就对这个事务进行回滚,于是锁就释放了,另一个事务就可以继续执行了。在 InnoDB 中,参数 innodb_lock_wait_timeout 是用来设置超时时间的,默认值时 50 秒。
  • 开启主动死锁检测。主动死锁检测在发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑,默认就开启。
  • 分析产生死锁的业务逻辑,考虑怎么去掉select …for update导致产生的死锁

为什么需要 undo log?

  • 实现事务回滚,保障事务的原子性。。
  • 实现 MVCC(多版本并发控制)关键因素之一。

为什么需要 缓冲池 Buffer Pool?

  • 当读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。
  • 当修改数据时,如果数据存在于 Buffer Pool 中,那直接修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘
  • Buffer Pool 除了缓存「索引页」和「数据页」,还包括了 Undo 页,插入缓存、自适应哈希索引、锁信息等等。

查询一条记录,就只需要缓冲一条记录吗?

不对,当我们查询一条记录时,InnoDB 是会把整个页的数据加载到 Buffer Pool 中

为什么需要 redo log ?

为了防止断电导致数据丢失的问题,当有一条记录需要更新的时候,InnoDB 引擎就会先更新内存(同时标记为脏页),然后将本次对这个页的修改以 redo log 的形式记录下来
当系统崩溃时,虽然脏页数据没有持久化,但是 redo log 已经持久化,接着 MySQL 重启后,可以根据 redo log 的内容,将所有数据恢复到最新的状态。

redo log 和 undo log 区别在哪?

  • redo log 记录了此次事务「完成后」的数据状态,记录的是更新之后的值;
  • undo log 记录了此次事务「开始前」的数据状态,记录的是更新之前的值;
  • 事务提交之前发生了崩溃,重启后会通过 undo log 回滚事务,事务提交之后发生了崩溃,重启后会通过 redo log 恢复事务,如下图:

redo log 什么时候刷盘?

  • MySQL 正常关闭时;
  • 当 redo log buffer 中记录的写入量大于 redo log buffer 内存空间的一半时,会触发落盘;
  • InnoDB 的后台线程每隔 1 秒,将 redo log buffer 持久化到磁盘。
  • 每次事务提交时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘(这个策略可由 innodb_flush_log_at_trx_commit 参数控制,下面会说)。

为什么需要 binlog ?

binlog 文件是记录了所有数据库表结构变更和表数据修改的日志,不会记录查询类的操作,比如 SELECT 和 SHOW 操作。

redo log 和 binlog 有什么区别?

  • binlog 是 MySQL 的 Server 层实现的日志,所有存储引擎都可以使用,用于备份恢复、主从复制;
  • redo log 是 Innodb 存储引擎实现的日志, 用于掉电等故障恢复。

如果不小心整个数据库的数据被删除了,能使用 redo log 文件恢复数据吗?

不可以使用 redo log 文件恢复,只能使用 binlog 文件恢复。

主从复制是怎么实现?

  • 写入 Binlog:主库写 binlog 日志,提交事务,并更新本地存储数据。
  • 同步 Binlog:把 binlog 复制到所有从库上,每个从库把 binlog 写到暂存日志中。
  • 回放 Binlog:回放 binlog,并更新存储引擎中的数据。

从库是不是越多越好?

不是的。
因为从库数量增加,从库连接上来的 I/O 线程也比较多,主库也要创建同样多的 log dump 线程来处理复制的请求,对主库资源消耗比较高,同时还受限于主库的网络带宽
所以在实际使用中,一个主库一般跟 2~3 个从库(1 套数据库,1 主 2 从 1 备主),这就是一主多从的 MySQL 集群结构。

为什么需要两阶段提交?

MySQL 会同时维护 binlog 日志与 InnoDB 的 redo log,为了保证这两个日志的一致性,MySQL 使用了内部 XA 事务

MySQL 磁盘 I/O 很高,有什么优化的方法?

  • 设置组提交的两个参数: binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 参数,延迟 binlog 刷盘的时机,从而减少 binlog 的刷盘次数。这个方法是基于“额外的故意等待”来实现的,因此可能会增加语句的响应时间,但即使 MySQL 进程中途挂了,也没有丢失数据的风险,因为 binlog 早被写入到 page cache 了,只要系统没有宕机,缓存在 page cache 里的 binlog 就会被持久化到磁盘。
  • 将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000),表示每次提交事务都 write,但累积 N 个事务后才 fsync,相当于延迟了 binlog 刷盘的时机。但是这样做的风险是,主机掉电时会丢 N 个事务的 binlog 日志。
  • 将 innodb_flush_log_at_trx_commit 设置为 2。表示每次事务提交时,都只是缓存在 redo log buffer 里的 redo log 写到 redo log 文件,注意写入到「 redo log 文件」并不意味着写入到了磁盘,因为操作系统的文件系统中有个 Page Cache,专门用来缓存文件数据的,所以写入「 redo log文件」意味着写入到了操作系统的文件缓存,然后交由操作系统控制持久化到磁盘的时机。但是这样做的风险是,主机掉电的时候会丢数据。

你知道mysql主从延迟吗?有些时候延迟的时间还会很长。遇到这种情况咋么办?

  • 多线程复制
    确保使用了多线程复制,并且已经按照手册查看了如何调整各种选项以从中获得最佳效率。
  • 调整 binlog 格式
    调整为 statement 减小binlog容量
  • 临时降低持久化要求
    可以临时设置
    sync_binlog=0,
    innodb_flush_log_at_trx_commit=0
    以提高复制速度。

怎么定位运行中的MySQL使用哪个配置文件

> which mysqld
/usr/sbin/mysqld
> /usr/sbin/mysqld --verbose --help | grep -A 1 'Default options'
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf 

为什么不建议字段格式为null

如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值比较都更复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理。

储存财务数据,BIGINT 还是 DECIMAL

假设要存储财务数据并精确到万分之一分,则可以把所有金额乘以一百万然后将结果存储在BIGINT里,这样可以同时避免浮点存储计算不精确和DECIMAL精确计算代价高的问题。

VARCHAR和CHAR的区别

  • VARCHAR
    VARCHAR需要额外使用1或2字节在每行数据前记录字符串的长度:如果最大长度<=255字节,则只使用1字节表示,否则使用2字节。VARCHAR节省了存储空间,所以对性能也有帮助。但是,由于行是可变长度的,在更新时可能会增长,这会导致InnoDB需要分割页面来容纳行,InnoDB将过长的VARCHAR值存储为BLOB

  • CHAR
    当存储CHAR值时,MySQL删除所有尾随空格。如果需要进行比较,值会用空格填充。CHAR适合存储用户密码的MD5值。对于经常修改的数据,CHAR也比VARCHAR更好,因为固定长度的行不容易出现碎片。对于非常短的列,CHAR也比VARCHAR更高效;设计为只保存Y和N的值的CHAR(1)在单字节字符集[1]中只使用1字节,但VARCHAR(1)需要2字节

如何查询各个数据表储存大小

mysql> select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)' from information_schema.tables where table_schema='test' order by data_length desc, index_length desc;
+-----------+----------------------+-----------+------------------+------------------+
| 数据库    | 表名                 | 记录数    | 数据容量(MB)     | 索引容量(MB)     |
+-----------+----------------------+-----------+------------------+------------------+
| test     | wd_admin_log         |       383 |             0.20 |             0.01 |
+-----------+----------------------+-----------+------------------+------------------+

DATETIME 还是 TIMESTAMP

  • DATETIME
    可以保存大范围的数值,从1000年到9999年,精度为1微秒。它以YYYYMMDDHHMMSS格式存储压缩成整数的日期和时间,且与时区无关。这需要8字节的存储空间。
  • TIMESTAMP
    存储自1970年1月1日格林尼治标准时间(GMT)午夜以来经过的秒数,只使用4字节的存储空间,只能表示从1970年到2038年1月19日,MySQL提供FROM_UNIXTIME()函数来将UNIX时间戳转换为日期,并提供了UNIX_TIMESTAMP()函数将日期转换为UNIX时间戳。
  • 结论
    使用带符号的32位INT,可以表达直到2038年的时间。使用无符号的32位INT,可以表达直到2106年的时间。如果使用64位,还可以超出这些范围。这一做法越来越流行。

可以对保存md5(),sha1(),uuid()的列做索引吗?

这些函数生成的新值会任意分布在很大的空间内,这会减慢
INSERT和某些类型的SELECT查询的速度

  • 因为插入的值会写到索引的随机位置,所以会使得INSERT查询变慢。这会导致页分裂、磁盘随机访问,以及对于聚簇存储引擎产生聚簇索引碎片。
  • SELECT查询也会变慢,因为逻辑上相邻的行会广泛分布在磁盘和内存中。

IPV4地址用什么数据类型?

用过函数转成int 然后用 unsigned int存储

MySQL schema设计中的有什么骚操作(错误示范)?

  • 太多的列
    MySQL的存储引擎API通过在服务器和存储引擎之间以行缓冲区格式复制行来工作,InnoDB的行格式总是需要转换的。这种转换的成本取决于列数。
  • 太多的联接
    MySQL限制每个联接有61个表
  • 全能的枚举
    MYSQL[快问快答系列]

如何不停机不锁表地更新表结构?

  • pt-online-schema-change:原理是使用触发器,对已经使用触发器的表不太兼容
  • gh-ost:原理是使用binlog,对使用外键的表不太兼容
  • 怎么选择
    如果你正在运行许多已存在外键的旧数据库,并且删除外键是很困难的,那么会发现pt-online-schema-change已经尝试对外键提供更广泛的支持,但你必须承担为数据完整性和正常运行时间选择最安全选项的认知负担。此外,gh-ost利用binlog来完成其工作,因此如果由于某种原因无法访问这些日志,pt-online-schema-change仍然是一个可行的选项。

INNODB 自适应哈希索引特性?

当InnoDB发现某些索引值被非常频繁地被访问时,它会在原有的B-tree索引之上,在内存中再构建一个哈希索引。这就可以实现非常快速的哈希查找。这个过程是完全自动化的,用户可以通过参数关闭这个特性。

如何减少索引和数据的碎片

通过执行OPTIMIZE TABLE或者导出再导入的方式来重新整理数
据。

联接查询怎么优化?

  • 确保ON或者USING子句中的列上有索引。
  • 确保任何GROUP BY和ORDER BY中的表达式只涉及一个表中的列,这样MySQL才有可能使用索引来优化这个过程。

怎么优化大表limit offset

# 错误示范
select id,description from film order by title limit 50, 5
# 正确示范
select id,description from film inner join (select id from film order by title limit 50,5) as lim using (id)

复制如何工作

  • 主库把数据更改记录到binlog
  • 从库启动线程1把主库的binlog复制到自己的中继日志
  • 从库启动线程2重放中继日志

binlog_format有多少种日志格式?

  • STATEMENT
    表示在binlog文件中只记录SQL语句。这是默认值,优点是简单紧凑容量小,其最大的弊端则在于会遇到某些具有“不确定性”的SQL语句问题
  • ROW
    表示在binlog文件中只记录受影响的行。在这种格式下,MySQL会将对数据的更改记录为行级别的操作。这种格式可以更准确地记录数据更改,但会导致binlog文件更大。
  • MIXED
    表示在binlog文件中既记录SQL语句,又记录受影响的行。MySQL会自动选择适当的格式来记录数据更改。这是最常用的格式,因为它可以平衡可读性和性能。
  • 结论
    我们(高性能MYSQL第四版)建议坚持使用基于行的复制ROW,除非某些场景下明确需要临时使用基于语句的复制。基于行的复制提供了最安全的数据复制方法。

怎么保证崩溃后的复制安全

#保证每个undo log都被同步地写到磁盘,增加磁盘写入操作频次,确保数据持久性
innodb_flush_log_at_trx_commit=1

#每次事务执行的时候都会把二进制日志同步写入磁盘。增加磁盘写入操作频次,防止丢失事务
sync_binlog=1

#使用 InnoDB 存储引擎存储中继日志信息,提供更好的可靠性和性能。
relay_log_info_repository=TABLE

#在复制过程中发生错误时自动尝试使用中继日志进行恢复
relay_log_recovery=ON

延迟复制有什么用

想象一下这样的场景,你正在处理大量数据,突然意外地做了一些变更:删除了一个表。从备份中恢复可能需要几个小时。如果使用了延迟复制的副本,则可以找到DROP TABLE语句对应的GTID,使副本服务器的复制运行到表被删除之前的时间点,这会大大减少修复时间。

什么是多线程复制?

最新的MySQL版本则提供了多线程复制能力,可以在副本端运行多个SQL线程,从而加快本地中继日志的应用。

什么是半同步复制?

在半同步复制中,主服务器会等待至少一个从服务器将更新成功复制后,才会返回客户端。确保至少一个从服务器成功复制了更新,降低故障恢复的成本,缺点是会影响主服务器的性能

本作品采用《CC 协议》,转载必须注明作者和本文链接
遇强则强,太强另说
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!