目录
前言
改进
原理
实现
参数
注意
前言
操作系统使用页面缓存来填补内存和磁盘访问的差距
对磁盘文件的写入会先写入道页面缓存中
由操作系统来决定何时将修改过的脏页刷新到磁盘
确保修改已经持久化到磁盘, 须调用 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 开启多线程复制)
定时发车增加了事务提交的延迟, 在高并发情况下, 延迟有可能增加争用从而减少吞吐量
定时发车有优点也有缺点, 要更具业务负载持续优化来决定最佳设置
参考
《Mariadb 原理与实现》
MySQL 组提交 https://mp.weixin.qq.com/s/_LK8bdHPw9bZ9W1b3i5UZA
来源: https://www.cnblogs.com/YangJiaXin/p/10464810.html