MySQL数据写入流程(InnoDB 引擎)
检查数据页是否在内存:如果要修改的数据页已在 Buffer Pool 中,直接使用如果不在,则从磁盘加载到 Buffer Pool(产生物理读 I/O)
增删改操作必须经过BufferPool,查询大多经过BufferPool
数据页:是innoDB引擎管理的最小内存单元,每个页大小默认16KB,页中存储的是行数据。
一个数据库表是由多个页组成
加载数据页到 Buffer Pool
检查数据页是否在内存:
如果要修改的数据页已在 Buffer Pool 中,直接使用
如果不在,则从磁盘加载某一页数据到 Buffer Pool(产生物理读 I/O)
记录 Undo Log
写入 Undo Log:
在修改数据前,先将旧数据写入 undo log(位于系统表空间或独立 undo 表空间)
用于事务回滚和 MVCC 多版本控制
保护机制:undo log 的写入本身也会被记录到 redo log(避免 undo log 丢失)
修改 Buffer Pool
内存中更新:
修改 Buffer Pool 中的数据页(此时磁盘数据未变)
标记该页为 脏页(dirty page)
记录 Redo Log:
将数据页的物理变化(如"页号X偏移量Y修改为Z")写入 redo log buffer
注意:redo log 记录的是物理变化,而非 SQL 语句

事务提交时的刷盘(关键区别)
根据 innodb_flush_log_at_trx_commit 参数决定
innodb_flush_log_at_trx_commit =1 (默认)
-
准备阶段
- 事务修改数据时,先在内存的 Buffer Pool 中更新数据页(变成脏页)
- 同时生成 redo log 记录,暂存到 redo log buffer(内存缓冲区)
-
提交阶段
- Step 1: 将事务的 redo log 从
redo log buffer写入操作系统的 page cache(内存) - Step 2: 立即调用
fsync() 将 page cache 中的 redo log 强制刷入物理磁盘 - Step 3: 收到磁盘确认后,标记事务提交成功(返回客户端)
- Step 1: 将事务的 redo log 从
-
数据页刷盘
- Buffer Pool 中的脏页(实际数据)由后台线程 异步写入磁盘(与事务提交非同步)
- 通过
checkpoint机制控制刷脏页的时机
innodb_flush_log_at_trx_commit =2
-
修改阶段
- 事务修改数据时,先在内存的 Buffer Pool 中更新数据页(标记为脏页)
- 同时生成 redo log 记录,写入 redo log buffer(内存缓冲区)
-
提交阶段
- Step 1: 将 redo log 从
redo log buffer写入操作系统的 page cache(内存) - Step 2: 立即返回事务提交成功(无需等待
fsync()刷盘) - Step 3: 后台线程每秒一次调用
fsync()将 page cache 中的 redo log 刷入磁盘
- Step 1: 将 redo log 从
-
数据持久化
- Buffer Pool 的脏页由后台线程异步刷盘(与事务提交无关)
- 即使 redo log 未刷盘,事务也已提交成功(客户端已收到确认)
innodb_flush_log_at_trx_commit =0
-
完全异步写入:
- 事务提交时,redo log 仅写入 redo log buffer(内存)
- 不立即写入 page cache,更不会调用 fsync()
-
定时刷盘:
- 后台线程每秒一次将 redo log buffer 内容:
- 写入操作系统的 page cache
- 并调用 fsync() 刷入磁盘
- 后台线程每秒一次将 redo log buffer 内容:
-
立即返回成功:
- 事务提交请求完全不等待任何磁盘IO
- 即使 redo log 还在内存中,也立即向客户端返回提交成功
| 行为特征 | =1 (严格模式) | =2 (实时写延迟刷) | =0 (完全异步) |
|---|---|---|---|
| 提交时写入位置 | 直接到物理磁盘 | 到操作系统page cache | 只到InnoDB log buffer |
| 返回客户端时机 | 等待磁盘IO完成 | 写入page cache后立即返回 | 写入内存后立即返回 |
| 后台刷盘频率 | 每次提交都刷 | 每秒1次 | 每秒1次 |
| 可能丢失的数据量 | 几乎不会丢失 | 最多1秒数据 | 超过1秒数据 |
不要redo log,buffer pool中数据直接同步行不行?
可以,但是性能极低,将buffer pool中的增删改同步刷新,保存到磁盘时都是随机的磁盘IO,性能极低。redo log同步时是顺序的磁盘IO,日志文件都是追加的,顺序的磁盘IO性能提高很多
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)