03_MySQL 存储引擎与存储管理 —— InnoDB 深入、表空间/ibd、binlog/redo/undo 与双写缓冲

03_MySQL 存储引擎与存储管理 ------ InnoDB 深入、表空间/ibd、binlog/redo/undo 与双写缓冲

系列定位 :《MySQL 数据库全栈运维实战系列》第 03 篇,与《Oracle 数据库全栈运维实战系列(VMware 版)》同构对标。适用版本 :MySQL 8.0(5.7 差异随文标注)。官方文档:MySQL 8.0 Reference Manual、InnoDB Storage Engine / InnoDB On-Disk Structures / The Binary Log。


一、存储引擎全景(可插拔架构)

图 1

特性 InnoDB MyISAM MEMORY 类比 Oracle
事务 ACID ✅ ❌ ❌ 对应 OLTP 表
锁粒度 行锁(默认) 表锁 表锁 行锁 vs 表锁
外键 ✅ ❌ ❌ 约束
崩溃恢复 ✅(redo 重放) ❌ ❌(重启即失) instance recovery
MVCC ✅ ❌ ❌ undo 多版本
全文索引 8.0 支持 ✅ ❌ 不适用
压缩 ✅( transparent ) ✅(myisampack) - 表压缩
存储位置 磁盘(.ibd) 磁盘(.MYD/.MYI) 内存 数据文件
生产定位 默认唯一选择 只读历史报表 临时缓存/汇总 -

核心结论 :MySQL 8.0 生产环境 100% 使用 InnoDB。MyISAM 仅在明确的只读归档场景偶见;MEMORY 用于临时表/会话级缓存。


二、InnoDB 物理存储结构(官方:InnoDB On-Disk Structures)

2.1 逻辑层级

图 2

层级 大小/说明 类比 Oracle
表空间 Tablespace 一个或多个数据文件 表空间
段 Segment 数据段/索引段/回滚段 段
区 Extent 1MB = 64 × 16KB 页 区 (extent)
页 Page 16KB(默认,可改 4K/8K/16K/32K/64K) 数据块 block
行 Row 记录存储在页中 行

2.2 表空间类型

表空间类型 说明 对应文件 类比 Oracle
系统表空间 数据字典、change buffer、回滚段 ibdata1 SYSTEM 表空间
独立表空间 每表一个 .ibd(8.0 默认 innodb_file_per_table=ON) 库名/表名.ibd 本地管理表空间
通用表空间 CREATE TABLESPACE 手动创建 自定义路径 大文件表空间
undo 表空间 独立 undo 日志(8.0 可在线调整) undo_001, undo_002 UNDO 表空间
临时表空间 临时表存储 ibtmp1 TEMP 表空间
复制代码
-- 解释:查看所有表空间
SELECT TABLESPACE_NAME, FILE_NAME, ENGINE FROM information_schema.FILES;

-- 解释:查看某表使用的表空间
SELECT TABLE_NAME, TABLESPACE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'appdb' AND TABLE_NAME = 't_order';

-- 解释:查看 .ibd 文件大小(每表独立表空间)
SHOW TABLE STATUS FROM appdb LIKE 't_order'\G

8.0 变化 :5.7 之前默认 innodb_file_per_table=OFF,所有表共用 ibdata1,导致 ibdata1 膨胀无法回收;8.0 默认 ON,每表一个 .ibd,DROP/TRUNCATE 表后空间可回收给操作系统。


三、三大日志:redo log / undo log / binlog

3.1 三大日志职责对比

图 3

日志 级别 作用 写入者 类比 Oracle
redo log InnoDB 引擎层 崩溃恢复(前滚),保证持久性 InnoDB redo 日志
undo log InnoDB 引擎层 事务回滚 + MVCC 版本链 InnoDB undo 段
binlog Server 层 主从复制 + 时间点恢复(PITR) MySQL Server 归档日志

关键区别 :redo 和 undo 是 InnoDB 引擎层 日志,binlog 是 MySQL Server 层日志。这就是为什么 MyISAM 没有崩溃恢复------它没有 redo log。

3.2 redo log(重做日志)

复制代码
-- 解释:查看 redo log 配置(8.0.30+ 使用 innodb_redo_log_capacity)
SHOW VARIABLES LIKE 'innodb_redo_log_capacity';    -- 总容量,默认 100M
SHOW VARIABLES LIKE 'innodb_log_buffer_size';       -- redo 缓冲,默认 16M

-- 解释:查看 redo 日志文件(8.0 在线 redo 目录)
SHOW VARIABLES LIKE 'innodb_log_group_home_dir';    -- 默认 ./ 即 datadir
参数 说明 推荐值
innodb_redo_log_capacity redo 总容量(8.0.30+) 2G~4G(高写入场景)
innodb_log_buffer_size redo 内存缓冲 64M(大事务场景)
innodb_flush_log_at_trx_commit 刷盘策略 1(最安全)
innodb_log_writes_advances 检查点推进频率 默认即可

5.7 差异 :5.7 使用 innodb_log_file_size + innodb_log_files_in_group 两个参数管理 redo;8.0.30+ 统一为 innodb_redo_log_capacity。

