MySQL 组提交(group commit)
程序员文章站
2022-11-22 09:08:33
[toc] 前言 操作系统使用 页面缓存 来填补内存和磁盘访问的差距 对磁盘文件的写入会先写入道页面缓存中 由操作系统来 决定何时 将修改过的脏页刷新到磁盘 确保修改已经持久化到磁盘,须调用 fsyn c或者 fdatasync 数据库在事务提交过程中调用fsync将数据持久化到磁盘,才满足 ACI ......
前言
- 操作系统使用页面缓存来填补内存和磁盘访问的差距
- 对磁盘文件的写入会先写入道页面缓存中
- 由操作系统来决定何时将修改过的脏页刷新到磁盘
- 确保修改已经持久化到磁盘,须调用fsync或者fdatasync
- 数据库在事务提交过程中调用fsync将数据持久化到磁盘,才满足acid中的d(持久化)
- fsync是昂贵的操作,对于普通磁盘,每秒能完成几百次fsync
- mysql中使用了两阶段提交协议,为了满足d(持久化) ,一次事务提交最多会导致3次fsync
- 提交的事务在存储引擎内部(redo log)中准备好,一次fsync;事务写入到binlog中并刷盘持久化,一次fsync;事务在存储引擎内部提交,一次fsync(可以省略,存储引擎准备好的事务可以通过binlog来恢复)
改进
- 为了提高单位时间内的事务提交数,必须减少事务提交过程中的fsync调用次数
- mysql 从5.6版本开始引入group commit技术(mariadb 5.3版本引入)
- 基本思想是多个并发提交的事务共用一次fsync操作来实现持久化
group commit
an innodb optimization that performs some low-level i/o operations (log write) once for a set of commit operations, rather than flushing and syncing separately for each commit
原理
- 多个并发需要提交的事务共享一次fsync操作来进行数据的持久化
- 将fsync操作的开销平摊到多个并发的事务上去
- group commit 不是在任何时候都能发挥作用,要有足够多并发的需要提交的事务
实现
- 多个并发提交的事务在写redo log或binlog前会被加入到一个队列中
- 队列头部的事务所在的线程称为leader线程,其它事务所在的线程称为follower线程
- leader线程负责为队列中所有的事务进行写binlog操作,此时,所有的follower线程处于等待状态
- 然后leader线程调用一次fsync操作,将binlog持久化
- 最后通知follower线程可以继续往下执行
参数
binlog_group_commit_sync_delay=n
定时发车,在等待n 微秒后,进行binlog刷盘操作
binlog_group_commit_sync_no_delay_count=n
人满发车,达到最大事务等待数量,开始binlog刷盘,忽略定时发车
注意
当binlog_group_commit_sync_delay=0时,binlog_group_commit_sync_no_delay_count参数设置无效,即没有定时发车情况下,人满发车也就没有了~_~
- 当sync_binlog=0或sync_binlog=1,在刷盘前,对每个binlog应用定时发车
- 当sync_binlog=n(n>1),在每n个binlog后应用定时发车
- 设置了定时发车增加了并发提交事务的数量,从而增加slave并行apply的速度(slave开启多线程复制)
- 定时发车增加了事务提交的延迟,在高并发情况下,延迟有可能增加争用从而减少吞吐量
定时发车有优点也有缺点,要更具业务负载持续优化来决定最佳设置
推荐阅读
-
MySQL 组提交(group commit)
-
MySQL关于重做日志刷新的组提交的译文
-
关于MySQL中的事务、回滚(rollback)、提交(commit)
-
mysql中的提交(commit)与回滚(rollback)
-
mysql的事务提交(commit)与回滚(rollback)详解
-
MySQL 5.7.20 Group Relication(组复制)搭建手册
-
mysql group by组内排序_MySQL
-
mysql-msyql group by怎么将null值和空值分为一组啊
-
MySQL5.7的组提交与并行复制实例教程
-
[MySQL5.6] 最近对group commit的小优化_MySQL