Redolog 刷盘时机

事务修改数据时,如果  buffer pool  中存在,则更新  buffer pool。同时,会将操作写入  redo log buffer

刷盘,是将  redo log buffer  的数据写入磁盘,即从  redo log buffer  到  os page cache  到  磁盘  的过程。

redo log  刷盘的时机

  1. 事务提交:当事务提交时,log buffer 里的 redo log 会被刷新到磁盘(可以通过 innodb_flush_log_at_trx_commit 参数控制,后文会提到)。
  2. log buffer 空间不足时:log buffer 中缓存的 redo log 已经占满了 log buffer 总容量 innodb_log_buffer_size 的大约一半左右,就需要把这些日志刷新到磁盘上。
  3. 事务日志缓冲区满:InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志的刷新,将日志写入磁盘。
  4. Checkpoint(检查点):InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。
  5. 后台刷新线程:InnoDB 启动了一个后台线程,负责周期性(每隔 1 秒)地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。
  6. 正常关闭服务器:MySQL 关闭的时候,redo log 都会刷入到磁盘里去。

InnoDB  存储引擎提供的  innodb_flush_log_at_trx_commit  参数,支持三种策略

  • 0 :每次事务提交时不进行刷盘操作
  • 1 :每次事务提交时都将进行刷盘操作(默认),调用  fsync  对 redo log 进行刷盘
  • 2 :每次事务提交时都只把  redo log buffer  内容写入  page cache

刷盘的时机和策略使得 redo log 可能在事务未提交时就存储到磁盘上。

Fetching Title#e03a

三种策略对应的故障结果:

  • 0 :如果  MySQL  挂了或宕机可能会有  1  秒数据的丢失。
  • 1 :只要事务提交成功,redo log  记录就一定在硬盘里,不会有任何数据丢失。如果事务执行期间  MySQL  挂了或宕机,这部分日志丢了,但是事务并没有提交,所以日志丢了也不会有损失。
  • 2 :只要事务提交成功,redo log buffer  中的内容只写入文件系统缓存( page cache )。如果仅仅只是  MySQL  挂了不会有任何数据丢失,但是宕机可能会有  1  秒数据的丢失。

通常我们说 MySQL 的“双 1”配置,指的就是  sync_binlog  和  innodb_flush_log_at_trx_commit  都设置成 1。也就是说,一个事务完整提交前,需要等待两次刷盘,一次是 redo log(prepare 阶段),一次是 binlog。