暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

主从延迟图像是一个直角三角形,你知道是什么原因吗?

点击上方蓝字关注我们





文章背景
本文根据KunlunBase交流群群友讨论相关问题而来。KunlunBase(也叫做Klustron)

关键词:redolog、binlog、事务连续性、主备一致性

本文约1600文字,大概阅读时长3分钟。

一个成熟的数据库管理系统,监控是必不可少的。在高可用架构里,至少有一个备库作为standby,目的是在主节点异常时能够切换到备库上,实现服务快速回复。主从延迟的情况,决定了HA系统的切换时间,因此主从延迟的监控也是必不可少的。

理想的主从延迟监控图像是一条y=0的函数图像,表示备节点一直没有延迟(或者说延迟都小于1秒)。

对于更新TPS大的主节点,即使偶尔出现一些1秒的“毛刺”,这也是比较理想的了。


这个图说明偶尔会有延迟达到1秒,但是很快就追上。

有另一个典型的主备延迟图像,是一个直角三角形,如下图。


可以看到,从第3秒开始,每一秒延迟都加1,到第13秒时,延迟突然消失了。这个最常见的原因,是主节点执行了一个大的更新,比如一个事务中update了大量数据,或者一个DDL语句。

这个事务在主节点执行了10秒,传到备库后,也用了10秒的时间执行。在备库应用这个事务时,从监控上看到的就是一个每秒都在增加的延迟图像。

这个延迟在现有的MySQL binlog机制下基本无解。

这就涉及到一个问题,也是KunlunBase技术交流群里的朋友提出来的:在事务执行过程中redolog可以边执行边写,binlog为什么不行呢?

事务执行过程中,可以一边执行一边写redolog,是因为redolog是物理日志,记录的是数据页的修改,而binlog是逻辑日志,记录的是sql语句的行为。运行期间,执行对物理页面修改时就写到redo log buffer,然后由事务提交或者后台专用线程刷到磁盘。

而binlog需要在每个事务提交时才持久化磁盘,这样可以提高性能和恢复速度。如果binlog也采用一边执行一边写的方式,则会出现不同事务的binlog交叉记录,也就是“串了”。

不同事务的binlog交叉记录,会导致下游,比如备库,或者解析binlog的其他接收段,执行时出现逻辑问题。

因此主节点上的binlog只能一个一个完整地写。

对于一个要更新多行的大事务,不能让它一直占用binlog,导致影响其他事务的提交,因此自然地,每个事务要有自己的日志缓存。事务执行过程中,日志先写在本线程自己的binlog缓存中。所有事务都经过三阶段流水线的flush阶段,与当时正在提交的若干个事务在同一个flush阶段成组flush到binlog文件中。

从上面的分析可以看到,一个在主节点执行了10秒的事务,就会导致主从有10秒的延迟,这个看来是无解的。但是这里其实还是有一个可以优化的空间。

在事务日志从binlog缓存写入到binlog日志文件过程中,此时备节点的IO线程状态是等待。因为主节点会在每个事务的binlog完全写完之后,再由binlog dump线程开始发送给备节点。这个是社区版的实现。

实际上,由于此时主节点上也没有别的日志写入,这时候一边写,一边发给备节点,就可以减少备节点的等待时间。也就是说,在主节点的binlog 缓存写入完成后,基本上备节点也收完了事务日志,就可以开始应用这个事务日志。
可以减少备节点的延迟时间。

Klustron团队实现了这个优化,我们来分析一下这个优化会不会引入新问题: 在binlog 缓存写入binlog日志期间,并且备机已经收到一部分这个正在flush 的事务的binlog日志,如果主节点发生异常宕机,会不会有问题。

我们先来看主节点,主节点重启之后,由于binlog文件中的日志不完整,崩溃恢复流程会回滚这个事务。如果这个事务是XA事务,则社区版MySQL无法正确地对其做故障恢复,而kunlun-storage可以正确地对其做故障恢复

备节点上,在社区版本,本来就没有这个事务日志,而我们优化的版本,备节点上有最后一个事务的部分日志,但是也是不完整的。这时候日志应用线程执行到这个事务,执行一半后会回滚。也就是说备节点最后也没有这个事务,这个行为的最终结果是和社区版本一致的。

另一种情况,如果主节点已经完全写完日志,只是备节点还没有收完就发生异常重启,备节点重新连接到主节点后,会重新完整地拉取这个事务的全部binlog并执行它。

顺便一提,社区5.7版本里的一个bug:在备机IO线程开始接收一个普通事务(begin...commit) 的binlog的同时备机工作线程已经开始重放这个事务的情况下,如果IO线程的主备连接因为各种原因(比如主节点宕机)断开,导致备机未完整收到这个事务,那么备机的工作线程会回滚这个事务。但是如果这个事务是XA事务,则社区版MySQL-5.7 无法正确地回滚它,而社区版MySQL-8.0可以正确地回滚它。

在KunlunBase下一个版本中,我们还会用全新的技术手段在kunlun-storage中完全解决MySQL的binlog无法边产生边传输的问题导致的执行大事务时主备延迟变大的问题,彻底解决事务产生的binlog数据量大导致的主备延迟因为随机增大问题,从而进一步提升KunlunBase的高可用能力。









现在,我们发起一轮新的投票,希望就以下问题请教大家,收集大家的反馈。为了感谢您的参与,所有参与问卷调查并留下邮箱联系方式的,由于我们的问卷系统不支持在线抽奖,我们将在后续会统一随机抽取 15 名有效填写者作为幸运参与者,送精美纪念礼品一份,感谢大家参加。
👆扫码填写

END

同时欢迎大家扫码👇添加小助手(备注:加入KunlunBase技术交流群)欢迎大家在交流群共同探讨更多问题及主题。


 点击👆上方,关注获取源代码及技术信息~



推荐阅读


关于我司将 KunlunBase 产品名称改为 Klustron 的通知


技术解读 | KunlunBase多层级并行查询处理技术


技术解读 | KunlunBase全局死锁检测技术


技术解读 | MySQL分布式事务处理的问题和kunlun-storage的解决方案


技术解读 | 深入了解词法分析:从原理到实践


技术解读 | Klustron 数据备份及全局一致性恢复


技术解读|Klustron Mirror表功能介绍和使用示例


MySQL Bug 的处理及修复


MySQL内核研发系列之二 - MySQL测试框架MTR简介

文章转载自KunlunBase 昆仑数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论