2026(5月更新)五大高清海报素材网站分享
2026/5/15 1:36:31
MySQL 每次 DML(INSERT/UPDATE/DELETE)操作生成 Redo 记录,是InnoDB 实现 WAL(Write-Ahead Logging)和崩溃恢复的核心机制。
✅关键特性:
Redo 记录与 SQL 无关,只与物理存储变更相关。
| 操作 | Redo 记录内容 |
|---|---|
| INSERT | - 聚簇索引页插入记录 - 所有二级索引页插入记录 - Undo Log 页插入回滚段 |
| UPDATE | - 聚簇索引页原记录标记删除 + 新记录插入 - 二级索引页若键值变更:删除旧 + 插入新 - Undo Log 更新 |
| DELETE | - 聚簇索引页记录标记删除 - 二级索引页记录标记删除 - Undo Log 插入 |
⚠️注意:
即使 UPDATE 未改变索引列,仍会生成聚簇索引的 Redo(因行数据变更)。
InnoDB Redo 记录采用类型化日志格式,核心字段:
// 伪代码:Redo 记录头structredo_header{uint16_ttype;// 日志类型(MLOG_1BYTE, MLOG_4BYTES...)uint16_tspace_id;// 表空间IDuint32_tpage_no;// 页号uint16_toffset;// 页内偏移uint16_tlength;// 数据长度byte data[];// 变更数据};| 类型 | 说明 | 示例 |
|---|---|---|
| MLOG_WRITE_STRING | 写入字符串 | 插入 VARCHAR 列 |
| MLOG_4BYTES | 写入 4 字节整数 | 更新 INT 列 |
| MLOG_REC_INSERT | 插入完整记录 | INSERT 新行 |
| MLOG_REC_DELETE_MARK | 标记删除 | DELETE 操作 |
💡为什么分类型?
减少日志体积:仅记录变更部分,而非整个页。
假设执行:
UPDATEproductsSETprice=100WHEREid=1000;idx_price),找到页 P2MLOG_REC_DELETE_MARK:标记原记录删除MLOG_REC_INSERT:插入新记录MLOG_REC_DELETE:删除旧索引项MLOG_REC_INSERT:插入新索引项MLOG_WRITE_STRING:写入旧值(price=50)到 Undo 页fsync是昂贵操作(尤其 HDD)📊实测数据:
- 纯内存操作(Buffer Pool 命中):Redo 生成占 CPU 10–20%
- 磁盘 I/O 密集:Redo
fsync成为主要瓶颈
-- 优于 1000 条单条 UPDATEUPDATEproductsSETprice=price*1.1WHEREcategory='A';# 增大日志文件(减少 checkpoint) innodb_log_file_size = 2G # 增大缓冲区(减少提前刷盘) innodb_log_buffer_size = 64M # 组提交优化(MySQL 5.7+) innodb_flush_log_at_trx_commit = 1 # 安全 # innodb_flush_log_at_timeout = 1 # 后台刷盘间隔fsync延迟fsync,提升吞吐-- Redo 日志生成速率SHOWGLOBALSTATUSLIKE'Innodb_os_log_written';-- 日志等待次数(缓冲区不足)SHOWGLOBALSTATUSLIKE'Innodb_log_waits';innodb_ruby可解析.ibd和 Redo 文件(需停机)fsync,而非 Redo 生成本身。💡终极原则:
“Redo 不是开销,而是可靠性的保险费——
付多少,取决于你对数据安全的重视程度。”