引 言

前提:

  • 以下讨论的前提 是设置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 组提交三个阶段的流程:

在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被修复。

到此这篇关于mysql组提交(group commit)的文章就介绍到这了,更多相关mysql组提交内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

发表评论

后才能评论