mysql5.7组提交_MySQL5.7的组提交与并行复制

从MySQL5.5版本以后,开始引入并行复制的机制,是MySQL的一个非常重要的特性。

MySQL5.6开始支持以schema为维度的并行复制,即如果binlog row event操作的是不同的schema的对象,在确定没有DDL和foreign key依赖的情况下,就可以实现并行复制。

社区也有引入以表为维度或者以记录为维度的并行复制的版本,不管是schema,table或者record,都是建立在备库slave实时解析row格式的event进行判断,保证没有冲突的情况下,进行分发来实现并行。

MySQL5.7的并行复制,multi-threaded slave即MTS,期望最大化还原主库的并行度,实现方式是在binlog event中增加必要的信息,以便slave节点根据这些信息实现并行复制。

MySQL 5.7的并行复制建立在group commit的基础上,所有在主库上能够完成prepared的语句表示没有数据冲突,就可以在slave节点并行复制。

关于MySQL5.7的组提交,我们要看下以下的参数:

mysql> show global variables like '%group_commit%';+-----------------------------------------+-------+

| Variable_name | Value |

+-----------------------------------------+-------+

| binlog_group_commit_sync_delay | 0 |

| binlog_group_commit_sync_no_delay_count | 0 |

+-----------------------------------------+-------+

2 rows in set (0.00 sec)

binlog_group_commit_sync_delay这个参数控制着日志在刷盘前日志提交要等待的时间,默认是0也就是说提交后立即刷盘,但是并不代表是关闭了组提交,当设置为0以上的时候,就允许多个事物的日志同时间一起提交刷盘,也就是我们说的组提交。组提交是并行复制的基础,我们设置这个值的大于0就代表打开了组提交的延迟功能,而组提交是默认开启的。最大值只能设置为1000000微妙。

binlog_group_commit_sync_no_delay_count ,这个参数表示我们在binlog_group_commit_sync_delay等待时间内,如果事物数达到binlog_group_commit_sync_no_delay_count 设置的参数,就会触动一次组提交,如果这个值设为为0的话就不会有任何的影响。如果到达时间但是事物数并没有达到的话,也是会进行一次组提交操作的。

组提交是个比较好玩的方式,我们根据MySQL的binlog就可以看得到组提交到底是怎么回事:

[root@mxqmongodb2 log]# mysqlbinlog mysql-bin.000005 |grep last_committed

#170607 11:24:57 server id 353306 end_log_pos 876350 CRC32 0x92093332 GTID last_committed=654 sequence_number=655#170607 11:24:58 server id 353306 end_log_pos 880406 CRC32 0x344fdf71 GTID last_committed=655 sequence_number=656#170607 11:24:58 server id 353306 end_log_pos 888700 CRC32 0x4ba2b05b GTID last_committed=656 sequence_number=657#170607 11:24:58 server id 353306 end_log_pos 890675 CRC32 0xf8a8ad64 GTID last_committed=657 sequence_number=658#170607 11:24:58 server id 353306 end_log_pos 892770 CRC32 0x127f9cdd GTID last_committed=658 sequence_number=659#170607 11:24:58 server id 353306 end_log_pos 894757 CRC32 0x518abd93 GTID last_committed=659 sequence_number=660#170607 11:37:46 server id 353306 end_log_pos 895620 CRC32 0x99174f95 GTID last_committed=660 sequence_number=661#170607 11:37:51 server id 353306 end_log_pos 895897 CRC32 0xb4ffc341 GTID last_committed=661 sequence_number=662#170607 11:38:00 server id 353306 end_log_pos 896174 CRC32 0x6bcbc492 GTID last_committed=662 sequence_number=663#170607 11:39:40 server id 353306 end_log_pos 896365 CRC32 0x1fe16c7c GTID last_committed=663 sequence_number=664

上面是没有组提交的一个日志,我们可以看得到binlog当中有两个参数last_committed和sequence_number,我们可以看到,下一个事物的last_committed永远都和上一个事物的sequence_number是相等的。这也很容易理解,因为事物是顺序提交的,这么理解起来并不奇怪。

下面看一下组提交模式的事物:

[root@mxqmongodb2 log]# mysqlbinlog mysql-bin.000008|grep last_commit

#170609 10:11:07 server id 353306 end_log_pos 75629 CRC32 0xd54f2604 GTID last_committed=269 sequence_number=270#170609 10:13:03 server id 353306 end_log_pos 75912 CRC32 0x43675b14 GTID last_committed=270 sequence_number=271#170609 10:13:24 server id 353306 end_log_pos 76195 CRC32 0x4f843438 GTID last_committed=270 sequence_number=272

