MySQL-binlog写入机制

以下内容来自mysql45讲第23讲mysql是怎么保证数据不丢的

binlog 的写入逻辑比较简单:事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中。
一个事务的 binlog 是不能被拆开的,所以比较大的事务会产生比较多的binlog,导致刷盘比较慢,也就是binlog写入竞争。
因此不论这个事务多大,也要确保一次性写入。这就涉及到了 binlog cache 的保存问题。
系统给 binlog cache 分配了一片内存,每个线程一个,参数 binlog_cache_size 用于控制单个线程内 binlog cache 所占内存的大小。
如果超过了这个参数规定的大小,就要暂存到磁盘。事务提交的时候,执行器把 binlog cache 里的完整事务写入到 binlog 中,并清空 binlog cache。

  db03 [(none)]>show variables like '%binlog_cache_size%';
  +-----------------------+----------------------+
  | Variable_name         | Value                |
  +-----------------------+----------------------+
  | binlog_cache_size     | 32768                |
  | max_binlog_cache_size | 18446744073709547520 |
  +-----------------------+----------------------+

write 和 fsync 的时机,是由参数 sync_binlog 控制的:
sync_binlog=0 的时候,表示每次提交事务都只 write 到 page cache,不 fsync 到磁盘,由系统决定什么时候刷新到磁盘;
sync_binlog=1 的时候,表示每次提交事务都会执行 fsync 刷新到磁盘;
sync_binlog=N(N>1) 的时候,表示每次提交事务都 write 到page cache,但累积 N 个事务后才 fsync。
因此,在出现 IO 瓶颈的场景里,将 sync_binlog 设置成一个比较大的值,可以提升性能。
在实际的业务场景中,考虑到丢失日志量的可控性,一般不建议将这个参数设成 0,比较常见的是将其设置为 100~1000 中的某个数值。
但是,将 sync_binlog 设置为 N,对应的风险是:如果主机发生异常重启,会丢失最近 N 个事务的 binlog 日志。

相关参数: binlog组提交
如果你想提升 binlog 组提交的效果,可以通过设置 binlog_group_commit_sync_delaybinlog_group_commit_sync_no_delay_count 来实现。
binlog_group_commit_sync_delay 参数,表示延迟多少微秒后才调用 fsync;
binlog_group_commit_sync_no_delay_count 参数,表示累积多少次以后才调用 fsync。
这两个条件是或的关系,也就是说只要有一个满足条件就会调用 fsync。
所以,当 binlog_group_commit_sync_delay 设置为 0 的时候,binlog_group_commit_sync_no_delay_count 也无效了。
也就表示当主库没有写压力的时候,其实并没有启用binlog的组提交

posted @   Enzo_Ocean  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示