MySQL 插入一条 SQL 语句,redo log 记录的内容
在 MySQL 的 InnoDB 存储引擎中,redo log(重做日志)主要用来保证事务的持久性和崩溃恢复能力。redo log 记录的是对数据页的物理变更,而不是 SQL 语句本身。
当执行一条插入语句时,redo log 的记录主要包括对数据页的修改信息,以及事务相关的元数据。以下是 redo log 在执行插入操作时的详细记录过程。
redo log 的核心作用
- 崩溃恢复:在数据库崩溃后,通过 redo log 恢复事务已提交但未写入磁盘的数据。
- 事务提交持久性:redo log 提供持久化保障,即使数据尚未完全刷入磁盘,也可以通过 redo log 恢复数据。
redo log 的记录内容
假设执行如下插入语句:
INSERT INTO users (id, name, age) VALUES (1, 'Alice', 30);
redo log 会记录以下内容:
-
事务元信息:
- 事务开始(
BEGIN
)。 - 事务结束(
COMMIT
或ROLLBACK
)。
- 事务开始(
-
页修改操作:
- 记录被修改的页(page)的编号和偏移量。
- 修改的内容(如插入了哪些记录、更新了哪些数据)。
- 仅记录具体的物理变更,而不是 SQL 语句本身。
-
日志类型:
- 分为
PREPARE
(事务准备阶段)和COMMITTED
(事务提交阶段)。
- 分为
-
顺序性保证:
- redo log 按顺序记录,以保证崩溃恢复时能按正确顺序重放日志。
redo log 的记录过程
-
事务开始:
redo log 写入事务开始的记录。 -
内存中的数据页变更:
- 修改页被加载到内存中(称为缓冲池)。
- 在缓冲池中对数据页进行修改,同时将变更写入 redo log。
-
redo log 持久化:
- 事务提交时,先将 redo log 刷入磁盘(称为 "刷盘")。
- 此时,即使数据页尚未写回磁盘(即未同步到表空间文件),也能通过 redo log 恢复。
-
事务提交:
- redo log 记录事务提交的标志,表示事务完成。
示例 redo log 记录内容
以上述 INSERT
语句为例,redo log 的记录内容可能类似如下:
- 事务开始标志(
BEGIN
)。 - 修改第 N 页某位置的数据:
- 在页的某个偏移量插入了一条记录(如用户 ID 为 1 的记录)。
- 页的元数据(如记录计数、空闲空间等)发生了相应更新。
- 事务提交标志(
COMMIT
)。
总结
- redo log 记录的是物理层面的数据页变更,而不是 SQL 语句或逻辑操作。
- 其设计目标是通过最小化写操作的开销来提高性能,同时提供崩溃恢复的能力。
- redo log 的记录过程遵循 WAL(Write-Ahead Logging) 原则,即先写日志,再更新数据。