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_delay
和 binlog_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的组提交
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?