十三Tech
数据库机制

图解 MySQL

从一条 SQL 的执行路径开始,拆到连接器、优化器、索引、事务、锁、日志、复制和备份恢复。

适合想系统补齐 MySQL 底层机制、排查路径和工程取舍的后端工程师。

3030/30 已完结最近更新 2026/6/17
阶段目录

按主题段落阅读

文章列表

完整目录

30
01

图解 MySQL 01|一条 SQL 怎么跑完:Server 层和存储引擎层那条缝

MySQL 被讲成「一个数据库」,但它其实是 Server 层 + 存储引擎层两块代码拼出来的。本文聊聊那条缝在哪里、为什么这么设计,以及看懂它能解决什么问题。

02

图解 MySQL 02|连接器:wait_timeout 和 interactive_timeout,99% 的人只改了一个

连接器被讲成「建立 TCP 连接 + 鉴权」,但出问题最多的不是建立而是断开。本文聊聊 wait_timeout 和 interactive_timeout 这对孪生参数,以及连接池配置的三个常见坑。

03

图解 MySQL 03|分析器 + 优化器 + 执行器:执行计划到底谁说了算

explain 看到的执行计划,跟实际跑出来的有时对不上。本文聊聊分析器、优化器、执行器三个组件怎么协作,以及优化器为什么会选错索引。

04

图解 MySQL 04|redo log:WAL 的精髓,kill -9 后数据不丢的真相

redo log 被讲成「崩溃恢复日志」,但它的精髓不是日志本身,而是 WAL(Write-Ahead Logging)思想。本文聊聊 redo log 的循环写结构、两阶段 checkpoint,以及为什么 kill -9 不丢数据。

05

图解 MySQL 05|binlog:跟 redo log 长得很像,但职责完全不同

binlog 被讲成「归档日志」,但它的真正角色是 MySQL 主从复制和数据恢复的协议层。本文聊聊 binlog 跟 redo log 的三大差别、三种 format 的坑,以及为什么 8.0 默认改用 ROW。

06

图解 MySQL 06|两阶段提交:redo log 和 binlog 怎么不打架

redo log 和 binlog 是两个独立日志,怎么保证要么都写成功要么都不写?答案就是两阶段提交。本文聊聊 prepare / binlog / commit 三步流程,以及崩溃恢复时 InnoDB 怎么判断事务到底有没有提交。

07

图解 MySQL 07|undo log:事务回滚和 MVCC 都靠它

undo log 被讲成「回滚日志」,但它的真正价值是承载 MVCC 的多版本。本文聊聊 undo log 怎么工作、三种操作各自的 undo 形态,以及大事务为什么会让 undo 段涨爆。

08

图解 MySQL 08|MVCC:快照读为什么不加锁

MVCC 被讲成「多版本并发控制」,但它的核心是一个叫 ReadView 的小结构。本文聊聊快照读和当前读的差别、ReadView 怎么判断版本可见性,以及 RC 和 RR 隔离级别的真正分野。

09

图解 MySQL 09|事务隔离级别:四个级别、三种异常、一图理清

隔离级别被讲成「读未提交 / 读已提交 / 可重复读 / 串行化」的名词解释,但真正理解它要看 SQL 标准和 InnoDB 实现的差别。本文聊聊三种异常、四个级别,以及为什么 MySQL 默认 RR。

10

图解 MySQL 10|锁:全局锁、表级锁、行级锁,三层粒度

MySQL 的锁被讲成「行锁」,但它其实是三层粒度——全局锁、表级锁、行级锁。本文聊聊每层的具体类型、应用场景,以及为什么 mysqldump 用 FTWRL 而不是 readonly。

11

图解 MySQL 11|行锁格式:Record / Gap / Next-Key 三种

行锁被讲成「锁住一行」,但 InnoDB 实际有三种格式——Record 锁单行、Gap 锁间隙、Next-Key 锁区间。本文聊聊三种格式的差别、加锁规则,以及为什么 SELECT WHERE id=10 可能锁住 id=15。

12

图解 MySQL 12|间隙锁深入:为什么 RR 下「看似无关的行」会被锁住

间隙锁被讲成「防幻读的机制」,但它的实际行为很反直觉——表里没数据也能锁住一个范围,两个事务插入不同 ID 也能死锁。本文聊聊间隙锁的诡异行为、死锁原理,以及怎么减轻它的影响。

13

图解 MySQL 13|死锁排查:SHOW ENGINE INNODB STATUS 到底怎么看

死锁不是数据库坏了,而是事务等待图里出现了环。本文聊聊死锁和锁等待的区别、SHOW ENGINE INNODB STATUS 怎么读、performance_schema 怎么辅助定位,以及生产中怎么修和兜底。

