Skip to content

Latest commit

 

History

History
373 lines (298 loc) · 18.8 KB

File metadata and controls

373 lines (298 loc) · 18.8 KB

MySQL 面试模块

大厂后端面试的"必考四大件"之一(Redis / MySQL / JVM / 并发)。

本模块按 架构 → 存储引擎 → 事务并发 → 日志 → 性能优化 → 高可用 → 新特性 七层组织,每篇都按 senior 标准写:原理 + 取舍 + 面试追问 + 生产踩坑 + 答题模板。


一、模块导航

架构与执行(2 篇)

文档 一句话定位
MySQL 架构总览 接入 / Server / 引擎 / 系统文件四层 + 引擎对比
SQL 语句执行过程 查询流程 + 更新流程 + 两阶段提交(高频题)

存储引擎与索引(4 篇)

文档 一句话定位
InnoDB 存储引擎 Buffer Pool / Change Buffer / Double Write / AHI / 后台线程
索引 B+Tree / 聚簇索引 / 最左前缀 / 索引下推 / 失效场景
explain type / key_len / Extra 全解读 + 实战案例

事务与并发(5 篇)

层次关系:事务原理(基础)→ 隔离级别(行为)→ MVCC(快照机制)+ 锁(互斥机制)→ 死锁(错乱处理)。

[事务的原理]   ← ACID + 三大日志映射
     ↓
[事务的隔离级别]
     ├─ MVCC          ← 快照读,解决脏读 / 不可重复读 / 部分幻读
     └─ 锁机制         ← 解决当前读 / 写写
           ↓
     [死锁分析]        ← 锁冲突的兜底排查
文档 一句话定位
事务的原理 ACID 与 undo / redo / binlog 映射
事务的隔离级别 四级别 + RC vs RR 生产选型 + 幻读真相
MVCC 隐式字段 + 版本链 + ReadView + RC/RR 唯一区别
锁机制 全局 / 表 / 行 / 间隙 / 临键锁 + 加锁规则总结
死锁分析 5 种典型模式 + LATEST DETECTED DEADLOCK 排查

日志与崩溃恢复(1 篇)

文档 一句话定位
三大日志 redo / undo / binlog 对比 + 两阶段提交 + group commit

性能优化、设计与规范(3 篇)

文档 一句话定位
SQL 优化与慢查询分析 9 类优化手法 + pt-query-digest + 服务器调优
数据库设计与范式 三范式 + 反范式实战 + E-R 建模 + 订单系统设计
MySQL 开发规范 7 大类军规 + 每条背后的事故

高可用与扩展(3 篇)

文档 一句话定位
主从复制 三线程 + 异步/半同步 + GTID + 主从延迟治理
备份与恢复 mysqldump / Xtrabackup / PITR 时间点恢复 / 备份策略与验证
分库分表 四象限拆分 + 分片键 + 分布式新问题 + NewSQL 替代

新特性(1 篇)

文档 一句话定位
MySQL 8.0 新特性 窗口函数 / CTE / 隐藏索引 / Hash Join / 原子 DDL / JSON

二、面试高频题 → 文档映射

被问到这些题,直接跳到对应文档:

