23 | MySQL是怎么保证数据不丢的?
该思维导图由 AI 生成,仅供参考
binlog 的写入机制
- 深入了解
- 翻译
- 解释
- 总结
MySQL数据保证机制的技术特点主要围绕binlog的写入流程和相关参数的设置展开。在binlog的写入机制中,事务执行过程中先将日志写入binlog cache,事务提交时再将binlog cache写入binlog文件中。每个线程有自己的binlog cache,但共用同一份binlog文件。参数sync_binlog控制了write和fsync的时机,可以根据实际情况设置以提升性能。然而,将sync_binlog设置为较大值会增加丢失日志的风险。因此,在实际业务中需要权衡性能和数据可靠性。此外,文章还介绍了redo log的写入机制和InnoDB提供的innodb_flush_log_at_trx_commit参数,以及组提交机制对磁盘IOPS消耗的影响。总的来说,文章通过详细解释binlog的写入流程和相关参数的设置,帮助读者了解MySQL数据保证机制的技术特点,为在业务高峰期临时提升性能提供了有益的参考。
《MySQL 实战 45 讲》,新⼈⾸单¥68
全部留言(188)
- 最新
- 精选
- 锅子置顶老师好,有一个疑问:当设置sync_binlog=0时,每次commit都只时write到page cache,并不会fsync。但是做实验时binlog文件中还是会有记录,这是什么原因呢?是不是后台线程每秒一次的轮询也会将binlog cache持久化到磁盘?还是有其他的参数控制呢?
作者回复: 你看到的“binlog的记录”,也是从page cache读的哦。 Page cache是操作系统文件系统上的😄 好问题
2019-01-0416184 - WilliamX为什么 binlog cache 是每个线程自己维护的,而 redo log buffer 是全局共用的? 这个问题,感觉还有一点,binlog存储是以statement或者row格式存储的,而redo log是以page页格式存储的。page格式,天生就是共有的,而row格式,只跟当前事务相关
作者回复: 嗯,这个解释也很好。👍🏿
2019-01-048159 - alias cd=rm -rf事务A是当前事务,这时候事务B提交了。事务B的redolog持久化时候,会顺道把A产生的redolog也持久化,这时候A的redolog状态是prepare状态么?
作者回复: 不是。 说明一下哈,所谓的 redo log prepare,是“当前事务提交”的一个阶段,也就是说,在事务A提交的时候,我们才会走到事务A的redo log prepare这个阶段。 事务A在提交前,有一部分redo log被事务B提前持久化,但是事务A还没有进入提交阶段,是无所谓“redo log prepare”的。 好问题
2019-01-2817130 - 倪大人老师求解sync_binlog和binlog_group_commit_sync_no_delay_count这两个参数区别 如果 sync_binlog = N binlog_group_commit_sync_no_delay_count = M binlog_group_commit_sync_delay = 很大值 这种情况fsync什么时候发生呀,min(N,M)吗? 感觉sync_binlog搭配binlog_group_commit_sync_delay也可以实现组提交? 如果 sync_binlog = 0 binlog_group_commit_sync_no_delay_count = 10 这种情况下是累计10个事务fsync一次?
作者回复: 好问题,我写这篇文章的时候也为了这个问题去翻了代码,是这样的: 达到N次以后,可以刷盘了,然后再进入(sync_delay和no_delay_count)这个逻辑; Sync_delay如果很大,就达到no_delay_count才刷; 只要sync_binlog=0,也会有前面的等待逻辑,但是等完后还是不调fsync😄
2019-01-041084 - Komine为什么binlog 是不能“被打断的”的呢?主要出于什么考虑?
作者回复: 好问题 我觉得一个比较重要的原因是,一个线程只能同时有一个事务在执行。 由于这个设定,所以每当执行一个begin/start transaction的时候,就会默认提交上一个事务; 这样如果一个事务的binlog被拆开的时候,在备库执行就会被当做多个事务分段自行,这样破坏了原子性,是有问题的。
2019-01-22479 - 猪哥哥老师 我想问下文件系统的page cache还是不是内存, 是不是文件系统向内核申请的一块的内存?
作者回复: 你理解的是对的
2019-01-10443 - 某、人有调到非双1的时候,在大促时非核心库和从库延迟较多的情况。 设置的是sync_binlog=0和innodb_flush_log_at_trx_commit=2 针对0和2,在mysql crash时不会出现异常,在主机挂了时,会有几种风险: 1.如果事务的binlog和redo log都还未fsync,则该事务数据丢失 2.如果事务binlog fsync成功,redo log未fsync,则该事务数据丢失。 虽然binlog落盘成功,但是binlog没有恢复redo log的能力,所以redo log不能恢复. 不过后续可以解析binlog来恢复这部分数据 3.如果事务binlog fsync未成功,redo log成功。 由于redo log恢复数据是在引擎层,所以重新启动数据库,redo log能恢复数据,但是不能恢复server层的binlog,则binlog丢失。 如果该事务还未从FS page cache里发送给从库,那么主从就会出现不一致的情况 4.如果binlog和redo log都成功fsync,那么皆大欢喜。 老师我有几个问题: 1.因为binlog不能被打断,那么binlog做fsync是单线程吧? 如果是的话,那么binlog的write到fsync的时间,就应该是redo log fsync+上一个事务的binlog fsync时间。 但是测试到的现象,一个超大事务做fsync时,对其它事务的提交影响也不大。 如果是多线程做fsync,怎么保证的一个事务binlog在磁盘上的连续性? 2. 5.7的并行复制是基于binlog组成员并行的,为什么很多文章说是表级别的并行复制?
作者回复: 1. Write的时候只要写进去了,fsync其实很快的。连续性是write的时候做的(写的时候保证了连续) 2. 你的理解应该是对的。不是表级
2019-01-061940 - xiaoyou老师,请教一个问题,文章说innodb的 redo log 在commit的时候不进行fsync,只会write 到page cache中。当sync_binlog>1,如果redo log 完成了prepare持久化落盘,binlog只是write page cache,此时commit标识完成write 但没有落盘,而client收到commit成功,这个时候主机掉电,启动的时候做崩溃恢复,没有commit标识和binglog,事务会回滚。我看文章说sync_binlog设置为大于1的值,会丢binlog日志,此时数据也会丢失吧?
作者回复: 你说的对,分析得很好
2019-01-091624 - Mr.Strive.Z.H.L老师你好,看了@倪大人的问题,个人认为: sync_binlog和binlog_group_commit_sync_no_delay_count的最大区别主要在于,数据的丢失与否吧? sync_binlog = N:每个事务write后就响应客户端了。刷盘是N次事务后刷盘。N次事务之间宕机,数据丢失。 binlog_group_commit_sync_no_delay_count=N: 必须等到N个后才能提交。换言之,会增加响应客户端的时间。但是一旦响应了,那么数据就一定持久化了。宕机的话,数据是不会丢失的。 不知道我这么理解对不对?
作者回复: 你的理解很到位
2019-01-081222 - 一大只😴你是怎么验证的?等于0的时候虽然有走这个逻辑,但是最后调用fsync之前判断是0,就啥也没做就走了 回复老师: 老师,我说的sync_binlog=0或=1效果一样,就是看语句实际执行的效果,参数binlog_group_commit_sync_delay我设置成了500000微秒,在=1或=0时,对表进行Insert,然后都会有0.5秒的等待,也就是执行时间都是0.51 sec,关闭binlog_group_commit_sync_delay,insert执行会飞快,所以我认为=1或=0都是受组提交参数的影响的。
作者回复: 👍🏿 非常好 然后再补上我回答的这个逻辑,就完备了
2019-01-0522