mysql日志刷盘
一,Mysql日志是否实时写入磁盘?
- Redo Log的实时性
当innodb_flush_log_at_trx_commit=1时,每次事务提交都会同步将Redo Log实时写入磁盘,是完全实时的;设为0或2时,仅每秒批量刷盘一次,事务提交时不会实时落盘。 - Binlog的实时性
当sync_binlog=1时,每次事务提交都会同步将Binlog实时写入磁盘;设为0或N时,不会实时刷盘,由操作系统或累计N个事务后批量落盘。
二,bin log刷盘机制是如何实现的?
Binlog的刷盘实现围绕内存缓冲、操作系统缓存、磁盘持久化三层结构展开,核心逻辑如下:
内存缓冲阶段
事务执行时,先将Binlog写入线程私有的Binlog Cache内存缓冲区,避免多线程竞争全局资源,事务提交前数据完全驻留内存。写入OS Page Cache
事务提交时,先将Binlog从线程缓存全局的Binlog文件追加写入,此时数据仅落入操作系统的Page Cache,未真正写入磁盘,这一步是顺序IO,性能很高。磁盘持久化控制
由sync_binlog参数决定后续刷盘行为:
- 设为1时,调用
fsync()系统调用,强制将Page Cache中的Binlog数据同步写入磁盘文件,完成真正持久化。 - 设为N(N>1)时,累计N个事务提交后,才执行一次
fsync()批量刷盘,减少磁盘IO次数。 - 设为0时,完全由操作系统自行调度Page Cache的刷盘时机,MySQL不主动触发持久化。
- 与Redo Log协同
Binlog刷盘会配合InnoDB的两阶段提交机制,确保Redo Log和Binlog的提交顺序一致,避免数据库崩溃后出现主从数据不一致的问题。
三,redo log刷盘机制是如何实现的?
Redo Log是InnoDB引擎实现崩溃恢复、保障数据持久化的核心物理日志,其刷盘实现分为以下核心环节:
1. 内存缓冲层设计
事务修改数据页时,先将变更写入内存的Redo Log Buffer,避免直接刷脏页产生大量随机IO,Buffer采用环形内存结构,通过log_buf指针管理写入位置,多线程通过互斥锁竞争写入,保证日志顺序性。
2. 写入OS Page Cache
事务提交时,先将Redo Log Buffer中的日志,通过pwrite()系统调用追加写入磁盘上的Redo Log文件,此时数据仅落入操作系统的Page Cache,未真正持久化到物理磁盘,这一步是高效的顺序IO。
3. 刷盘策略控制
由参数innodb_flush_log_at_trx_commit决定后续持久化行为:
- 设为1:每次事务提交后,立即调用
fsync()强制将Page Cache中的Redo Log同步写入磁盘,完全保障数据零丢失,是MySQL默认的安全配置。 - 设为2:事务提交仅将日志写入Page Cache,后台每秒批量执行一次
fsync()刷盘,性能大幅提升,仅宕机时可能丢失1秒内数据。 - 设为0:事务提交不触发任何写入操作,后台线程每秒直接将Redo Log Buffer批量刷入磁盘,性能最高,宕机可能丢失1秒内所有事务数据。
4. 后台异步刷盘机制
InnoDB后台有专门的log_flusher线程,负责定期将内存中未刷盘的Redo Log批量落盘,同时配合Checkpoint机制,将已持久化的Redo Log对应的脏数据页逐步刷入磁盘,推进Redo Log的环形写入起点,避免日志空间被占满。
5. 与Binlog的协同校验
Redo Log刷盘会配合两阶段提交机制,先写Redo Log并标记为PREPARED状态,再写Binlog,最后将Redo Log标记为COMMITTED状态,确保两者的提交顺序完全一致,数据库崩溃重启时可通过Redo Log恢复未完成的事务,保证数据一致性。
四,undo log刷盘机制是如何实现的?
Undo Log是InnoDB实现事务原子性、MVCC多版本并发控制的核心日志,其刷盘实现逻辑如下:
1. 核心作用与存储结构
Undo Log用于记录数据修改前的旧版本快照,事务回滚时可恢复数据到修改前状态,同时为MVCC提供历史版本链。它存放在共享表空间或独立的undo表空间中,采用段页式结构管理。
2. 内存写入流程
事务执行修改操作时,先在内存的Undo Log Buffer中生成对应的回滚日志,无需直接同步刷盘,这一步仅占用少量内存资源,写入效率很高。
3. 刷盘持久化机制
Undo Log的刷盘并非独立触发,而是和Redo Log强绑定:
- Undo Log的修改会被同步记录到Redo Log中,随Redo Log的刷盘流程一起持久化到磁盘,无需单独实现刷盘逻辑。
- 当事务提交时,Undo Log对应的物理页会被标记为可复用,后台purge线程会定期清理已不再需要的旧版本Undo Log,释放存储空间。
4. 持久化保障逻辑
数据库崩溃重启时,InnoDB会先通过Redo Log恢复所有未持久化的事务数据,再利用Undo Log回滚所有未成功提交的活跃事务,完全保证事务的原子性不被破坏。
磁盘写入固然是比较慢的.
参数: sync_binlog,
binlog写入策略:
1、sync binlog=0的时候,表示每次提交事务binlog不会马上写入到磁盘,而是先写到page cache,相对于磁盘写入来说写page cache要快得多不过在Mysql崩滚的时候会有丢失日志的风险.
2、sync_binlog=1的时候,表示每次提交事务都会执行fsync写入到磁盘;
3、sync binlog的值大于1的时候,表示每次提交事务都先写到page cache,只有等到积累了N个事务之后才tsync写入到磁盘,同样在此没置下Mysq1崩溃的时候会有丢失N个事务日志的风险。
很显然三种模式下,sync_binlog=1是强一致的选择,迭择0或者N的情况下在极端情况下就会有丢失日志的风险,具体选择什么模式还是得看系统对于一效性的要求。
innodb_flush_log_at_trx_commit
取值0,每秒《一秒钟内提交的事务》写入磁盘每秒触发一次缓存日志回写磁盘操作,并调用操作系统fsync刷新 IO 缓存。
取值1,有事务提交就立即刷盘,每次提交事务会立即调用操作系fsync刷新IO缓存。
取值2,每次事务提交都写给操作系统 由系统接管什么时候写入磁盘每次都把redo log写到系统的pasge cache、由系统接管什么时候写入磁盘
时机顺序:
1,开启事务
2,查询数据库中简要更新的字段,加载到内存中形成数据脏页
3,记录undo log到内存缓冲区(用于回滚和mvcc)并关联redo log->可刷盘·4,记录redo log到内存缓冲区(用于失效重放)准备提交事务 ->可刷盘·
5,修改内存中的脏页数据
6,提交事务触发redolog刷盘7,undo log 和赃页刷盘·
8,事务成功
五,MySQL日志刷盘详细介绍
结合之前我们讨论过MySQL事务隔离级别、MVCC并发控制的相关背景,MySQL日志刷盘是保障事务ACID特性、实现数据不丢的核心机制,以下是详细介绍:
一、核心刷盘日志类型
- Redo Log(重做日志)
InnoDB引擎专属的物理日志,记录数据页的修改操作,采用环形写入机制,默认总大小为4*512MB,用于数据库崩溃后快速恢复未持久化的数据,避免直接刷脏页带来的随机IO开销。 - Binlog(归档日志)
MySQL Server层生成的逻辑日志,记录所有修改数据的SQL事件,支持STATEMENT/ROW/MIXED三种格式,用于主从数据同步和全量数据备份恢复,采用追加写入的顺序IO模式。
二、核心刷盘流程
- 事务提交时,先将修改写入内存的Redo Log Buffer,根据配置策略决定是否同步刷入磁盘的Redo Log文件。
- 生成Binlog并写入Binlog Cache,同样根据配置策略决定是否同步刷入磁盘的Binlog文件。
- 执行InnoDB的两阶段提交,确保Redo Log和Binlog的提交顺序一致,避免主从数据出现不一致的情况。
三、关键刷盘参数配置
| 参数 | 取值 | 刷盘行为 | 数据安全性 | 性能表现 |
|---|---|---|---|---|
innodb_flush_log_at_trx_commit | 0 | 每秒批量刷盘1次,事务提交不主动触发刷盘 | 低,宕机可能丢失1秒内数据 | 极高 |
innodb_flush_log_at_trx_commit | 1 | 每次事务提交同步刷盘到磁盘 | 最高,完全不丢数据 | 低 |
innodb_flush_log_at_trx_commit | 2 | 事务提交刷到OS缓存,每秒批量刷入磁盘 | 中,仅宕机可能丢数据 | 高 |
sync_binlog | 0 | 由操作系统自行决定Binlog刷盘时机 | 低 | 极高 |
sync_binlog | 1 | 每次事务提交同步刷Binlog到磁盘 | 最高 | 低 |
sync_binlog | N | 每累计N个事务提交后批量刷盘 | 中 | 高 |
四、生产环境优化策略
- 金融级强一致场景:采用双1配置(两个参数都设为1),完全保障数据零丢失。
- 高吞吐普通业务场景:将
innodb_flush_log_at_trx_commit设为2、sync_binlog设为100,在可接受少量数据丢失的前提下,大幅提升写入性能。 - 搭配SSD磁盘,利用其高随机IO能力,进一步降低刷盘操作的延迟。