3.3 undo log(回滚日志)

复制代码
-- 解释:查看 undo 表空间
SHOW VARIABLES LIKE 'innodb_undo_directory';        -- undo 目录
SHOW VARIABLES LIKE 'innodb_undo_tablespaces';      -- undo 表空间数量

-- 解释:查看当前 undo 段使用情况
SELECT * FROM information_schema.INNODB_UNDO_LOGS;
作用 说明
事务回滚 ROLLBACK 时用 undo 恢复旧值
MVCC 一致性读 快照读通过 undo 版本链找到历史版本
purge 线程 清理已提交事务不再需要的 undo 版本

3.4 binlog(二进制日志)

复制代码
-- 解释:查看 binlog 配置
SHOW VARIABLES LIKE 'log_bin';                      -- ON 表示已开启
SHOW VARIABLES LIKE 'binlog_format';                 -- ROW / STATEMENT / MIXED
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';    -- 保留时长(秒)
SHOW MASTER STATUS;                                   -- 当前 binlog 位点
binlog 格式 记录内容 优点 缺点 适用
ROW(8.0 默认) 每行数据的前后镜像 数据安全、准确 日志体积大 生产默认
STATEMENT 原始 SQL 语句 日志小 函数不确定(NOW()/UUID())可能主从不一致 批量大事务
MIXED 自动选择 折中 复杂度高 兼容场景

四、Doublewrite Buffer(双写缓冲)

4.1 为什么需要双写

图 4

问题 说明 类比 Oracle
页半写(torn page) 16KB 页只写了一部分就断电 块断裂
页大小与 OS 块不对齐 MySQL 页 16KB,OS 块 4KB,中间断电导致部分写入 -
双写作用 先写一份到共享表空间的双写区,再写真正位置;崩溃时从双写区恢复 类似 Oracle 的块恢复
复制代码
-- 解释:查看双写状态
SHOW VARIABLES LIKE 'innodb_doublewrite';            -- ON(默认开启)
SHOW STATUS LIKE 'innodb_dblwr%';                    -- 双写统计

性能影响 :双写会带来约 5~10% 的写入性能开销,但换取了崩溃安全性,生产环境必须开启。


五、Change Buffer(变更缓冲)

图 5

参数 说明
innodb_change_buffering 缓冲类型:all/none/inserts/deletes/changes/pures
innodb_change_buffer_max_size Change Buffer 最大占 Buffer Pool 百分比,默认 25%

原理:二级索引页不在内存时,先把变更记录到 Change Buffer,避免随机读盘,等后续访问该页时再合并回真实数据。显著提升写多读少场景的性能。


六、Buffer Pool 深入(官方:InnoDB Buffer Pool)

图 6

组件 作用 关键参数
LRU 链表 管理所有缓存页,young/old 分区防全表扫描污染 innodb_old_blocks_pct(默认 37%)
Free 链表 空闲可用页 -
Flush 链表 脏页列表,后台线程异步刷盘 innodb_max_dirty_pages_pct(默认 90)
Change Buffer 二级索引写缓冲 innodb_change_buffering
复制代码
-- 解释:Buffer Pool 命中率监控
SHOW ENGINE INNODB STATUS\G
-- 重点看 BUFFER POOL AND MEMORY 段:
-- Buffer pool hit rate: 999/1000(越高越好,< 990 需关注)

七、表空间管理实操

7.1 查看表空间

复制代码
-- 解释:所有表空间概览
SELECT TABLESPACE_NAME, FILE_NAME, EXTENT_SIZE, INITIAL_SIZE/1024/1024 AS initial_mb
FROM information_schema.FILES WHERE FILE_TYPE='DATAFILE';

-- 解释:查看独立表空间文件大小
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE, ROUND(DATA_LENGTH/1024/1024,2) AS data_mb,
       ROUND(INDEX_LENGTH/1024/1024,2) AS index_mb
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','sys','information_schema','performance_schema');

7.2 收缩表空间(OPTIMIZE TABLE)

复制代码
-- 解释:删除大量数据后 .ibd 文件不会自动缩小给 OS,需 OPTIMIZE 回收空间
-- 原理:重建表 + 索引,相当于 MySQL 版的 MOVE/SPLICE
OPTIMIZE TABLE appdb.t_order;

-- 5.7 注意:OPTIMIZE 在 InnoDB 上实际是 CREATE + INSERT + RENAME,会锁表
-- 8.0 Online DDL 支持在线 OPTIMIZE(短暂元数据锁)

7.3 表空间迁移(Transportable Tablespace)

复制代码
-- 解释:导出表空间(类似 Oracle 的 transportable tablespace)
FLUSH TABLES appdb.t_order FOR EXPORT;     -- 加读锁,生成 .cfg
-- 此时复制 t_order.ibd 和 t_order.cfg 到目标机
UNLOCK TABLES;

-- 在目标机导入
ALTER TABLE appdb.t_order DISCARD TABLESPACE;
-- 复制 .ibd 和 .cfg 到目标数据目录
ALTER TABLE appdb.t_order IMPORT TABLESPACE;

八、VMware 虚机存储注意事项

