mysql组提交优缺点_图解MySQL

引  言

本文是由爱可生研发团队出品的「图解MySQL」系列文章,不定期更新,但篇篇精品。

爱可生开源社区持续运营维护的小目标:

每周至少推送一篇高质量技术文章

每月研发团队发布开源组件新版

每年1024开源一款企业级组件

2019年至少25场社区活动

欢迎大家持续关注~

34646b2b2b32db8b7e818f5773a153d1.gif

前提:

以下讨论的前提 是设置MySQL的crash safe相关参数为双1:

sync_binlog=1

innodb_flush_log_at_trx_commit=1

背景说明:

WAL机制 (Write Ahead Log)定义:

WAL指的是对数据文件进行修改前,必须将修改先记录日志。MySQL为了保证ACID中的一致性和持久性,使用了WAL。

Redo log的作用:

Redo log就是一种WAL的应用。当数据库忽然掉电,再重新启动时,MySQL可以通过Redo log还原数据。也就是说,每次事务提交时,不用同步刷新磁盘数据文件,只需要同步刷新Redo log就足够了。相比写数据文件时的随机IO,写Redo log时的顺序IO能够提高事务提交速度。

组提交的作用:

在没有开启binlog时

Redo log的刷盘操作将会是最终影响MySQL TPS的瓶颈所在。为了缓解这一问题,MySQL使用了组提交,将多个刷盘操作合并成一个,如果说10个事务依次排队刷盘的时间成本是10,那么将这10个事务一次性一起刷盘的时间成本则近似于1。

当开启binlog时

为了保证Redo log和binlog的数据一致性,MySQL使用了二阶段提交,由binlog作为事务的协调者。而 引入二阶段提交 使得binlog又成为了性能瓶颈,先前的Redo log 组提交 也成了摆设。为了再次缓解这一问题,MySQL增加了binlog的组提交,目的同样是将binlog的多个刷盘操作合并成一个,结合Redo log本身已经实现的 组提交,分为三个阶段(Flush 阶段、Sync阶段、Commit阶段)完成binlog 组提交,最大化每次刷盘的收益,弱化磁盘瓶颈,提高性能。

图解:

下图我们假借“渡口运输”的例子来看看binlog 组提交三个阶段的流程:

e96f86baaa7d48e119d644c124d09961.png

在MySQL中每个阶段都有一个队列,每个队列都有一把锁保护,第一个进入队列的事务会成为leader,leader领导所在队列的所有事务,全权负责整队的操作,完成后通知队内其他事务操作结束。

Flush 阶段(图中第一个渡口)

首先获取队列中的事务组

将Redo log中prepare阶段的数据刷盘(图中Flush Redo log)

将binlog数据写入文件,当然此时只是写入文件系统的缓冲,并不能保证数据库崩溃时binlog不丢失 (图中Write binlog)

Flush阶段队列的作用是提供了Redo log的组提交

如果在这一步完成后数据库崩溃,由于协调者binlog中不保证有该组事务的记录,所以MySQL可能会在重启后回滚该组事务

Sync 阶段(图中第二个渡口)

这里为了增加一组事务中的事务数量,提高刷盘收益,MySQL使用两个参数控制获取队列事务组的时机:

binlog_group_commit_sync_delay=N:在等待N μs后,开始事务刷盘(图中Sync binlog)

binlog_group_commit_sync_no_delay_count=N:如果队列中的事务数达到N个,就忽视binlog_group_commit_sync_delay的设置,直接开始刷盘(图中Sync binlog)

Sync阶段队列的作用是支持binlog的组提交

如果在这一步完成后数据库崩溃,由于协调者binlog中已经有了事务记录,MySQL会在重启后通过Flush 阶段中Redo log刷盘的数据继续进行事务的提交

Commit 阶段(图中第三个渡口)

首先获取队列中的事务组

依次将Redo log中已经prepare的事务在引擎层提交(图中InnoDB Commit)

Commit阶段不用刷盘,如上所述,Flush阶段中的Redo log刷盘已经足够保证数据库崩溃时的数据安全了

Commit阶段队列的作用是承接Sync阶段的事务,完成最后的引擎提交,使得Sync可以尽早的处理下一组事务,最大化组提交的效率

缺陷分析:

本文最后要讨论的bug(可通过阅读原文查看)就是来源于Sync阶段中的那个binlog参数binlog_group_commit_sync_delay,在MySQL 5.7.19中,如果该参数不为10的倍数,则会导致事务在Sync 阶段等待极大的时间,表现出来的现象就是执行的sql长时间无法返回。该bug已在MySQL 5.7.24和8.0.13被修复。

1acd30c55160aeb7b7bdf731e2e97b1a.gif

开源分布式中间件DBLE

社区官网:https://opensource.actionsky.com/

GitHub主页:https://github.com/actiontech/dble

技术交流群:669663113

开源数据传输中间件DTLE

社区官网:https://opensource.actionsky.com/

GitHub主页:https://github.com/actiontech/dtle

技术交流群:852990221

058a0dba586baa7011724706cb0370ef.png

8278a51af63a1f7db9136679999c0c8c.gif

喜欢点“分享”,不行就“好看”

4f5bd447e192046c0f6caf632d0a36ac.gif

多喝热水,重启试试

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值