14

图解 MySQL 14|索引模型:B+ 树为什么适合数据库

索引不是“加速查询”的魔法,而是一套让磁盘 IO 可控的数据组织方式。本文聊聊哈希、有序数组、二叉树和 B+ 树的差别,以及为什么 InnoDB 最终选择 B+ 树。

15

图解 MySQL 15|主键索引与二级索引:回表到底在回什么

InnoDB 的主键索引叶子节点存整行,二级索引叶子节点存主键值。本文聊聊聚簇索引、二级索引、回表,以及为什么主键设计会影响整张表。

16

图解 MySQL 16|覆盖索引与最左前缀:联合索引怎么设计

联合索引不是把多个字段随手拼在一起。本文聊聊覆盖索引、最左前缀、字段顺序和排序复用,解释为什么索引设计本质上是查询模式设计。

17

图解 MySQL 17|索引下推:少回表之前先过滤

索引下推让存储引擎在遍历索引时先判断部分 where 条件,减少无意义回表。本文聊聊 ICP 解决什么问题、什么时候生效,以及 explain 里的 Using index condition 怎么看。

18

图解 MySQL 18|普通索引和唯一索引:change buffer 的取舍

普通索引和唯一索引不只是约束不同,它们的写入路径也不同。本文聊聊 change buffer 为什么只适合普通二级索引,以及写多读少场景下怎么取舍。

19

图解 MySQL 19|优化器统计信息:为什么 MySQL 会选错索引

优化器不是凭直觉选索引,而是根据统计信息估算成本。本文聊聊基数、采样、rows 估算、ANALYZE TABLE,以及为什么执行计划有时会选错。

20

图解 MySQL 20|EXPLAIN:执行计划里哪些字段最该看

EXPLAIN 不是背字段含义,而是还原 MySQL 准备怎么访问数据。本文聊聊 type、key、rows、Extra 的阅读顺序,以及如何用执行计划定位慢查询方向。

21

图解 MySQL 21|Buffer Pool:数据页为什么能命中内存

Buffer Pool 是 InnoDB 最核心的内存结构。本文聊聊数据页如何进入内存、LRU 为什么要分冷热区,以及为什么大查询可能冲击缓存命中率。

22

图解 MySQL 22|脏页与刷盘:为什么更新偶尔会抖一下

更新先改内存页并写 redo,数据页稍后刷盘。本文聊聊脏页、checkpoint、刷脏触发条件,以及为什么写入高峰会出现性能抖动。

23

图解 MySQL 23|count(*):为什么数行并不简单

count(*) 看起来只是数行,但 InnoDB 不能像 MyISAM 一样直接返回表总行数。本文聊聊 count(*)、count(1)、count(列) 的差别,以及大表计数怎么做。

24

图解 MySQL 24|ORDER BY:排序是怎么发生的

ORDER BY 可能复用索引顺序,也可能进入 filesort。本文聊聊索引排序、排序缓冲、全字段排序和 rowid 排序,以及分页为什么越翻越慢。

25

图解 MySQL 25|GROUP BY:分组为什么常常用临时表

GROUP BY 的核心是把同一组的数据聚到一起。本文聊聊索引分组、临时表聚合、Using temporary,以及如何减少大分组查询的代价。

26

图解 MySQL 26|JOIN:NLJ、BKA、Hash Join 怎么选

JOIN 慢不慢,取决于驱动表、被驱动表索引和连接算法。本文聊聊 Nested Loop Join、Batched Key Access、Hash Join,以及多表查询的优化方向。

27

图解 MySQL 27|临时表:内存表、磁盘表和大查询的代价

临时表是 MySQL 执行复杂查询时的中间工作台。本文聊聊内部临时表何时出现、为什么会从内存转磁盘,以及如何降低临时表成本。

28

图解 MySQL 28|主从复制:binlog 怎么变成从库数据

主从复制不是简单“拷贝数据”,而是从库拉取主库 binlog 后重放。本文聊聊 binlog dump、relay log、SQL 线程、GTID,以及复制链路的关键风险。

29

图解 MySQL 29|主从延迟:读写分离为什么会读到旧数据

读写分离提升吞吐,也会引入主从延迟。本文聊聊延迟来源、Seconds_Behind_Source 的局限、并行复制,以及业务上怎么做读一致性。

30

图解 MySQL 30|备份恢复:从全量备份到 PITR 的闭环

备份不是把文件存起来,而是能在事故时恢复到目标时间点。本文聊聊逻辑备份、物理备份、binlog 增量恢复、恢复演练,以及图解 MySQL 系列的最终收束。