mysql执行SQL时redo log在什么时候写入_日志执行顺序说明

来源:这里教程网 时间:2026-02-28 20:43:36 作者:

MySQL 执行 SQL 时 redo log 是什么时候写入的

redo log 不是在 SQL 执行完才写,也不是在事务提交(

COMMIT
)那一刻“一次性”写入。它是在事务执行过程中、对数据页(buffer pool 中的 page)做**物理修改前**,就先将该修改操作记入 redo log buffer;随后由后台线程或刷盘策略控制,异步或同步地刷入磁盘上的
ib_logfile*
文件。

redo log 写入的关键触发点有哪些

实际写入磁盘不是靠“SQL 执行完毕”,而是依赖以下几种机制协同作用:

innodb_flush_log_at_trx_commit = 1
(默认):每次事务提交时,强制调用
fsync()
将 redo log buffer 刷入磁盘,保证 crash-safe
innodb_log_buffer_size
满了:log buffer 占用达到阈值,自动触发刷盘
后台线程
log_writer
log_flusher
定期(约每秒)检查并刷入未落盘日志
脏页刷新(
page cleaner
)不直接触发 redo 写入,但若此时 log buffer 已有对应 LSN 的日志未刷盘,会阻塞刷脏页

redo log 和 SQL 执行顺序的真实关系

以一条

UPDATE t SET a=2 WHERE id=1
为例,关键步骤顺序如下(简化版):

1. 解析 SQL,获取行锁(record lock)
2. 在 buffer pool 中定位/读取 page(若不在内存则从磁盘加载)
3. 修改 page 中的记录(此时 page 变为“脏页”)
4. 生成对应的 redo 日志条目(如 MLOG_REC_UPDATE_IN_PLACE),写入 redo log buffer
5. 记录当前 LSN 到 page header(mtr_commit 阶段完成)
6. 事务进入 COMMIT 流程 → 根据 innodb_flush_log_at_trx_commit 决定是否 fsync

注意:

步骤 4
发生在
步骤 3
后、
步骤 5
前,且是逻辑上“原子”的 mini-transaction(mtr)提交环节,不是靠用户 SQL 语句结束来驱动。

容易被误解的几个点

很多人以为 “SQL 执行完 → redo 写入 → commit 成功”,其实中间夹着 mtr 提交和 log buffer 管理逻辑,容易踩坑的地方包括:

设置
innodb_flush_log_at_trx_commit = 0
2
时,commit 返回成功 ≠ redo 已落盘,crash 可能丢事务
长事务持续修改大量数据,可能反复填满 log buffer,引发频繁刷盘,拖慢性能 使用
INSERT ... SELECT
或大事务批量更新时,即使没显式 commit,log buffer 也可能因 size 溢出而提前刷盘,导致磁盘 I/O 比预期高
MySQL 8.0+ 引入了独立的
log_writer
线程,不再依赖主线程同步 write/fsync,但
fsync
仍可能成为瓶颈(尤其在机械盘或低配云盘上)

真正影响 redo 落盘时机的,从来不是 SQL 文本执行到哪一行,而是 mtr 生命周期、log buffer 状态、以及那几个关键的 InnoDB 配置项。忽略这点,光看 binlog 或 slow log 很难定位 I/O 突增或 crash 恢复异常的问题。

相关推荐