文章目录
- RedoLog是什么
- 刷盘机制
- 崩溃恢复
- 相关参数
- Redo Log 和 Undo Log 对比
https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html
RedoLog是什么
RedoLog 是MySQL的一种日志文件,用于在崩溃恢复期间纠正由不完整事务写入的数据。在正常操作过程中,RedoLog会对SQL语句或MySQL内部低级API调用产生的更改表数据的请求进行编码。在MySQL崩溃之前未完成数据文件更新的修改将在初始化期间和接受连接之前自动重放。
主要功能有以下几点
- 保证事务的完整性,因为事务运行期间可能由于 MySQL 崩溃而执行一半就默认退出了
- 数据备份,便于在 MySQL 崩溃后进行恢复
RedoLog在磁盘上物理表示为由RedoLog文件。写入RedoLog文件的数据根据受影响的记录进行编码,这些数据统称为Redo。
在mysql的数据目录下可以看到RedoLog文件,RedoLog文件
- RedoLog采用二进制格式,以便更高效地存储和处理数据。与文本格式相比,二进制格式可以减少存储空间并提高 I/O 性能。
- 顺序写入:Redo Log 文件使用顺序写入的方式,这意味着日志条目被顺序追加到文件的末尾。这种方式提高了写入效率,因为磁盘的顺序写入速度通常比随机写入快得多。
- 恢复机制:在系统崩溃时,Redo Log 文件用于恢复未完成的事务。MySQL 会读取这些日志条目,将数据库恢复到崩溃前的状态。
- 日志内容:每个日志数据项包含了事务的具体操作和相关的元数据,例如事务 ID 和修改前后的数据状态。这些信息用于确保数据的一致性和完整性。
刷盘机制
https://dev.mysql.com/doc/refman/8.4/en/glossary.html#glos_log_buffer
MySQL写 RedoLog 时是往 LogBuffer 里面写,LogBuffer 是一块保存要写入构成RedoLog的日志文件的数据的内存区域。它的大小由innodb_log_buffer_size
配置选项控制。存在内存中的数据需要将其写入磁盘防止数据丢失。一般来说,RedoLog 落盘的时机有以下几种
- 定时刷盘:MySQL 有一个后台线程以默认每秒一次的频率把LogBuffer 中的 RedoLog 刷新到磁盘 (fsync),由
innodb_flush_log_at_trx_commit
这个变量控制 - 事务提交或者回滚
- LogBuffer 空间不足
如果开启了定时刷盘,可能和事务提交时刷盘冲突
崩溃恢复
https://dev.mysql.com/doc/refman/8.0/en/innodb-recovery.html
MySQL利用 Redo Log 进行恢复的核心思想是在系统崩溃后,通过重放Redo Log中记录的操作,将数据库恢复到崩溃前的状态,从而保证了事务的持久性。
Checkpoint 检查点
在数据库系统中,检查点是一种用于在系统崩溃后减少恢复所需的时间的机制。它记录了数据库在一个特定时间点的一致性状态。在崩溃恢复期间,数据库只需要重放从最后一个检查点开始的日志记录,而不是从头开始重放所有日志记录,从而加快恢复速度。
可以将检查点理解为数据库的一个快照,它标记了哪些数据页已经被安全地写入磁盘。
检查点的作用:
- 缩短恢复时间:这是检查点的主要作用。通过记录一个一致性状态,数据库在崩溃后只需要重放部分日志,而不是全部日志,从而显著减少恢复时间。
- 提高效率:检查点可以减少恢复过程中需要读取的数据页数量,从而提高恢复效率。
- 提高可用性:更快的恢复时间意味着数据库可以更快地重新上线,从而提高系统的可用性。
以下是MySQL如何利用Redo Log进行恢复的详细步骤:
- 崩溃恢复的触发: 当MySQL服务器异常宕机或重启后,在启动过程中会自动触发崩溃恢复流程。
- 查找检查点: InnoDB存储引擎会首先找到最后一个检查点(checkpoint)。检查点记录了哪些数据页已经被写入磁盘。在崩溃恢复时,只需要重做检查点之后的操作即可,避免了不必要的重复工作。
- 扫描Redo Log: 从检查点对应的Redo Log位置开始,顺序扫描Redo Log文件。
- 重放操作: Redo Log中记录了所有已提交事务的修改操作,包括对数据页的修改、对索引的修改等。MySQL会按照顺序重放这些操作,将修改应用到相应的数据页上,即使这些修改在崩溃前还没有被写入磁盘。
- 恢复数据: 通过重放Redo Log中的操作,将数据恢复到崩溃前的最新一致状态。 这确保了已提交事务的数据不会丢失。
- 回滚未提交事务:在重放Redo Log的过程中,如果遇到未提交事务的操作,MySQL会进行回滚操作,撤销这些未完成的修改,保证数据的一致性。
Redo Log 的关键特性使其能够有效地进行崩溃恢复:
- 顺序写入: Redo Log 是顺序写入的,这使得写入操作非常高效。
- 记录物理修改: Redo Log 记录的是对数据页的物理修改,而不是逻辑操作,这使得重放操作非常快速。
- 循环写入: Redo Log 使用循环写入的方式,避免了文件无限增大的问题。
崩溃恢复的类型
MySQL的崩溃恢复主要分为两种类型:
- 基于checkpoint的恢复,这是最常见的恢复方式,如上所述。
- 基于分析的恢复 (crash-safe replication):在某些情况下,例如Redo Log损坏,MySQL可以使用基于分析的恢复。这种方式会分析数据文件,并尝试推断出哪些事务已经提交,然后进行恢复。 这种方式比基于checkpoint的恢复更复杂,也更耗时。
通过以上机制,MySQL利用 Redo Log 实现了事务的持久性,保证了数据的安全性和一致性。
相关参数
innodb_flush_log_at_trx_commit
https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
0 -> 每秒写入并刷新磁盘一次
1 -> 每次事务提交就写入并刷新磁盘,最安全的方式
2 -> 每次提交后写入,每秒刷新一次到磁盘
innodb_flush_log_at_timeout
https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_flush_log_at_timeout
如果其值为 N,则表示在 N 秒的延迟后将日志写入文件
参考文章:
- https://dev.mysql.com/doc/refman/8.4/en/optimizing-innodb-logging.html
- https://dev.mysql.com/doc/refman/8.4/en/optimizing-innodb-transaction-management.html
Redo Log 和 Undo Log 对比
1.redo log通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
2.undo用来回滚行记录到某个版本。undo log一般是逻辑日志,根据每行记录进行记录。