项 建议 原因
数据盘独立 /data 单独挂载一块虚拟磁盘,与系统盘分离 便于扩容、快照独立、IO 隔离
磁盘格式 Thick Eager Zeroed 数据库 IO 延迟敏感,Thin 首次写入有分配延迟
IO 控制器 Paravirtual (PVSCSI) 比 LSI Logic SAS 更高 IOPS,适合数据库
磁盘缓存 禁用读写缓存(虚拟机设置 → 高级) InnoDB 已有自己的 Buffer Pool,OS/VMware 缓存多余
磁盘模式 Independent - Persistent 防止快照回滚导致数据文件与 binlog 不一致
SSD 直通 宿主机 SSD 可直通给虚机(Virtual Disk 选 SSD) 显著提升随机 IO 性能

九、踩坑记录(实测汇总)

# 坑 现象 解决
1 5.7 升级 8.0 后 .frm 文件失效 表无法读取 8.0 数据字典统一管理,必须用 mysql_upgrade 或升级流程
2 ibdata1 膨胀不回收 系统表空间越来越大 5.7 前 innodb_file_per_table=OFF 导致,重建库迁移
3 innodb_flush_log_at_trx_commit=2 宕机丢 1 秒数据 生产必须设为 1
4 doublewrite 被关闭 断电后页损坏无法恢复 保持 innodb_doublewrite=ON
5 redo log 太小 刷盘频繁、性能抖动 8.0.30+ 调大 innodb_redo_log_capacity
6 binlog 格式 STATEMENT 主从数据不一致 生产统一 ROW 格式
7 undo 表空间不够 长事务导致 undo 膨胀 监控长事务,及时 kill;调大 undo 表空间
8 OPTIMIZE TABLE 锁表 业务高峰执行导致阻塞 低峰期执行,或用 pt-online-schema-change
9 VMware 快照回滚数据盘 binlog 位点断裂、主从复制报错 数据盘设为 Independent - Persistent
10 .ibd 文件被手动复制 表空间导入报错 必须用 FLUSH TABLES ... FOR EXPORT 正规导出
11 Buffer Pool 设太大 系统 OOM 或 swap 不超过物理内存 70%,留够 OS 和连接内存
12 页大小不匹配 数据文件无法跨版本恢复 页大小建库后不可改,统一用默认 16KB

十、要点速记

  1. InnoDB 是唯一生产选择:事务、行锁、MVCC、崩溃恢复全靠它。
  2. 三大日志分工:redo 保恢复(前滚)、undo 保回滚 + MVCC、binlog 保复制 + PITR。
  3. 双写缓冲防页半写:崩溃恢复的最后一道防线,生产必开。
  4. 8.0 默认 per_table 表空间:每表一个 .ibd,DROP/TRUNCATE 自动回收空间。
  5. Buffer Pool 是性能核心:建议物理内存 60~70%,命中率应 > 99%。

十一、参考资料(官方正式文档)

主题 官方链接
MySQL 8.0 Reference Manual https://dev.mysql.com/doc/refman/8.0/en/
InnoDB Storage Engine https://dev.mysql.com/doc/refman/8.0/en/innodb-storage-engine.html
InnoDB On-Disk Structures(表空间/页/区) https://dev.mysql.com/doc/refman/8.0/en/innodb-on-disk-structures.html
InnoDB Buffer Pool https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-pool.html
The Doublewrite Buffer https://dev.mysql.com/doc/refman/8.0/en/innodb-doublewrite-buffer.html
The Change Buffer https://dev.mysql.com/doc/refman/8.0/en/innodb-change-buffer.html
The Binary Log https://dev.mysql.com/doc/refman/8.0/en/binary-log.html
InnoDB Redo Log https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html
InnoDB Undo Logs https://dev.mysql.com/doc/refman/8.0/en/innodb-undo-logs.html

本文章属于《MySQL 数据库全栈运维实战系列》基础与架构篇。欢迎收藏、交流。

相关推荐
Z21-X1 小时前
云原生运维笔记:打通OpenStack的任督二脉——从Neutron网络踩坑到Swift与Heat硬核实战
运维·笔记·学习·云原生
瀚高PG实验室1 小时前
瀚高数据库提交数据后,是否需要COMMIT
数据库·postgresql·瀚高数据库
bksczm1 小时前
MySQL程序架构
数据库·mysql·架构
论文复现现场1 小时前
2026 低成本 AI Agent 模型怎么选?DeepSeek V4.1 Flash、Qwen3.8 Flash、GLM-5.3 Flash 对比
数据库·人工智能·qwen·ai agent·glm·deepseek
你看我名字2 小时前
云计算工程师技能树:从 Linux 基础到云平台架构能力
linux·架构·云计算
广州灵眸科技有限公司9 小时前
4G 模组开机自连 systemd 服务方案:基于灵眸科技EAI1106--Core-T
运维·服务器·科技
摇滚侠9 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试10 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
晶捷软件10 小时前
从 IT 架构视角看 ERP 选型:用友、金蝶与鼎捷生态(含晶捷智能)的技术差异
架构·智能制造·erp·制造业信息化