D
AI
学习工作台
后端面试题2026-05-221 分钟阅读

MySQL InnoDB 深度解析

聚簇索引、事务隔离、MVCC、锁与日志

MySQLInnoDB索引事务后端面试记笔记标记疑惑

InnoDB 存储结构

默认引擎 InnoDB,支持事务、行级锁、外键(少用)。数据按 B+ 树聚簇索引 组织:叶子节点存完整行,非叶子存主键路由。表若无主键会选唯一非空列或隐式 row_id。

二级索引叶子存主键值,查询需回表;覆盖索引(索引含查询列)可避免回表。

-- 联合索引 (a, b, c) 最左前缀:可用 a; a,b; a,b,c
EXPLAIN SELECT id, b FROM t WHERE a = 1 AND b = 2;
-- Extra: Using index 表示覆盖索引

事务 ACID 与隔离级别

| 级别 | 脏读 | 不可重复读 | 幻读 | |---|---|---|---| | READ UNCOMMITTED | 可能 | 可能 | 可能 | | READ COMMITTED | 否 | 可能 | 可能 | | REPEATABLE READ | 否 | 否* | InnoDB 大体防 | | SERIALIZABLE | 否 | 否 | 否 |

*RC 下每次 SELECT 新快照;RR 下同一事务 Read View 不变。

MVCC:undo log 版本链 + Read View;快照读 普通 SELECT 无锁;当前读 SELECT ... FOR UPDATEUPDATE/DELETE 加锁。

锁类型

  • Record Lock:记录上的锁。
  • Gap Lock:间隙,防插入幻读。
  • Next-Key Lock:Record + Gap,RR 默认。
死锁:InnoDB 检测回滚代价小的事务。开发上固定索引顺序访问多行、缩短事务、避免大事务。

日志体系

  • redo log:WAL,Page 物理修改,循环写,崩溃恢复
  • undo log:回滚与 MVCC 历史版本。
  • binlog:逻辑日志,主从、备份;与 redo 两阶段提交(prepare → commit)保证一致性。
刷盘innodb_flush_log_at_trx_commit=1 每次提交刷 redo,最安全;=2 写 OS 缓存,依赖 fsync。

优化与实践

  • 建索引看 WHERE / ORDER / JOIN 列,避免函数破坏索引。
  • 长事务阻塞 undo 清理,导致表膨胀。
  • 大分页用 WHERE id > last_id LIMIT n 替代深 OFFSET
  • 执行计划关注 typekeyrowsExtra(Using filesort/temporary 警惕)。

延伸阅读

站内专题 MySQL 面试章节 有更系统的刷题路线、手写 SQL 与场景题拆解,建议与本篇索引/事务/日志三角对照复习。

面试答题路径:场景(慢查询/死锁)→ 原理(索引/锁/MVCC)→ 手段(EXPLAIN、改 SQL、拆库表)→ 风险(主从延迟、锁等待),体现完整工程思维。

知识卡片

问题

InnoDB 聚簇索引是什么?

点击翻转查看答案

答案

叶子节点存整行数据,表数据按主键顺序组织;二级索引叶子存主键值,回表再查聚簇索引。

问题

MVCC 如何实现可重复读?

点击翻转查看答案

答案

每行有隐藏版本号/undo 链,Read View 决定可见性;快照读不加锁,当前读用 next-key lock。

问题

redo log 与 binlog 区别?

点击翻转查看答案

答案

redo InnoDB 物理页恢复,崩溃安全;binlog 服务层逻辑日志,主从复制与点对点恢复;两阶段提交保证一致。