高频题 跳转
MySQL 架构有几层? 架构总览
InnoDB 和 MyISAM 区别? 架构总览 - 引擎对比
一条 update 语句的全过程? SQL 执行过程 - 更新流程
为什么要两阶段提交? SQL 执行过程 - 两阶段提交
崩溃恢复时事务怎么定生死? SQL 执行过程 / 日志
Buffer Pool 改良 LRU 是怎么回事? InnoDB - 改良 LRU
Change Buffer 解决什么问题?为什么不对唯一索引生效? InnoDB - Change Buffer
Double Write 解决什么?为什么 redo log 不够? InnoDB - Double Write
MySQL 索引为什么用 B+Tree? 索引 - 为什么是 B+Tree
聚簇索引和非聚簇索引区别? 索引 - 聚簇 vs 非聚簇
什么是回表?覆盖索引?索引下推? 索引 - 回表与覆盖
最左前缀原则?为什么范围列后续断索引? 索引 - 组合索引
索引为什么会失效? 索引 - 索引失效
EXPLAIN 怎么看? explain
Using filesort / Using temporary 怎么办? explain - Extra
ACID 各靠什么实现? 事务的原理
undo log 什么时候删? 事务的原理
脏读 / 不可重复读 / 幻读区别? 事务的隔离级别
MySQL 默认隔离级别是什么?为什么不是 RC? 事务的隔离级别
RR 解决幻读了吗? 事务的隔离级别 - RR 真的解决幻读吗
MVCC 怎么实现的?RC 和 RR 在 MVCC 上的差别? MVCC
ReadView 几个字段?可见性怎么判断? MVCC - ReadView
行锁是怎么实现的? 锁机制 - 行级锁
什么是 MDL?为什么生产容易出事? 锁机制 - MDL
意向锁是什么?为什么需要? 锁机制 - 意向锁
Gap Lock / Next-Key Lock 在哪个级别才有? 锁机制 - 行锁形态
加锁规则三原则? 锁机制 - 加锁规则
发生死锁怎么排查? 死锁分析
常见死锁模式? 死锁分析 - 典型模式
redo log 和 binlog 区别? 日志 - redo vs binlog
binlog 三种格式怎么选? 日志 - binlog
WAL 是什么?为什么 redo 顺序写比改数据页随机写快? 日志 - redo log
怎么发现慢 SQL? SQL 优化 - 慢日志
深分页怎么优化? SQL 优化 - 深分页
count(*) 慢吗?怎么优化? SQL 优化 - count
JOIN 怎么优化? SQL 优化 - JOIN
Java 批量 INSERT 为什么很慢? SQL 优化 - 批量插入
互联网公司的 MySQL 规范有哪些? MySQL 规范
单表多大需要分库分表? 分库分表 - 触发条件
分片键怎么选? 分库分表 - 分片键
跨片 JOIN / 跨片事务怎么办? 分库分表 - 分布式新问题
主从复制流程? 主从复制 - 三个线程
主从延迟根因和治理? 主从复制 - 延迟治理
异步 / 半同步 / 同步区别? 主从复制 - 复制模式
三范式各是什么?区别? 数据库设计与范式 - 三范式
互联网为什么不严格遵循范式? 数据库设计与范式 - 反范式
订单表为什么冗余 user_name / 商品价格? 数据库设计与范式 - 订单实战
MySQL 怎么备份?逻辑还是物理? 备份与恢复 - 逻辑 vs 物理
mysqldump 加 --single-transaction 的原理? 备份与恢复 - mysqldump
误删表怎么救?什么是 PITR? 备份与恢复 - PITR 流程
备份策略怎么定? 备份与恢复 - 生产策略
Xtrabackup 怎么实现热备? 备份与恢复 - Xtrabackup
MySQL 8.0 哪些新特性? MySQL 8.0 新特性
窗口函数和 GROUP BY 区别? MySQL 8.0 - 窗口函数
递归 CTE 应用场景? MySQL 8.0 - CTE
隐藏索引 / 函数索引怎么用? MySQL 8.0 - 索引能力
Hash Join 解决什么问题? MySQL 8.0 - Hash Join
原子 DDL 是什么? MySQL 8.0 - 原子 DDL
JSON 字段怎么建索引? MySQL 8.0 - JSON
8.0 升级要注意什么? MySQL 8.0 - 升级注意

三、推荐学习路径

新手路径(按依赖顺序)

基础层
 1. MySQL 架构总览                ← 全局视图
 2. SQL 执行过程                  ← 一条 SQL 的内部
 3. InnoDB 存储引擎               ← 存储 / 内存 / 后台线程

索引与查询
 4. 索引                          ← 必学,最高频考点
 5. explain                       ← 配合索引验证

事务与并发
 6. 事务的原理                     ← ACID + 三大日志
 7. 事务的隔离级别                 ← 4 级别 + RC/RR 选型
 8. MVCC                          ← 快照读机制
 9. 锁机制                        ← 互斥机制
10. 死锁分析                      ← 锁的兜底
11. 日志                          ← undo / redo / binlog 整合

设计与优化
12. 数据库设计与范式               ← 三范式 + 反范式实战
13. SQL 优化与慢查询              ← 性能调优
14. MySQL 开发规范                ← 上线前必看

高可用
15. 主从复制                      ← 高可用基础
16. 备份与恢复                    ← PITR 时间点恢复
17. 分库分表                      ← 横向扩展终极

新特性
18. MySQL 8.0 新特性              ← 窗口函数 / CTE / Hash Join

面试速通路径(30 分钟刷一遍)

每篇看 答题模板 一节就够:

架构与执行

存储与索引

事务与并发

设计与优化

高可用

新特性


四、关键速记表

4.1 InnoDB 关键参数

# 内存
innodb_buffer_pool_size       = 物理内存 × 0.5~0.75
innodb_buffer_pool_instances  = 8
innodb_log_buffer_size        = 16M

# redo log
innodb_log_file_size          = 1G ~ 4G
innodb_flush_log_at_trx_commit = 1     # 双 1 高可靠

# binlog
sync_binlog                   = 1
binlog_format                 = ROW
gtid_mode                     = ON

# 文件
innodb_file_per_table         = ON

# 复制
slave_parallel_type           = LOGICAL_CLOCK
slave_parallel_workers        = 8
slave_preserve_commit_order   = 1
rpl_semi_sync_master_enabled  = 1

# IO(SSD)
innodb_io_capacity            = 2000
innodb_flush_neighbors        = 0

