彻底搞懂三大MySQL日志,Redo Log、Undo Log、Bin Log

彻底搞懂三大MySQL日志,Redo Log、Undo Log、Bin Log
最新回答
玻璃回忆

2021-10-22 09:39:59

彻底搞懂三大MySQL日志:Redo Log、Undo Log、Bin LogRedo Log(重做日志)

Redo Log的内容与作用

Redo Log记录的是物理日志,即磁盘数据页的修改。它的主要作用是保证服务崩溃后,仍能把事务中变更的数据持久化到磁盘上。MySQL事务中的持久性就是使用Redo Log实现的。

什么时候写入Redo Log?

Redo Log的写入过程如下:

  1. 从磁盘加载数据到内存。
  2. 在内存中修改数据。
  3. 把新数据写到Redo Log Buffer中。
  4. 把Redo Log Buffer中的数据持久化到Redo Log文件中。
  5. 把Redo Log文件中的数据持久化到数据库磁盘中。

这种方案叫做WAL(Write-Ahead Logging),即预写日志,目的是先写日志,再写磁盘,以提高性能。

Redo Log刷盘规则

写入Redo Log Buffer之后,并不会立即持久化到Redo Log File,需要等待操作系统调用fsync()操作,才会刷到磁盘上。具体刷盘时机可以通过innodb_flush_log_at_trx_commit参数配置决定:

  • 0(延迟写):提交事务后,不会立即刷到OS Buffer中,而是等一秒后刷新到OS Buffer并调用fsync()写入Redo Log File,可能会丢失一秒钟的数据。
  • 1(实时写):每次提交事务,都会刷新到OS Buffer并调用fsync()写到Redo Log File,性能较差。
  • 2(延迟刷新):每次提交事务只刷新到OS Buffer,一秒后再调用fsync()写入Redo Log File。

Redo Log File是固定大小的,可以配置为每组4个文件,每个文件的大小是1GB,那么Redo Log File可以记录4GB的操作。它采用循环写入覆盖的方式,write pos记录开始写的位置,向后移动;checkpoint记录将要擦除的位置,也是向后移动。write pos到checkpoint之间的位置是可写区域,checkpoint到write pos之间的位置是已写区域。

Undo Log(回滚日志)

Undo Log的内容与作用

Undo Log记录的是逻辑日志,即SQL语句。比如,当我们执行一条insert语句时,Undo Log就记录一条相反的delete语句。它的主要作用有两个:一是回滚事务时,恢复到修改前的数据;二是实现MVCC(多版本并发控制,Multi-Version Concurrency Control)。MySQL事务中的原子性就是使用Undo Log实现的。

Undo Log如何回滚到上一个版本

Undo Log通过两个隐藏列trx_id(最近一次提交事务的ID)和roll_pointer(上个版本的地址),建立一个版本链。并在事务中读取的时候生成一个ReadView(读视图),在Read Committed隔离级别下,每次读取都会生成一个读视图,而在Repeatable Read隔离级别下,只会在第一次读取时生成一个读视图。

Bin Log(备份日志)

Bin Log的内容与作用

Bin Log记录的是逻辑日志,即原始的SQL语句,是MySQL自带的。它的主要作用是数据备份和主从同步。

Bin Log共有三种日志格式,可以通过binlog_format配置参数指定:

  • Statement:记录原始SQL语句,可能会导致更新时间与原库不一致,比如update_time=now()。
  • Row:记录每行数据的变化,保证了数据与原库一致,但缺点是数据量较大。
  • Mixed:Statement和Row的混合模式,默认采用Statement模式,涉及日期、函数相关的时候采用Row模式,既减少了数据量,又保证了数据一致性。

什么时候写入Bin Log?

Bin Log采用追加写入的模式,并不会覆盖原有日志,所以可以用来恢复到之前某个时刻的数据。Bin Log也是采用WAL模式,即先写日志,再写磁盘。至于什么时候刷新到磁盘,可以通过sync_binlog配置参数指定:

  • 0(延迟写):每次提交事务都不会刷盘,由系统自己决定什么时候刷盘,可能会丢失数据。
  • 1(实时写):每次提交事务,都会刷盘,性能较差。
  • N(延迟写):提交N个事务后,才会刷盘。

加入写Bin Log之后的事务流程涉及二阶段提交的概念:先写处于prepare状态的Redo Log,事务提交后,再写处于commit状态的Redo Log。

知识点总结
  • Redo Log:记录物理日志,保证服务崩溃后数据持久化;采用WAL模式,写入Redo Log Buffer后,根据innodb_flush_log_at_trx_commit参数决定刷盘时机;固定大小,循环写入覆盖。
  • Undo Log:记录逻辑日志,用于回滚事务和实现MVCC;通过trx_id和roll_pointer建立版本链。
  • Bin Log:记录逻辑日志,用于数据备份和主从同步;有三种格式:Statement、Row、Mixed;采用WAL模式,根据sync_binlog参数决定刷盘时机;追加写入,不会覆盖原有日志。

通过深入了解MySQL的三大日志系统,我们可以更好地理解MySQL的事务处理、崩溃恢复以及集群的主从复制等核心功能。