📖 本篇简介:理解 InnoDB 架构是从"会写 SQL"到"懂数据库"的分水岭。本篇用 16 道高频题串起 InnoDB 的三大块——内存结构(Buffer Pool、Change Buffer、Log Buffer、AHI)、磁盘结构(表空间/段/区/页、doublewrite)、后台线程(page cleaner、purge、IO 线程),讲清 WAL、刷脏页、checkpoint 等运行机制。学完本篇,你能讲清"为什么内存命中率这么重要""为什么随机写性能不差""redo log 写满会怎样"。前置知识:第 3~6 章事务、锁、MVCC;本系列示例基于 MySQL 8.0。
目录
- 1 InnoDB 架构高频考点地图
- 题目 1InnoDB 整体架构分哪几块
- 题目 2Buffer Pool 是干什么的怎么配大小
- 题目 3Change Buffer 是什么解决什么问题
- 题目 4Log Buffer 是干什么的
- 题目 5Adaptive Hash Index 自适应哈希是什么
- 题目 6InnoDB 磁盘结构表空间段区页是什么关系
- 题目 7doublewrite 双写缓冲解决什么问题
- 题目 8后台线程有哪些各自干什么
- 题目 9脏页是什么时候怎么刷盘checkpoint 是什么
- 题目 10WAL 预写日志是怎么回事
- 题目 11redo log 写满会怎样
- 题目 12InnoDB 页大小为什么是 16K
- 题目 13怎么看 InnoDB 运行状态SHOW ENGINE INNODB STATUS
- 题目 14Buffer Pool 命中率怎么算低了怎么办
- 题目 15临出问题时 InnoDB 有哪些关键监控指标
- 题目 16InnoDB 内存结构和磁盘结构怎么协同
- InnoDB 架构速查表
- 常见坑与注意事项
- 复习清单
- 练习题
1 InnoDB 架构高频考点地图
| 难度 | 典型问题 | 本篇对应 |
|---|---|---|
| 入门 | 整体架构?Buffer Pool? | 题目 1、2 |
| 基础 | Change Buffer?doublewrite? | 题目 3、7 |
| 进阶 | WAL?刷脏页?checkpoint? | 题目 9、10 |
| 实战 | 命中率?redo 写满? | 题目 11、14 |
一条主线记住:InnoDB 把数据缓存在 Buffer Pool,写先记 redo log(WAL),脏页异步刷盘;崩溃靠 redo 重放恢复。所有性能问题都围绕"内存命中率 + 刷盘速度"。
题目 1:InnoDB 整体架构分哪几块?
考点
- 内存结构;
- 磁盘结构;
- 后台线程。
参考答案
InnoDB 架构分三块:
1. 内存结构:
- Buffer Pool(数据/索引页缓存);
- Change Buffer(二级索引写缓冲);
- Log Buffer(redo log 缓冲);
- Adaptive Hash Index(自适应哈希);
2. 磁盘结构:
- 系统表空间(ibdata1)、独立表空间(*.ibd);
- redo log(ib_logfile)、undo log 表空间、临时表空间;
- doublewrite buffer;
3. 后台线程:master thread、IO 线程、page cleaner、purge thread。
- 一句话:内存扛热数据,磁盘持久化,后台线程异步刷。
-- 查看内存结构大小(MySQL 8.0)
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; -- 通常物理内存 50%~70%
SHOW VARIABLES LIKE 'innodb_log_buffer_size'; -- 默认 16M
SHOW VARIABLES LIKE 'innodb_change_buffer_max_size';
追问
- 问:Buffer Pool 和 OS page cache 区别?答:Buffer Pool 是 InnoDB 自己管理的页缓存(带 LRU、脏页标记);OS page cache 是操作系统文件缓存,多了一层。
- 问:为什么 InnoDB 不直接用 OS cache?答:自己管理能做预热、脏页刷新策略、压缩,比 OS cache 更懂数据库访问模式。
题目 2:Buffer Pool 是干什么的?怎么配大小?
考点
- 数据页缓存;
- 减少磁盘 IO;
- 推荐内存 50%~70%。
参考答案
- Buffer Pool:InnoDB 在内存中缓存数据页和索引页的区域,单位是页(16KB);
- 读数据先查 Buffer Pool,命中就直接返回,未命中才从磁盘读页;
- 写数据先改 Buffer Pool 里的页(标记为脏页),后台异步刷盘;
- 配置:
innodb_buffer_pool_size,专用数据库服务器建议物理内存的 50%~70%(留内存给 OS、连接、其他进程); - 8.0 支持多实例 Buffer Pool(
innodb_buffer_pool_instances),减少并发锁竞争。
-- 查看 Buffer Pool 配置和状态
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'innodb_buffer_pool_instances';
-- 命中率:
SHOW STATUS LIKE 'Innodb_buffer_pool_read_requests'; -- 逻辑读
SHOW STATUS LIKE 'Innodb_buffer_pool_reads'; -- 物理读
-- 命中率 = 1 - reads / read_requests
追问
- 问:Buffer Pool 满了怎么办?答:LRU 链表淘汰冷页;InnoDB 用改进的 LRU(midpoint insertion)防止全表扫描污染缓冲池。
- 问: Buffer Pool 能热扩容吗?答:8.0 支持
SET GLOBAL innodb_buffer_pool_size=...在线调整,不用重启。
题目 3:Change Buffer 是什么?解决什么问题?
考点
- 二级索引写缓冲;
- 减少随机 IO;
- 8.0 改名 change buffer。
参考答案
- Change Buffer:对非唯一二级索引的写操作(INSERT/UPDATE/DELETE),如果对应的索引页不在 Buffer Pool,不立即从磁盘读页,而是把修改记录到 Change Buffer;等以后这个索引页被读到内存时,再把修改 merge 进去;
- 解决的问题:二级索引叶子是随机位置,写操作会导致大量随机读磁盘,性能差;Change Buffer 把这些写"攒"起来合并,把随机 IO 变顺序 IO;
- 只对非唯一索引生效(唯一索引必须读页校验唯一性,不能延迟)。
-- 查看 Change Buffer 状态
SHOW ENGINE INNODB STATUS\G
-- INSERT BUFFER AND ADAPTIVE HASH INDEX 段
-- merged operations:合并次数
SHOW VARIABLES LIKE 'innodb_change_buffer_max_size'; -- 占 Buffer Pool 百分比
追问
- 问:唯一索引用 Change Buffer 吗?答:不用,唯一索引要立刻校验重复,必须读页。
- 问:Change Buffer 会不会丢数据?答:不会,它的修改也记 redo log,宕机后能恢复。
题目 4:Log Buffer 是干什么的?
考点
- redo log 内存缓冲;
- 批量刷盘;
- innodb_flush_log_at_trx_commit。
参考答案
- Log Buffer(redo log buffer):内存中待写 redo log 的缓冲区;
- 事务提交时根据
innodb_flush_log_at_trx_commit决定怎么刷盘: - =1:每次 commit 都 fsync 到磁盘,最安全;
- =2:commit 写 OS cache,每秒 fsync;
- =0:每秒刷盘(MySQL 崩丢 1 秒);
- 默认 16MB,大事务/高并发写入可适当调大。
SHOW VARIABLES LIKE 'innodb_log_buffer_size';
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'; -- 金融场景必须 1
追问
- 问:Log Buffer 满了会怎样?答:自动刷盘到 redo log 文件,性能下降。
- 问:为什么不直接每次写盘?答:fsync 很慢,批量写 + 组提交才能扛住高并发。
题目 5:Adaptive Hash Index 自适应哈希是什么?
考点
- InnoDB 自动加的哈希索引;
- 对频繁等值查询加速;
- 用户不可控。
参考答案
- AHI(Adaptive Hash Index):InnoDB 监控索引的查询模式,发现某个 B+ 树叶子被频繁等值访问,自动在其上建一层哈希索引;
- 效果:等值查询从"沿 B+ 树走 3~4 层"变成 O(1) 哈希查找;
- 对用户透明,不需要也不能手动建;
- 8.0 默认开启
innodb_adaptive_hash_index=ON。
SHOW VARIABLES LIKE 'innodb_adaptive_hash_index';
SHOW ENGINE INNODB STATUS\G
-- INSERT BUFFER AND ADAPTIVE HASH INDEX 段看命中率
追问
- 问:AHI 什么时候反而拖性能?答:热点极端、哈希桶冲突多时,内部 latch 竞争激烈,可关闭测试。
- 问:为什么 InnoDB 不直接用哈希索引?答:哈希不支持范围查询和排序,B+ 树通用;AHI 只在热点等值上加,是补充。
题目 6:InnoDB 磁盘结构:表空间、段、区、页是什么关系?
考点
- 从大到小:tablespace → segment → extent → page;
- 页 16K;区 1MB(64 页);
- 段 = 索引叶子段 + 非叶子段 + 回滚段。
参考答案
InnoDB 磁盘空间层次(从大到小):
| 层级 | 大小 | 说明 |
|---|---|---|
| 表空间 tablespace | 整个文件 | 独立表空间 *.ibd 或共享 ibdata1 |
| 段 segment | 多个区 | 数据段(叶子节点)+ 索引段(非叶子)+ 回滚段 |
| 区 extent | 1MB = 64 页 | 空间分配的最小单位 |
| 页 page | 16KB | 磁盘 IO 和 Buffer Pool 的最小单位 |
- 一次磁盘 IO 读写一页(16KB);
- 空间按区分配,避免碎片;
- 8.0 默认每张表独立表空间(
innodb_file_per_table=ON)。
SHOW VARIABLES LIKE 'innodb_page_size'; -- 16384 = 16K
SHOW VARIABLES LIKE 'innodb_file_per_table'; -- ON
-- 每张表对应一个 .ibd 文件
追问
- 问:为什么不用更小的页?答:页太小扇出小、树高变高;16K 是权衡。
- 问:独立表空间和共享表空间区别?答:独立表空间 per 表一个 .ibd,drop table 直接回收;共享 ibdata1 不会自动缩小,历史坑。
题目 7:doublewrite 双写缓冲解决什么问题?
考点
- partial page write 半页写;
- 先写 doublewrite 再写真实位置;
- 恢复时用副本。
参考答案
- 问题:InnoDB 页 16KB,OS 块 4KB。写页时如果写到一半宕机(断电),这个页就是损坏的(partial page write);
- doublewrite:脏页刷盘时,先写到系统表空间的 doublewrite 区(连续 2MB),再写到真实位置;
- 恢复时:如果真实页损坏,从 doublewrite 区复制一份完整页,再用 redo 重放;
- 8.0 默认开启,性能损耗约 5%,换来数据安全。
SHOW VARIABLES LIKE 'innodb_doublewrite'; -- ON
-- 8.0.20+ 支持 atomic write(O_DIRECT + 原子写),可替代 doublewrite
追问
- 问:为什么 redo log 不能直接修复半页写?答:redo 是"页某偏移改成某值",前提是页本身完好;页都坏了 redo 无从应用。
- 问:ssd 还需要 doublewrite 吗?答:SSD 也可能半页写,仍然需要;支持原子写的 NVMe + O_DIRECT 可关。
题目 8:后台线程有哪些?各自干什么?
考点
- master thread;
- IO 线程;
- page cleaner;
- purge thread。
参考答案
| 线程 | 职责 |
|---|---|
| master thread | 全局调度,刷脏页、merge change buffer、undo 清理 |
| read/write IO thread | 处理异步 IO 请求(预读、写页) |
| page cleaner | 把 Buffer Pool 脏页刷到磁盘 |
| purge thread | 清理已提交事务的 undo log 和删除标记 |
| redo log flush thread | 把 log buffer 刷到 redo 文件 |
| monitor thread | 监控状态、打印错误日志 |
- 这些线程都在后台跑,业务请求不直接等它们;
- purge 线程和 MVCC 直接相关(见第 6 章)。
追问
- 问:page cleaner 刷太猛会怎样?答:刷脏页占 IO 带宽,业务请求变慢,这就是"checkpoint 抖动"。
- 问:purge 线程数能调吗?答:
innodb_purge_threads,默认 4,大库可调大。
题目 9:脏页是什么时候、怎么刷盘?checkpoint 是什么?
考点
- 脏页 = 内存页 ≠ 磁盘页;
- 刷盘时机;
- checkpoint 推进 redo 覆盖点。
参考答案
- 脏页:Buffer Pool 里被修改过但还没写回磁盘的页;
- 刷脏页时机:
1. Buffer Pool 空闲页不足,LRU 淘汰冷脏页;
2. redo log 写满,推进 checkpoint;
3. 系统空闲时 master thread 主动刷;
4. 正常关闭;
- checkpoint:标记"这个点之前的脏页都已经落盘",redo log 只需要重放 checkpoint 之后的;
- 刷脏页用双写(先 doublewrite 再真实位置),保证不半页写。
-- 查看脏页和 checkpoint
SHOW ENGINE INNODB STATUS\G
-- BUFFER POOL AND MEMORY 段:Dirty pages 数量
-- LOG 段:Log sequence number / Log flushed up to / Pages flushed up to
追问
- 问:刷脏页会阻塞业务吗?答:大量刷时占 IO 带宽,业务慢查询增多;大促前要预热 + 控刷脏速度。
- 问:怎么调刷脏速度?答:
innodb_io_capacity、innodb_io_capacity_max,SSD 可设大(如 2000),机械盘小(200)。
题目 10:WAL 预写日志是怎么回事?
考点
- Write-Ahead Logging;
- 先写 redo log 再改数据页;
- 保证持久性。
参考答案
- WAL(Write-Ahead Logging):修改数据时,先把修改写到 redo log(顺序写),再改内存页;redo log 落盘后才返回 COMMIT 成功;
- 数据页本身的修改(随机写磁盘)由后台异步刷;
- 优点:
1. 把随机写数据页变成顺序写 redo log,性能高;
2. 宕机时靠 redo log 重放,不丢已提交事务;
- 这是 InnoDB 持久性的核心(见第 3 章)。
-- WAL 流程:
-- 1. 修改 Buffer Pool 数据页(标记脏)
-- 2. 写 redo log buffer
-- 3. commit 时 redo log 刷盘(fsync)
-- 4. 返回成功
-- 5. 后台慢慢把脏页刷到数据文件
追问
- 问:redo log 是顺序写还是随机写?答:顺序写,固定文件循环追加,这是它快的原因。
- 问:数据页写盘是顺序还是随机?答:随机写,所以慢,靠 Buffer Pool 缓存吸收。
题目 11:redo log 写满会怎样?
考点
- 循环写;
- 写满触发 forced checkpoint;
- 业务阻塞。
参考答案
- redo log 是固定大小的循环文件(如 2 个 1GB 文件);
- 写满时,InnoDB 必须推进 checkpoint:把 checkpoint 之前的脏页全部刷盘,否则新的 redo 没地方写;
- 这叫 forced checkpoint,此时业务写入被阻塞,直到脏页刷出空间;
- 大促前要检查 redo log 大小,太小会频繁触发阻塞。
SHOW VARIABLES LIKE 'innodb_log_file_size'; -- 单个 redo 文件大小
SHOW VARIABLES LIKE 'innodb_log_files_in_group'; -- 文件个数,默认 2
-- 总 redo = file_size × files_in_group
追问
- 问:redo log 多大合适?答:1~4GB,能撑 10 分钟以上写入,避免频繁 forced checkpoint;8.0.30+ 支持动态调整。
- 问:怎么知道是不是写满了?答:
SHOW ENGINE INNODB STATUS的 LOG 段,checkpoint age 接近总 redo 大小就要警惕。
题目 12:InnoDB 页大小为什么是 16K?
考点
- 页 = IO 最小单位;
- 与磁盘、B+ 树扇出的权衡;
- 可改但不建议。
参考答案
- InnoDB 默认页大小 16KB,是磁盘 IO 和 Buffer Pool 的最小单位;
- 为什么是 16K:
1. B+ 树非叶子节点一页能存更多键(扇出大),树高 3 层能覆盖亿级行;
2. 与磁盘块(4K)对齐,4 倍于块大小,减少读放大;
3. 与 OS page cache 配合好;
- 理论上可改(4K/8K/16K/32K/64K),但要初始化时指定,生产几乎不改。
SHOW VARIABLES LIKE 'innodb_page_size'; -- 16384
追问
- 问:页越大越好吗?答:页大扇出大但单页 IO 成本高、缓存效率低;16K 是经验值。
- 问:一行超过 16K 怎么办?答:大字段(TEXT/BLOB)存页外(off-page),页内只留前缀和指针。
题目 13:怎么看 InnoDB 运行状态?SHOW ENGINE INNODB STATUS
考点
- 重要段落;
- TRANSACTIONS / BUFFER POOL / LOG / ROW OPERATIONS;
- 实战排查入口。
参考答案
SHOW ENGINE INNODB STATUS\G 输出重要段落:
| 段落 | 看什么 |
|---|---|
| BACKGROUND THREAD | 主线程状态、pending IO |
| SEMAPHORES | 锁等待、信号量竞争(高并发瓶颈) |
| TRANSACTIONS | 长事务、history list length |
| FILE I/O | IO 读写等待 |
| INSERT BUFFER AND ADAPTIVE HASH INDEX | change buffer、AHI 命中率 |
| LOG | redo 写入、checkpoint age |
| BUFFER POOL AND MEMORY | 脏页数、空闲页数、命中率 |
| ROW OPERATIONS | 当前 SQL、读写行数 |
- 线上排查第一入口;关键指标有异常要进一步查。
追问
- 问:输出太长怎么办?答:
innodb_status_output_locks=ON打印锁;也可以查performance_schema各表。 - 问:history list length 多少算高?答:持续 > 100 万要查长事务。
题目 14:Buffer Pool 命中率怎么算?低了怎么办?
考点
- 命中率公式;
- 低 = 内存不够或访问模式差;
- 解决:加内存、优化查询。
参考答案
- 命中率公式:
命中率 = 1 - Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
read_requests:逻辑读(Buffer Pool 命中请求);reads:物理读(磁盘读页次数);- 健康的数据库命中率应 > 99%;
- 低了怎么办:
1. 内存不够 → 调大 innodb_buffer_pool_size;
2. 全表扫描太多 → 加索引,避免大查询污染缓冲池;
3. 冷数据多 → 考虑分区、归档。
SHOW STATUS LIKE 'Innodb_buffer_pool_read_requests';
SHOW STATUS LIKE 'Innodb_buffer_pool_reads';
-- 算命中率:
-- 1 - reads / read_requests
追问
- 问:全表扫描会污染 Buffer Pool 吗?答:会,InnoDB 用 midpoint LRU 把全表扫描读到的页放 young 区末尾,快速淘汰,减少污染。
- 问:命中率 95% 算低吗?答:看数据量,小库 95% 也正常;大库要求 99%+。
题目 15:临出问题时 InnoDB 有哪些关键监控指标?
考点
- 缓冲池命中;
- 行锁等待;
- history list;
- checkpoint age。
参考答案
线上 InnoDB 必看指标:
| 指标 | 查看方式 | 健康值 |
|---|---|---|
| Buffer Pool 命中率 | SHOW STATUS | > 99% |
| 脏页比例 | BUFFER POOL 段 | < 10% |
| history list length | TRANSACTIONS 段 | < 100 万 |
| 行锁等待数 | Innodb_row_lock_waits | 平稳不暴涨 |
| checkpoint age | LOG 段 | < 70% redo 总量 |
| 活跃事务数 | INNODB_TRX | < 几十 |
- 这些指标接 Prometheus/Grafana 告警,是 DBA 日常。
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock_waits';
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock_time_avg';
追问
- 问:脏页比例高怎么办?答:调大
innodb_io_capacity让刷脏更快,或降低写入峰值。 - 问:行锁等待暴涨说明什么?答:热点行并发写冲突,要业务侧拆分。
题目 16:InnoDB 内存结构和磁盘结构怎么协同?
考点
- 读路径;
- 写路径;
- 一致性保证。
参考答案
读路径:
1. 查 Buffer Pool 是否有目标页;
2. 命中 → 直接返回(MVCC 判断版本);
3. 未命中 → 从磁盘读页进 Buffer Pool,再返回。
写路径:
1. 找到目标页(不在则读入 Buffer Pool);
2. 修改内存页,标记脏;
3. 写 redo log buffer;
4. commit 时 redo 刷盘;
5. 后台 page cleaner 异步把脏页刷到磁盘。
- 一致性:redo log 保证崩溃恢复,doublewrite 保证页不半写,MVCC 保证读一致。
追问
- 问:为什么写不直接刷磁盘?答:随机写太慢,靠 Buffer Pool 攒批 + redo 顺序写,吞吐提升百倍。
- 问:宕机丢数据吗?答:已 commit 的事务 redo 已刷盘,重启重放不丢;未 commit 的靠 undo 回滚。
InnoDB 架构速查表
| 组件 | 位置 | 作用 | 关键参数 |
|---|---|---|---|
| Buffer Pool | 内存 | 缓存数据/索引页 | innodb_buffer_pool_size |
| Change Buffer | 内存 | 二级索引写合并 | innodb_change_buffer_max_size |
| Log Buffer | 内存 | redo 缓冲 | innodb_log_buffer_size |
| AHI | 内存 | 热点等值哈希加速 | innodb_adaptive_hash_index |
| doublewrite | 磁盘 | 防半页写 | innodb_doublewrite |
| redo log | 磁盘 | WAL 崩溃恢复 | innodb_log_file_size |
| undo log | 磁盘 | 回滚 + MVCC | 独立表空间 |
| 页 | 磁盘 | IO 最小单位 16K | innodb_page_size |
| 读/写路径 | 步骤 |
|---|---|
| 读 | Buffer Pool 命中 → 返回;未命中 → 读页进内存 → MVCC 判断 |
| 写 | 改内存页(脏)→ 写 redo buffer → commit 刷 redo → 后台刷脏页 |
常见坑与注意事项
1. Buffer Pool 设成物理内存 90%+:OS 和连接没内存用,swap 一发整机卡。
2. redo log 太小:高并发下 forced checkpoint 频繁,业务写入抖动。
3. change buffer 被误以为是 undo:它是二级索引写缓冲,不是回滚日志。
4. doublewrite 关掉图快:断电半页写,恢复时页损坏,数据丢失风险。
5. 大查询跑在业务高峰:全表扫描把 Buffer Pool 污染,热点页被挤出,命中率骤降。
6. history list length 暴涨不查:长事务拖 undo,磁盘写满。
7. 以为 Buffer Pool 命中率 100% 才好:100% 反而可能说明数据量小于内存,要关注增长趋势。
复习清单
| 题目 | 核心结论 | 易错点 |
|---|---|---|
| 架构分层 | 内存 + 磁盘 + 后台线程 | 漏了 change buffer |
| Buffer Pool | 数据页缓存,50~70% 内存 | 与 OS cache 混淆 |
| Change Buffer | 二级索引写合并 | 唯一索引不用 |
| doublewrite | 防半页写 | 以为 redo 能替代 |
| WAL | 先写 redo 再改页 | 顺序写 redo 随机写页 |
| 脏页刷盘 | 异步 + checkpoint | 忘了 doublewrite |
| redo 写满 | forced checkpoint 阻塞写 | 以为 redo 会自动 truncate |
| 页大小 | 16K,IO 最小单位 | 答成 4K |
| 命中率 | 1 - reads/read_requests | 公式记反 |
| 长事务 | 拖 purge,undo 暴涨 | 只读事务不算 |
练习题
练 1:一台 32GB 内存的数据库服务器,innodb_buffer_pool_size 设多少合适?为什么?
<details>
<summary>参考答案</summary>
建议 18~22GB(物理内存的 50%~70%)。留 30%~50% 给 OS page cache、连接线程、临时表、系统进程。全给 Buffer Pool 会导致 OS 缺内存触发 swap,整机性能暴跌。8.0 可拆成多个 instance(如 4×5GB)减少锁竞争。
</details>
练 2:写入高峰时业务突然变慢,SHOW ENGINE INNODB STATUS 看到 LOG 段 checkpoint age 接近 redo 总大小。这是什么问题?怎么缓解?
<details>
<summary>参考答案</summary>
redo log 写满触发 forced checkpoint,page cleaner 必须拼命刷脏页才能腾出 redo 空间,IO 打满,业务写入阻塞。缓解:
1. 临时调大 innodb_io_capacity/max 让刷脏更快;
2. 调大 redo log 大小(8.0.30+ 在线调);
3. 业务侧削峰,避免瞬时写入尖峰。
</details>
练 3:为什么 InnoDB 写性能比 MyISAM 好?从架构上解释。
<details>
<summary>参考答案</summary>
MyISAM 只有表锁,写一来全堵;InnoDB:
1. 行锁,写不互斥不同行;
2. WAL:写先到 redo(顺序写)+ Buffer Pool,commit 快;
3. Change Buffer 把二级索引随机写合并;
4. 脏页异步刷盘,不等 IO。
综合下来写并发远高于 MyISAM。
</details>
下一篇预告:第 8 章 存储引擎对比与选型面试精讲
文章回复
0 条公开回复