我们可以看到最后两个事物的last_committed是相同的,这意味什么呢,意味着两个事物是作为一个组提交的,两个事物在perpare截断获取相同的last_committed而且相互不影响,最终是会作为一个组进行提交。这就是所谓的组提交。

#MTS

slave-parallel-type=LOGICAL_CLOCK

slave-parallel-workers=8 #太多的线程会增加线程间同步的开销,建议4-8个slave线程

master_info_repository=TABLErelay_log_info_repository=TABLErelay_log_recovery=ONslave-parallel-type有两个之,DATABASE和LOGICAL_CLOCK,DATABASE: 默认值,兼容5.6以schema维度的并行复制, LOGICAL_CLOCK: MySQL 5.7基于组提交的并行复制机制。

综合来说,MySQL5.7的并行复制是基于group commit和从库以下参数的配置:mysql> show variables like '%slave_para%';

+------------------------+---------------+

| Variable_name | Value |

+------------------------+---------------+

| slave_parallel_type | LOGICAL_CLOCK |

| slave_parallel_workers | 8 |

+------------------------+---------------+

2 rows in set (0.01 sec)

要想使用MySQL5.7的并行复制,必须首先主库必须标记某几个事物是同时提交,也就是last_commited的值是相同的擦灰在从库上并行回放,然后在从库设置线程数和相关的方式。我们上面设置的是8,再从库就能看到

mysql>show processlist;+----+-------------+--------------------+------+---------+--------+--------------------------------------------------------+------------------+

| Id | User | Host | db | Command | Time | State | Info |

+----+-------------+--------------------+------+---------+--------+--------------------------------------------------------+------------------+

| 1 | system user | | NULL | Connect | 373198 | Waiting for master to send event | NULL |

| 2 | system user | | NULL | Connect | 1197 | Slave has read all relay log; waiting for more updates | NULL |

| 4 | system user | | NULL | Connect | 4292 | Waiting for an event from Coordinator | NULL |

| 5 | system user | | NULL | Connect | 373198 | Waiting for an event from Coordinator | NULL |

| 6 | system user | | NULL | Connect | 373198 | Waiting for an event from Coordinator | NULL |

| 7 | system user | | NULL | Connect | 373198 | Waiting for an event from Coordinator | NULL |

| 8 | system user | | NULL | Connect | 373198 | Waiting for an event from Coordinator | NULL |

| 9 | system user | | NULL | Connect | 373198 | Waiting for an event from Coordinator | NULL |

| 10 | system user | | NULL | Connect | 373198 | Waiting for an event from Coordinator | NULL |

| 11 | system user | | NULL | Connect | 373198 | Waiting for an event from Coordinator | NULL |

| 16 | root | 172.16.16.34:37263 | NULL | Query | 0 | starting | show processlist |

+----+-------------+--------------------+------+---------+--------+--------------------------------------------------------+------------------+

从库会有八个线程来等待事物处理,已经不是一个了。

最近好友看到我的文章,指出了一些错误的理解。感谢,我大概又测试了一下。首先我们的环境还是不变的,我们有一主两从的一套MySQL高可用结构,A(主),B(MTS从),C(普通从库)三个MySQL数据库,版本5.7

我们的设置

mysql> show variables like 'binlog_group_commit_sync_delay';+--------------------------------+-------+

| Variable_name | Value |

+--------------------------------+-------+

| binlog_group_commit_sync_delay | 0 |

+--------------------------------+-------+

1 row in set (0.00 sec)

下面先在主库进行压测,主库A上进行压力测试。然后观看三个数据库的日志。

[root@mxqmongodb2 tpcc-mysql]# ./tpcc_start -h127.0.0.1 -P3306 -d tpcc -u root -p123456 -w 10 -c 50 -r 30 -l 300

压测结束开始看日志信息:

[root@localhost log]# mysqlbinlog /home/mysql/db3306/log/mysql-bin.000013 |grep last_commit

首先上A主库的:

c05c6a323f63fcc7c27923666d9ca1f4.png

然后看B,开启多线程复制的从库的日志信息

23043ea45c9dcd393e45d9370d43f801.png

接下来看C普通复制从库的日志信息:

9aa60ca9700f8ac0a97304a6b9855e64.png

通过对比发现,主库由于并没有开启组提交,但是也是并行执行的,也就是说在MySQL5.7当中,组提交是默认开启的,而binlog_group_commit_sync_delay参数相对来说是因为考虑到从库的性能,能够更多的一次性提交多个事物提交来减少IO,所以开启了组提交的B从库,事物是分组提交的,这也就是说明,MTS本身就是基于组提交来实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值