在 MySQL 里,undo log
对于事务的回滚和多版本并发控制(MVCC)起着关键作用。undo log
的刷盘(持久化到磁盘)机制与事务的提交、系统配置等因素相关,以下是其详细的刷盘过程:
- 内存缓冲:在事务执行期间,产生的
undo log
首先会被写入 undo log buffer
,这是位于内存中的一块缓冲区。使用内存缓冲可以减少磁盘 I/O 次数,提升性能。
- 按顺序写入:
undo log
按照事务操作的顺序依次写入 undo log buffer
。
- 部分刷盘:当事务提交时,
undo log
不一定会立即全部刷盘。这是因为 undo log
除了用于事务回滚,还用于 MVCC,在其他事务可能还需要访问这些 undo log
来构建旧版本数据时,过早刷盘会影响 MVCC 的正常工作。
- 持久化标记:不过,事务提交时会有一个
redo log
刷盘操作,redo log
会记录 undo log
的修改信息。当 redo log
刷盘后,就保证了即使系统崩溃,undo log
的修改也能通过 redo log
进行恢复,从而实现 undo log
的持久化。
- 自动刷盘:如果
undo log buffer
达到一定的阈值(通常由系统参数控制),会触发自动刷盘操作。此时,undo log buffer
中的部分或全部内容会被写入磁盘上的 undo log
文件。
- 定期刷盘:MySQL 会定期执行检查点操作。在检查点过程中,会将
undo log buffer
中尚未刷盘的 undo log
写入磁盘。检查点操作有助于减少崩溃恢复的时间,因为在崩溃恢复时,只需要从最后一个检查点开始进行恢复即可。
- 全部刷盘:当 MySQL 数据库正常关闭时,会确保
undo log buffer
中的所有 undo log
都被刷盘到磁盘,以保证数据的完整性。
- 同步刷盘:可以通过配置参数,让
undo log
在某些关键操作时进行同步刷盘。例如,在事务提交时,强制将 undo log
同步写入磁盘,确保数据的持久性。不过,这种方式会增加磁盘 I/O 开销,降低系统性能。
- 异步刷盘:默认情况下,
undo log
采用异步刷盘方式。在异步刷盘中,undo log
先在内存中进行修改,然后由后台线程在合适的时机将其刷盘。这样可以减少对事务执行的影响,提高系统的并发性能。
innodb_flush_log_at_trx_commit
:该参数控制 redo log
的刷盘策略,间接影响 undo log
的持久化。例如,当该参数设置为 1 时,每次事务提交都会将 redo log
同步刷盘,从而保证 undo log
的修改能够持久化。
innodb_max_undo_log_size
:该参数限制了单个 undo log
文件的最大大小。当 undo log
文件达到这个阈值时,会触发 undo log
的清理和刷盘操作。
通过以上的刷盘机制,MySQL 确保了 undo log
的数据在不同情况下都能安全持久化,同时也兼顾了系统的性能和数据的一致性。