数据库复制的主要性能问题就是数据延时
为了优化复制性能,Mysql 5.6 引入了 “多线程复制” 这个新功能
但 5.6 中的每个线程只能处理一个数据库,所以如果只有一个数据库,或者绝大多数写操作都是集中在某一个数据库的,那么这个“多线程复制”就不能充分发挥作用了
Mysql 5.7 对 “多线程复制” 进行了改善,可以按照逻辑时钟的方式来分配线程,大大提高了复制性能
下面看一下在5.7中如何配置 “多线程复制”
1、查看当前复制模式
可以看到只有一个复制线程在工作
2、设置并发同步类型为逻辑时钟方式
查看默认的并发复制类型
mysql> show variables like 'slave_parallel_type';
+---------------------+----------+
| Variable_name | Value |
+---------------------+----------+
| slave_parallel_type | DATABASE |
+---------------------+----------+
1 row in set (0.00 sec)
默认是datebase,每个线程只能处理一个数据库
配置成基于逻辑时钟的方式
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
mysql> set global slave_parallel_type='logical_clock';
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'slave_parallel_type';
+---------------------+---------------+
| Variable_name | Value |
+---------------------+---------------+
| slave_parallel_type | LOGICAL_CLOCK |
+---------------------+---------------+
1 row in set (0.01 sec)
mysql>
3、设置复制线程的数量
#查看下当前的复制线程数,默认都是0
mysql> show variables like 'slave_parallel_workers';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| slave_parallel_workers | 0 |
+------------------------+-------+
1 row in set (0.00 sec)
#适当调整,我这里设置的是4
mysql> set global slave_parallel_workers=4;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'slave_parallel_workers';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| slave_parallel_workers | 4 |
+------------------------+-------+
1 row in set (0.01 sec)
4、配置从库回放顺序
slave_preserve_commit_order 参数在多线程复制环境下,能够保证从库回放relay log事务的顺序与这些事务在relay log中的顺序完全一致,也就是与主库提交的顺序完全一致。
举个例子,开启并行复制后,如果relay log中有3个事务A,B,C,他们在relay log中的顺序是A->B->C,而它们的last_commited相同,也就是说他们可以并行回放,那么在从库上,这3个事务,提交的顺序可能就不再是A->B->C,设置slave_preserve_commit_order=ON,能够保证这3个事务,在从库回放时,仍然按照它们在relay log中的顺序来回放,保证从库回放relay log事务的顺序与主库完全相同。
slave_preserve_commit_order:
作用范围:Global
动态修改:Yes,修改时需要停止SQL线程
默认值:OFF
该参数起作用的前提条件是开启多线程复制:
slave_parallel_type=LOGICAL_CLOCK
slave_parallel_workers>0
在 8.0.18 及之前版本,从库只有开启binlog的两个参数(log_bin,log_slave_updates),才能设置slave_preserve_commit_order=ON,而 8.0.19 版本开始,这个前提条件不再需要了。
设置slave_preserve_commit_order=ON,当一个线程等待其他线程的事务提交时,会出现一个状态信息,在一个写入量较大的主从复制集群中,在从库上执行show processlist可以看到这个状态信息,如下:
Waiting for preceding transaction to commit
5、设置事件所需的内存大小
mysql> set global slave_pending_jobs_size_max= 536970912;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show variables like '%slave_pending_jobs_size_max%';
+-----------------------------+-----------+
| Variable_name | Value |
+-----------------------------+-----------+
| slave_pending_jobs_size_max | 536970240 |
+-----------------------------+-----------+
1 row in set (0.01 sec)
从库回放线程的时间内存大小默认为16M,这个参数不一定非要修改,但是一定要大于主库设置的max_allowed_packet。
负责我们放回时可能就会报错,具体参考下面的报错信息
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1864
Last_Error: Cannot schedule event Write_rows, relay-log name ./mysql-relay-bin.001304, position 416228895 to Worker thread because its size 16777357 exceeds 16777216 of slave_pending_jobs_size_max.
6、统一配置文件
以上参数,全部可以在从库的配置文件中添加上,然后重启数据库
slave_parallel_type= LOGICAL_CLOCK
slave_parallel_workers= 4
slave_preserve_commit_order= 1
slave_pending_jobs_size_max= 536870912
log_slave_updates =1