当前位置: 代码网 > it编程>数据库>Mysql > MySQL WAL 详细介绍 为什么要先写 redo log 再刷数据页

MySQL WAL 详细介绍 为什么要先写 redo log 再刷数据页

2026年09月24日 • Mysql •我要评论
wal全称:write-ahead logging‌wal(write-ahead logging,预写日志)是 mysql innodb 存储引擎保证事务持久性的核心机制,核心思想是&ld

wal全称:write-ahead logging

‌wal(write-ahead logging,预写日志)是 mysql innodb 存储引擎保证事务持久性的核心机制,核心思想是“先写日志,再写数据”。‌ 具体来说,事务执行时先修改内存中的 buffer pool 数据页(变为脏页),同时生成 redo log 记录物理修改,‌redo log 先持久化到磁盘后,事务才算提交成功‌,而数据页可以稍后异步刷盘。这样设计主要是为了‌性能‌和‌崩溃恢复‌两个目标。

很多人会把它记成一句话: «先写日志,再写数据。» 这句话没错,但很容易产生一个误解: 先把 redo log 写入磁盘 ↓ 然后才能修改
buffer pool 中的数据 实际上并不是这样。

1. wal 真正的先写是什么意思?

假设执行:

update account
set balance = 900
where id = 1;

原来的余额:1000

innodb 会先在:
buffer pool
中的数据页进行修改:
1000 → 900
同时生成对应的:
redo record

于是:

buffer pool 中的数据页
↓
已经修改成 900
↓
成为 dirty page
但是磁盘数据文件中可能仍然是:
1000
真正的 wal 约束发生在持久化阶段:
redo log 先持久化
        ↓
dirty page 后持久化

在脏页写入磁盘数据文件之前,对应的 redo log 必须先完成持久化。

2. 为什么要这样设计?

假设一个事务修改了:

page a
page b
page c

如果没有 wal,可能发生:

page a 已经刷盘
page b 没刷
page c 没刷
redo 也还没持久化
这时候服务器突然宕机。
内存中的:
page b
page c
修改就丢了。
而数据库又没有完整的 redo 信息,就很难可靠恢复这些修改。

所以 innodb 要保证:
只要修改后的数据页
有机会写入磁盘
那么恢复它所需要的 redo
必须已经先落盘

这样即使发生:
page a 已刷盘
page b 未刷盘
page c 未刷盘

服务器突然宕机,

重启以后仍然可以:

读取 redo log
     ↓
crash recovery
     ↓
重新应用缺失的修改
恢复数据库。

3. wal 为什么还能提高性能?

你可能会想:

每次事务提交,直接把修改后的数据页写回磁盘不就行了吗?

问题在于 innodb 的数据页通常是16kb

即使我们只是修改balance

这样一个很小的字段,也可能涉及整个数据页的刷盘。

而且数据页可能分散在磁盘不同位置:

page a
↓
某个位置
page b
↓
另一个位置
page c
↓
又一个位置
容易产生较多随机 i/o。
redo log 则更适合:
顺序追加
所以可以:
修改 buffer pool
      ↓
生成 redo
      ↓
redo 先持久化
      ↓
事务完成
      ↓
脏页以后再慢慢刷盘
既保证可靠性,又避免每次事务都必须立即把所有数据页刷回磁盘。

📌 补充:wal 的性能优化

除了顺序写,innodb 还有‌组提交(group commit)‌机制:多个并发事务的 redo log 可以合并成一次 fsync 写入,减少系统调用次数,大幅降低磁盘 iops 消耗。lsn(日志序列号)单调递增,用来标记写入位置,保证重放顺序正确。‌‌

到此这篇关于mysql wal 是什么?为什么要先写 redo log 再刷数据页?的文章就介绍到这了,更多相关mysql wal 全解内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

赞 (0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com