只是简单记录一下可能的原因,8.0.28 单主主节点
-
这个gap不是参数group_replication_gtid_assignment_block_size导致的。 -
这个gap和MTS的并发出现的gap也不是一回事。
问题展示
8.0.28 压测期间发现类似如下的GAP。
mysql> show master status G
*************************** 1. row ***************************
File: mysql-bin.000016
Position: 8662025
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 00743881-cdbb-11ec-9895-000c2949bc85:1-239566:239568-239571
可以看到这里只有239567是gap,但是接着马上就填平了。以前没有仔细注意过这个问题,今天稍微想了一下,是有可能的。
原理简析
这里就简单的说下原理,首先各个session线程事务提交的事务会通过group_replication_trans_before_commit进入MGR层,然后通过GCS做消息的各种处理,然后进入到XCOM层做一致性协议,然后流出后由xengine线程处理并且做认证,即便是单主也要过认证函数,当然不做认证,会生成GTID。然后主库的事务就会继续提交,备节点就会进入relay log。
这里如果是主库就实际上是移交处理事务的权利给了MySQL层,各个session拿到通过了MGR层的事务后,开始自己的提交也就是我们说的order commit,而我们的GTID展示给大家是在order commit的commit阶段。
虽然各个session拿到提交权利的时候是有序的(单线程xengine过认证模块是有序的),但是权利移交后就是多线程处理了,代码处理的速度有快有慢,线程还可能丢失CPU,到了order commit的时候顺序就不一定了。这里实际上如果把GTID的生成和展示看成一个临界区,那么这个临界区太大了,不可能上mutex。简单搞个箭头示意如下:
这个时候可能就是1:3 中间的GTID 2占时没有展示出来,但是很快就会补全。最简单的理解试试打了个时间差。
但是需要注意的是单库的话没有这个问题,因为生成GTID是上了mutex的,而且flush/fsync/commit 队列是顺序的。
测试验证
这个问题如果要必现,肯定是要加一两句代码的,不然依靠操作系统和硬件很难必现,目的在于用随机sleep来模拟丢失CPU的情况。也就是各个session获取事务处理的权利后加个随机sleep的语句,如下:
8.0.23:MYSQL_BIN_LOG::commit
vi binlog.cc +8155
{int x = (int)(xid%5);sleep(x);}
这里就是在group_replication_trans_before_commit完成后在order commit之前通过xid来取个数字,这个数字就是最大5秒,轮训的这是因为XID是有序的,那么每个事务提交都会等待0-5秒,那么就可以了,然后用sysbench压一下,当然TPS很感人(因为每个事务都要休眠0-5秒),重现如下:
因此试验证明原理是正确的,这种现象在MGR主节点出现也是正常的。
以上。。。
原文始发于微信公众号(MySQL学习):MySQL:MGR主节点GTID还有少量gap?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/20183.html