在 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 的数据在不同情况下都能安全持久化,同时也兼顾了系统的性能和数据的一致性。