# 监控
slow_query_log                = ON
long_query_time               = 0.5
innodb_print_all_deadlocks    = ON

4.2 三大日志一图

日志 类型 作用
undo InnoDB 逻辑(反向操作) 回滚 + MVCC
redo InnoDB 物理(页修改) 崩溃恢复
binlog Server 逻辑(行/SQL) 主从复制 + PITR

4.3 隔离级别 + 锁

级别 脏读 不可重复 幻读 实现
RU 不做特殊保护
RC MVCC(每次新 ReadView)
RR ✗* MVCC(首次 ReadView 复用)+ Gap Lock
Serializable 全 SELECT 加 S 锁

* 快照读由 ReadView 解,当前读由 Next-Key Lock 解

4.4 加锁规则速查

索引 查询 命中 锁形态
唯一索引 等值 命中 Record Lock
不命中 Gap Lock
范围 Next-Key Lock + 多锁一行
普通索引 等值 命中 Next-Key + 后续 Gap
不命中 Gap Lock
范围 Next-Key Lock

4.5 EXPLAIN type 排序

system > const > eq_ref > ref > range > index > ALL
                                           ↑       ↑
                                         警告    必须优化

4.6 索引失效场景

1. 函数 / 表达式:YEAR(t)=2024
2. 隐式类型转换:phone=13800138000 (varchar)
3. 左模糊:LIKE '%xx'
4. 跳过最左前缀
5. 范围列后续列断索引
6. OR 一边无索引
7. 区分度低(性别)→ 优化器放弃

4.7 高频生产参数

场景 配置
金融级零丢失 flush_log_at_trx_commit=1 + sync_binlog=1(双 1)
互联网高吞吐 flush_log_at_trx_commit=2 + sync_binlog=100~1000
半同步避免主挂丢数据 rpl_semi_sync_master_enabled=1
主从并行复制 slave_parallel_type=LOGICAL_CLOCK + 8 workers

4.8 MySQL 版本演进

版本 关键变化
5.5 InnoDB 成为默认引擎
5.6 在线 DDL;GTID;ICP;多线程 Purge
5.7 JSON;并行复制;Buffer Pool 在线 resize;undo 表空间独立
8.0 数据字典转 InnoDB(无 .frm);窗口函数;CTE;隐藏索引;移除 Query Cache;Hash Join;ATOMIC DDL

五、生产踩坑 TOP 10

文档
长事务卡 Purge → undo 膨胀 → 磁盘炸 MVCC
ALTER + 长事务 → MDL 锁全表 锁机制 - MDL
隐式类型转换吞 QPS(phone 字段不加引号) 索引 - 索引失效
大事务拆爆从库(ROW binlog 百万事件) 主从复制 - 延迟
索引太多 INSERT 慢一个量级 索引 - 单表索引数量
Java 批量 INSERT 实际还是逐条 SQL 优化 - 批量插入
sync_binlog=0 主从不一致 日志 - sync_binlog
深分页 LIMIT 1000000, 10 几十秒 SQL 优化 - 深分页
分库分表用 order_id 当分片键 → 全分片广播 分库分表 - 分片键
ibdata1 不收缩(没开 file_per_table) InnoDB

六、面试常被一连串追问的话题

按出现频率列出:

  1. 索引:B+Tree → 聚簇 vs 非聚簇 → 回表 → 覆盖索引 → 索引下推 → 失效
  2. MVCC:隐式字段 → 版本链 → ReadView → RC vs RR → 与幻读
  3. :全局 → 表 → MDL → 意向 → Record/Gap/Next-Key → 加锁规则
  4. 隔离级别:脏读/不可重复/幻读 → 4 级别 → RR 解决幻读 → RC vs RR 选型
  5. 日志:redo(物理 + WAL) → undo(回滚 + MVCC) → binlog(主从 + ROW) → 两阶段提交 → group commit
  6. 执行流程:连接 → Parser → Optimizer → Executor → Buffer Pool → 两阶段提交 → 主从
  7. 慢 SQL 优化:慢日志 → EXPLAIN → 索引 / SQL 改写 → 复测
  8. 死锁:必要条件 → InnoDB 检测 → LATEST DETECTED → 5 种模式 → 修复
  9. 主从:3 线程 → 异步/半同步 → GTID → 延迟根因 → 并行复制
  10. 分库分表:何时拆 → 分片键 → 跨片 JOIN/事务 → 全局 ID → 扩容
  11. 数据库设计:三范式 → 反范式动机 → E-R 建模 → 订单表为何冗余 user_name
  12. 备份恢复:mysqldump vs Xtrabackup → 全量 + 增量 → binlog → PITR 误删恢复 → 备份验证
  13. 8.0 新特性:窗口函数 → 递归 CTE → 隐藏索引 → Hash Join → 原子 DDL → JSON 索引

每条主线都对应至少一篇深度文档,按上方"高频题映射"快速跳转。


七、相关模块