MySQL(关系型数据库)与分库分表
0. 正式分册入口与阅读顺序
本文件保留第一轮主线、图解、数据演绎和题目索引;复习时先读 00 建立全景,再按 01 至 08 逐册深入。遇到线上故障或面试串讲,可直接回到 08,再反查对应原理分册。
- 00-知识图谱与复习路线:先确定能力地图、题目迁移关系和阅读节奏。
- 01-InnoDB(事务存储引擎)页、行与 Buffer Pool(缓冲池):理解数据如何落到页、如何被缓存和刷盘。
- 02-B+Tree(多路平衡树)索引与优化器:学习访问路径、回表与执行计划判断。
- 03-事务隔离与 MVCC(多版本并发控制):掌握一致性读、当前读和版本可见性。
- 04-InnoDB(事务存储引擎)锁与死锁:掌握锁范围、等待链和死锁治理。
- 05-undo(撤销日志)、redo(重做日志)、binlog(二进制日志)与崩溃恢复:串起提交、恢复和数据修复。
- 06-复制高可用与备份恢复:处理复制延迟、切换和恢复边界。
- 07-分库分表与迁移:学习分片、扩容和双写校验。
- 08-线上排障项目话术与综合题库:把原理转成排障证据链与可复述项目话术。
阅读顺序:
00 → 01 → 02 → 03 → 04 → 05 → 06 → 07 → 08。主文档的第 10 章只作旧题索引,具体机制以对应正式分册为准。
1. 简历关联点
简历中写到“精通 MySQL(关系型数据库)、PostgreSQL(关系型数据库),具备 SQL(结构化查询语言)调优、索引优化实战经验;熟练使用 ShardingSphere(分库分表中间件)、MyCat(数据库中间件),有海量数据下的分库分表架构设计与落地经验”。面试高频追问集中在:
- InnoDB(事务存储引擎)为什么使用 B+Tree(多路平衡树)索引。
- 聚簇索引、二级索引、回表、覆盖索引是什么。
- MVCC(多版本并发控制)如何通过 undo log(回滚日志)和 Read View(读视图)实现快照读。
- redo log(重做日志)、binlog(二进制日志)、undo log(回滚日志)分别解决什么问题。
- 行锁、间隙锁、临键锁、意向锁、元数据锁如何工作。
- 死锁如何排查和规避。
- 分库分表如何选择分片键,如何处理全局 ID(全局唯一标识)、跨库查询、分页、事务。
2. 面试主线
建议按“存储结构 -> 索引 -> 事务 -> 日志 -> 锁 -> 调优 -> 分库分表 -> 项目落地”的顺序回答。
- MySQL(关系型数据库)性能基础是 InnoDB(事务存储引擎)页结构和 B+Tree(多路平衡树)索引。
- 事务隔离依赖锁和 MVCC(多版本并发控制),读写并发的核心是快照读和当前读。
- 日志体系分工明确:undo log(回滚日志)保证回滚和版本链,redo log(重做日志)保证崩溃恢复,binlog(二进制日志)保证复制和归档。
- 锁不是只背概念,要能用数据范围演绎行锁、间隙锁、临键锁。
- 分库分表是容量和性能方案,但会牺牲单库事务、查询灵活性和开发复杂度。
3. 基础知识
3.1 InnoDB(事务存储引擎)页与 B+Tree(多路平衡树)
InnoDB(事务存储引擎)以页为基本 I/O(输入输出)单位,常见页大小是 16KB(千字节)。B+Tree(多路平衡树)适合数据库索引,因为树高低、范围查询友好、叶子节点有序。
flowchart TD
R["根节点\n索引键 30 / 60"] --> N1["内部节点\n10 / 20"]
R --> N2["内部节点\n40 / 50"]
R --> N3["内部节点\n70 / 80"]
N1 --> L1["叶子页\n1,5,10,15,20"]
N2 --> L2["叶子页\n31,40,45,50,59"]
N3 --> L3["叶子页\n61,70,75,80,90"]
L1 --> L2
L2 --> L3B+Tree(多路平衡树)特点:
- 非叶子节点只存索引键和指针,单页能放更多键,树更矮。
- 叶子节点存完整数据或主键值。
- 叶子节点之间有链表,范围查询效率高。
热门面试题
问题(基础题):3.1 InnoDB(事务存储引擎)页与 B+Tree(多路平衡树) 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 3.1 InnoDB(事务存储引擎)页与 B+Tree(多路平衡树),再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):3.1 InnoDB(事务存储引擎)页与 B+Tree(多路平衡树) 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):WMS(仓储管理系统)库存表发生热点页写入时,如何利用索引设计限制写放大?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:WMS(仓储管理系统)库存表以
(warehouse_id(仓库标识), sku_id(库存单位标识))建唯一索引,让扣减精确命中一条聚簇索引记录;若监控发现某仓库的连续写入集中在少量页,先按仓库拆分写入队列并限流,而不是盲目增加索引,避免二级索引同时放大写入和页分裂。 - 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
3.2 聚簇索引、二级索引、回表
| 概念 | 含义 |
|---|---|
| 聚簇索引 | 叶子节点存整行数据,InnoDB(事务存储引擎)按主键组织表 |
| 二级索引 | 叶子节点存索引列和主键值 |
| 回表 | 通过二级索引找到主键后,再回聚簇索引查整行 |
| 覆盖索引 | 查询字段都在二级索引里,不需要回表 |
回表演绎:
表:order(id 主键, user_id, status, amount)
索引:idx_user_status(user_id, status)
SQL(结构化查询语言):select amount from order where user_id=10 and status='PAID';如果 idx_user_status(用户状态索引)只包含 user_id(用户标识)、status(状态)、id(主键),查询 amount(金额)就需要回表。如果索引改成 idx_user_status_amount(user_id, status, amount),就可能覆盖索引。
热门面试题
问题(基础题):3.2 聚簇索引、二级索引、回表 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 3.2 聚簇索引、二级索引、回表,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):3.2 聚簇索引、二级索引、回表 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):订单列表既要快又要展示详情字段时,如何控制回表成本和索引宽度?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:订单列表固定走
(user_id(用户标识), status(状态), create_time(创建时间))联合索引,只返回列表页需要的订单号、状态和创建时间;详情页再按主键批量查,防止为了偶发详情字段把宽列塞进索引。若回表量突然上升,先核对返回列和扫描行数,再决定是否增加覆盖列。 - 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
3.3 执行计划关注点
| 字段 | 关注点 |
|---|---|
| type(访问类型) | const(常量)、ref(非唯一索引)、range(范围)、index(下标),表示全索引扫描、ALL(全表扫描) |
| possible_keys(可能索引) | 优化器可选索引 |
| key(键) | 实际使用索引 |
| rows(扫描行数) | 估算扫描行数 |
| Extra(额外信息) | Using index(下标),在执行计划中表示覆盖索引;Using filesort(文件排序)、Using temporary(临时表) |
热门面试题
问题(基础题):3.3 执行计划关注点 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 3.3 执行计划关注点,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):3.3 执行计划关注点 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):跨境履约查询发布后扫描行数暴涨,你如何用执行计划止血并验证修复?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:跨境履约查询上线前保存基线执行计划和扫描行数;若发布后从索引访问退化为全表扫描,先回滚该查询或开关,再核对谓词是否对索引列做函数转换、统计信息是否过期以及返回集是否膨胀。不能只因
key(键)列非空就认定查询安全。 - 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
4. 底层原理
4.1 ACID(原子性、一致性、隔离性、持久性)
| 特性 | 含义 | InnoDB(事务存储引擎)依赖 |
|---|---|---|
| Atomicity(原子性) | 事务要么全成功,要么全失败 | undo log(回滚日志) |
| Consistency(一致性) | 事务前后约束一致 | 业务约束、事务、锁 |
| Isolation(隔离性) | 并发事务互不干扰 | 锁、MVCC(多版本并发控制) |
| Durability(持久性) | 提交后不丢 | redo log(重做日志) |
热门面试题
问题(基础题):4.1 ACID(原子性、一致性、隔离性、持久性) 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 4.1 ACID(原子性、一致性、隔离性、持久性),再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):4.1 ACID(原子性、一致性、隔离性、持久性) 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):支付入账同时涉及订单、资金流水和通知时,如何划定本地事务与异步补偿边界?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:支付入账只把订单状态、资金流水和发件箱事件放在同一个本地事务内;第三方渠道确认、消息投递和余额通知都在提交后异步执行。这样 ACID(原子性、一致性、隔离性、持久性)保证库内账实一致,外部调用失败由事件重试和对账补偿处理,不把远程接口塞进持锁事务。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
4.2 MVCC(多版本并发控制)
InnoDB(事务存储引擎)每行记录有隐藏字段:
| 隐藏字段 | 含义 |
|---|---|
| trx_id(事务标识) | 最近修改该行的事务 ID(事务标识) |
| roll_pointer(回滚指针) | 指向 undo log(回滚日志)旧版本 |
| row_id(行标识) | 没有主键时生成的隐藏行 ID(行标识) |
Read View(读视图)关键字段:
| 字段 | 含义 |
|---|---|
| m_ids(活跃事务集合) | 生成 Read View(读视图)时还没提交的事务 |
| min_trx_id(最小活跃事务标识) | 活跃事务里最小 ID(标识) |
| max_trx_id(下一个事务标识) | 创建 Read View(读视图)时系统将分配的下一个 ID(标识) |
| creator_trx_id(创建者事务标识) | 创建该 Read View(读视图)的事务 |
可见性判断:
- 如果版本 trx_id(事务标识)小于 min_trx_id(最小活跃事务标识),说明已提交,可见。
- 如果版本 trx_id(事务标识)大于等于 max_trx_id(下一个事务标识),说明是未来事务,不可见。
- 如果版本 trx_id(事务标识)在 m_ids(活跃事务集合)中,说明当时未提交,不可见。
- 如果版本 trx_id(事务标识)不在 m_ids(活跃事务集合)中,说明当时已提交,可见。
热门面试题
问题(基础题):4.2 MVCC(多版本并发控制) 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 4.2 MVCC(多版本并发控制),再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):4.2 MVCC(多版本并发控制) 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):库存展示与扣减并发发生时,哪些读可以用 MVCC(多版本并发控制),哪些必须走当前读?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:库存展示可以使用 MVCC(多版本并发控制)快照读,但扣减必须使用带条件的当前读更新,例如库存大于零才扣减。若长事务持续占住旧 Read View(读视图),会阻碍 undo log(回滚日志)清理;因此报表事务必须限时,不能复用到库存写入链路。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
4.3 三大日志
flowchart TD
A["事务更新一行数据"] --> B["写 undo log(回滚日志)旧版本"]
B --> C["修改 Buffer Pool(缓冲池)数据页"]
C --> D["写 redo log(重做日志)prepare(准备)"]
D --> E["写 binlog(二进制日志)"]
E --> F["写 redo log(重做日志)commit(提交)"]
F --> G["事务提交成功"]| 日志 | 作用 | 所属层级 | 典型用途 |
|---|---|---|---|
| undo log(回滚日志) | 回滚、MVCC(多版本并发控制)旧版本 | InnoDB(事务存储引擎) | 事务回滚、快照读 |
| redo log(重做日志) | 崩溃恢复,保证持久性 | InnoDB(事务存储引擎) | 宕机后恢复已提交事务 |
| binlog(二进制日志) | 复制、归档、恢复 | Server(服务层) | 主从复制、数据恢复 |
两阶段提交保证 redo log(重做日志)和 binlog(二进制日志)一致,否则可能出现主库恢复和从库复制结果不一致。
热门面试题
问题(基础题):4.3 三大日志 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 4.3 三大日志,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):4.3 三大日志 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):支付回调重复且主从存在延迟时,如何依赖三类日志保持提交与读取边界正确?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:支付成功回调落库后,以 redo log(重做日志)和 binlog(二进制日志)的两阶段提交保证本机恢复与复制口径一致;回调重复时先按渠道流水号唯一约束判重。监控同时观察提交耗时、日志刷盘等待和复制延迟,不能把提交成功误当成从库已经可读。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
5. 架构图与流程图
5.1 MVCC(多版本并发控制)版本链
flowchart LR
V3["当前版本\namount=300\ntrx_id=30"] --> U2["undo log(回滚日志)\namount=200\ntrx_id=20"]
U2 --> U1["undo log(回滚日志)\namount=100\ntrx_id=10"]
RV["Read View(读视图)\nm_ids=[30]\nmin=30\nmax=31"] -.判断可见.-> V3
RV -.不可见,沿 roll_pointer(回滚指针)找旧版本.-> U2热门面试题
问题(基础题):5.1 MVCC(多版本并发控制)版本链 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 5.1 MVCC(多版本并发控制)版本链,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):5.1 MVCC(多版本并发控制)版本链 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):对账长任务如何使用版本链,同时避免阻碍 undo log(回滚日志)回收?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:对账任务在 Read View(读视图)建立后只读取同一批次的历史快照,避免边翻页边看到新入账数据;若任务超过阈值仍未结束,主动终止并按主键范围续跑,避免旧版本链过长导致 undo log(回滚日志)无法回收。该读模型不承担实时资金余额判断。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
5.2 锁范围示意
假设表中索引值为 10、20、30、40。
flowchart LR
A["(-∞,10) 间隙"] --> B["10 记录"]
B --> C["(10,20) 间隙"]
C --> D["20 记录"]
D --> E["(20,30) 间隙"]
E --> F["30 记录"]
F --> G["(30,40) 间隙"]
G --> H["40 记录"]
H --> I["(40,+∞) 间隙"]临键锁是记录锁加间隙锁,例如 (10,20],既锁住 20 这条记录,也锁住 10 到 20 之间的间隙,防止幻读。
热门面试题
问题(基础题):5.2 锁范围示意 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 5.2 锁范围示意,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):5.2 锁范围示意 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):库存扣减如何避免范围当前读把无关商品一并锁住?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:库存扣减只按唯一的仓库与商品键等值更新,不使用“库存区间”做当前读;一旦发现等待集中在某个间隙,先暂停该范围内的批量补货写入,再检查扫描边界和隔离级别。业务层以扣减影响行数为准,不把锁等待后的重试直接当作成功。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
5.3 分库分表架构
flowchart TD
APP["应用服务"] --> S["ShardingSphere(分库分表中间件)"]
S --> DB0["order_db_0"]
S --> DB1["order_db_1"]
DB0 --> T00["order_00"]
DB0 --> T01["order_01"]
DB1 --> T10["order_10"]
DB1 --> T11["order_11"]
ID["Snowflake(雪花算法)全局 ID(全局唯一标识)"] --> APP热门面试题
问题(基础题):5.3 分库分表架构 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 5.3 分库分表架构,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):5.3 分库分表架构 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):订单按商家分片后,如何处理跨商家报表与路由层故障?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:订单按商家标识路由到固定分片,订单详情、状态流转和扣款幂等记录保持在同一分片;运营跨商家报表写入异步汇总库,不在请求链路执行跨库 join(连接查询)。路由层不可用时先拒绝写入并保留重试事件,不能随机切换分片造成同一订单双写。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
6. 表格对比
6.1 隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | MySQL(关系型数据库)表现 |
|---|---|---|---|---|
| Read Uncommitted(读未提交) | 可能 | 可能 | 可能 | 基本不用 |
| Read Committed(读已提交) | 避免 | 可能 | 可能 | 每次快照读生成新 Read View(读视图) |
| Repeatable(可重复注解) Read(可重复读) | 避免 | 避免 | 大多避免 | 首次快照读生成 Read View(读视图) |
| Serializable(串行化) | 避免 | 避免 | 避免 | 读写串行,性能低 |
热门面试题
问题(基础题):6.1 隔离级别 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 6.1 隔离级别,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):6.1 隔离级别 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):支付对账与库存预占分别选择什么隔离语义,为什么不能共用长事务?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:支付对账读取已提交流水时选择 Read Committed(读已提交),每次查询可见最新已提交修正;库存预占事务保持 Repeatable(可重复注解) Read(可重复读)以稳定读视图,但扣减语句仍用当前读。隔离级别由读写语义决定,不能为了“更高”隔离而把报表和扣减都放进长事务。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
6.2 锁类型
| 锁 | 作用 | 触发场景 |
|---|---|---|
| 行锁 | 锁住索引记录 | 等值命中唯一索引 |
| 间隙锁 | 锁住索引间隙 | 范围查询防插入 |
| 临键锁 | 行锁 + 间隙锁 | Repeatable(可重复注解) Read(可重复读)范围当前读 |
| 意向锁 | 表级标记,表示将加行锁 | InnoDB(事务存储引擎)自动加 |
| 元数据锁 | 保护表结构 | 查询与 DDL(数据定义语言)冲突 |
| 表锁 | 锁整张表 | 无索引更新、显式锁表或引擎限制 |
热门面试题
问题(基础题):6.2 锁类型 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 6.2 锁类型,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):6.2 锁类型 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):支付回调重复并发时,如何用唯一索引、条件更新和锁等待证据保证幂等?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:支付回调先根据渠道流水号走唯一索引定位,再用条件更新推进状态;同一订单的多条更新按订单主键升序加锁。发现锁等待时记录阻塞会话、事务年龄和 SQL(结构化查询语言)指纹,优先停止可重试的批任务,不通过无限重试把连接池耗尽。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
6.3 ShardingSphere(分库分表中间件)与 MyCat(数据库中间件)
| 维度 | ShardingSphere(分库分表中间件) | MyCat(数据库中间件) |
|---|---|---|
| 形态 | JDBC(Java 数据库连接)增强或 Proxy(代理) | Proxy(代理) |
| 接入成本 | JDBC(Java 数据库连接)模式对应用侵入较低 | 对应用透明但多一层网络 |
| 生态 | 活跃度较高 | 老牌中间件 |
| 适合 | Java(编程语言)应用内分片治理 | 多语言透明代理 |
热门面试题
问题(基础题):6.3 ShardingSphere(分库分表中间件)与 MyCat(数据库中间件) 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 6.3 ShardingSphere(分库分表中间件)与 MyCat(数据库中间件),再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):6.3 ShardingSphere(分库分表中间件)与 MyCat(数据库中间件) 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):分片中间件出现路由异常时,如何区分 ShardingSphere(分库分表中间件)与 MyCat(数据库中间件)的故障边界?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:选择 ShardingSphere(分库分表中间件)时,路由规则、分片键和数据源配置随应用版本发布;为路由异常准备只读降级和消息暂存。选择 MyCat(数据库中间件)时,还要把代理连接数、故障切换和协议兼容纳入容量评估,不能只比较接入代码量。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
7. 数据演绎
7.1 MVCC(多版本并发控制)数据演绎
初始数据:
| id | amount | trx_id(事务标识) |
|---|---|---|
| 1 | 100 | 10 |
事务执行:
| 时间 | 事务 A | 事务 B |
|---|---|---|
| T1 | begin(开始),事务 ID(标识)=20 | |
| T2 | select amount,生成 Read View(读视图),看到 100 | |
| T3 | begin(开始),事务 ID(标识)=30 | |
| T4 | update amount=200,提交 | |
| T5 | select amount |
在 Repeatable(可重复注解) Read(可重复读)下,事务 A 第一次快照读生成 Read View(读视图),后续复用同一个 Read View(读视图)。事务 B 的 trx_id(事务标识)=30 对事务 A 不可见,所以事务 A 在 T5 仍看到 100。
版本链:
| 版本 | amount | trx_id(事务标识) | 对事务 A 是否可见 |
|---|---|---|---|
| 当前版本 | 200 | 30 | 不可见 |
| undo log(回滚日志)旧版本 | 100 | 10 | 可见 |
如果是 Read Committed(读已提交),事务 A 每次 select(查询)都会生成新的 Read View(读视图),T5 就能看到事务 B 已提交的 200。
热门面试题
问题(基础题):7.1 MVCC(多版本并发控制)数据演绎 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 7.1 MVCC(多版本并发控制)数据演绎,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):7.1 MVCC(多版本并发控制)数据演绎 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):如何用三个事务标识解释库存“读到旧值但扣减成功”的并发现象?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:用三个事务标识演练库存可见性:T100 建立 Read View(读视图)时活跃集合含 T101,T102 后续提交的预占变更不能被 T100 看见;真正扣减由条件更新处理。这样可以解释“展示库存仍是旧值”与“扣减成功”并不矛盾,也明确快照读不能代替库存校验。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
7.2 锁范围演绎
表数据:
| id | age |
|---|---|
| 1 | 10 |
| 2 | 20 |
| 3 | 30 |
SQL(结构化查询语言):
select * from user where age between 10 and 20 for update;如果 age(年龄)有普通索引,在 Repeatable(可重复注解) Read(可重复读)下当前读会加临键锁,可能锁住:
(负无穷, 10](10, 20](20, 30)
这样其他事务不能插入 age(年龄)=15,也可能不能插入 age(年龄)=25,具体范围取决于索引扫描边界。面试里要强调:InnoDB(事务存储引擎)锁的是“索引记录和索引间隙”,不是抽象的业务条件。
热门面试题
问题(基础题):7.2 锁范围演绎 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 7.2 锁范围演绎,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):7.2 锁范围演绎 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):批量校验使用范围当前读时,如何防止缺索引导致锁范围扩大?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:这个范围锁只能用于后台批量校验,不能直接套到高并发库存接口;若缺少 age(年龄)索引,扫描会扩大到大量记录与间隙。上线前用生产脱敏数据核对锁范围,出现等待时按批次缩小范围或改为主键分段,而不是提高锁等待超时。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
7.3 死锁演绎
| 时间 | 事务 A | 事务 B |
|---|---|---|
| T1 | update account set balance=balance-100 where id=1; | |
| T2 | update account set balance=balance+100 where id=2; | |
| T3 | update account set balance=balance+100 where id=2; 等待 B | |
| T4 | update account set balance=balance-100 where id=1; 等待 A |
事务 A 持有 id=1 的锁,等待 id=2;事务 B 持有 id=2 的锁,等待 id=1,形成死锁。解决方式:
- 固定加锁顺序,例如永远按 id(标识)从小到大更新。
- 缩短事务时间,避免锁内远程调用。
- 使用唯一索引精准命中,减少锁范围。
- 捕获死锁异常后幂等重试。
热门面试题
问题(基础题):7.3 死锁演绎 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 7.3 死锁演绎,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):7.3 死锁演绎 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):资金划拨的双账户更新如何固定加锁顺序并安全重试?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:资金划拨按账户主键升序一次取锁;数据库选出的死锁受害事务只在业务幂等键仍有效时退避重试。复盘时保留最近死锁日志,比较每条 SQL(结构化查询语言)的索引、锁持有时长和调用链,避免把“重试三次”当成唯一治理手段。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
8. 线上排查与实战经验
8.1 慢 SQL(结构化查询语言)排查
- 开启 slow query log(慢查询日志),定位慢 SQL(结构化查询语言)。
- 使用 explain(执行计划)查看 type(访问类型)、key(键)(表示实际索引)、rows(扫描行数)、Extra(额外信息)。
- 判断是否索引失效:函数、隐式类型转换、前导模糊 like(模糊匹配)、or(或)条件、低选择度字段。
- 看是否回表过多,考虑覆盖索引。
- 看是否排序和临时表,优化 order by(排序)和 group by(分组)。
- 看数据量是否已经超过单表承载,考虑归档或分库分表。
热门面试题
问题(基础题):8.1 慢 SQL(结构化查询语言)排查 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 8.1 慢 SQL(结构化查询语言)排查,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):8.1 慢 SQL(结构化查询语言)排查 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):下单链路被一条慢 SQL(结构化查询语言)拖慢时,十分钟内如何止血并保留证据?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:慢 SQL(结构化查询语言)告警后先按接口、分片和发布时间聚合,保全执行计划、扫描行数与锁等待;若单条语句拖慢下单链路,先关闭非必要筛选或导出并限流,再用同量级脱敏数据验证索引改动。优化目标是减少总扫描和尾延迟,不是只让单次耗时好看。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
8.2 锁等待排查
常用方向:
- 查看
show engine innodb status中 LATEST DETECTED DEADLOCK(最近检测到的死锁)。 - 查看 information_schema(信息模式)中的事务和锁等待。
- 定位长事务,确认是否有未提交事务长期持锁。
- 检查 DDL(数据定义语言)是否被元数据锁阻塞。
- 检查 SQL(结构化查询语言)是否没有走索引导致锁范围扩大。
热门面试题
问题(基础题):8.2 锁等待排查 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 8.2 锁等待排查,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):8.2 锁等待排查 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):发现锁等待后,如何定位阻塞事务并避免错误终止资金写入?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:锁等待排查先找阻塞者而非批量杀连接:检查活跃事务开始时间、持锁 SQL(结构化查询语言)和等待对象;确认阻塞者是可重跑批任务后才终止它,并核验受害请求的幂等结果。若阻塞来自元数据锁,则暂停表结构变更并等待短事务释放。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
8.3 binlog(二进制日志)恢复思路
如果误删数据:
- 找最近一次全量备份。
- 恢复到临时实例。
- 用 binlog(二进制日志)按时间点回放到误操作前。
- 导出正确数据,回补生产。
- 复盘权限、审核、备份、演练。
热门面试题
问题(基础题):8.3 binlog(二进制日志)恢复思路 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 8.3 binlog(二进制日志)恢复思路,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):8.3 binlog(二进制日志)恢复思路 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):生产误删订单后,如何在不覆盖后续合法更新的前提下完成恢复?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:误删恢复先冻结相关写入并记录 binlog(二进制日志)位置,在隔离实例恢复最近备份后回放到误操作前,再按主键和业务时间窗比对差异;确认补回数据不覆盖后续合法更新后,分批写回生产。不能直接在主库反向执行猜测出来的 SQL(结构化查询语言)。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
9. 项目落地话术
9.1 慢 SQL(结构化查询语言)优化话术
“我优化慢 SQL(结构化查询语言)会先看执行计划,不会一上来盲目加索引。先确认 type(访问类型)是不是 ALL(全表扫描),key(键)(表示实际索引)是否命中,rows(扫描行数)是否过大,Extra(额外信息)里有没有 Using filesort(文件排序)和 Using temporary(临时表)。如果是回表多,就考虑覆盖索引;如果是范围大,就看业务能不能缩小条件;如果单表数据已经很大,就考虑归档或分库分表。”
热门面试题
问题(基础题):9.1 慢 SQL(结构化查询语言)优化话术 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 9.1 慢 SQL(结构化查询语言)优化话术,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):9.1 慢 SQL(结构化查询语言)优化话术 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):请用一次履约列表慢 SQL(结构化查询语言)优化说明你的发布、验证和回滚策略。
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:面试中用一条履约列表慢查询说明闭环:先发现扫描 40 万行只返回 20 行,再将筛选与排序对齐到联合索引,使扫描降到数十行;发布采用索引先建、灰度观察、保留回滚开关。若索引写入成本超过收益,就把低频报表迁到只读链路,而非继续堆索引。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
9.2 库存扣减一致性话术
“库存扣减不能只靠 Redis(远程字典服务)预扣减。我的做法是 Redis(远程字典服务)Lua(脚本语言)先抗并发和防超卖,MySQL(关系型数据库)用乐观锁和库存流水做最终一致性。扣减 SQL(结构化查询语言)会带条件,例如 available >= count,并检查影响行数。失败要回滚 Redis(远程字典服务)冻结或进入补偿队列。”
热门面试题
问题(基础题):9.2 库存扣减一致性话术 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 9.2 库存扣减一致性话术,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):9.2 库存扣减一致性话术 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):WMS(仓储管理系统)库存扣减超时或重复请求时,如何保证不超卖且结果可追溯?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:WMS(仓储管理系统)扣减采用“库存大于零才更新”的单行条件更新,并以订单号写唯一扣减流水;事务提交后由发件箱事件驱动库存变更通知。重复请求命中同一流水直接返回既有结果,超时请求通过对账确认,不依赖跨服务长事务锁住库存行。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
9.3 分库分表话术
“分库分表不是越早越好。单表还能通过索引、归档、冷热分离解决时,我会优先保持简单。当订单或流水长期增长、单表索引变深、归档仍不能满足查询和写入时,再按业务主维度选择分片键。比如订单常按 customer_id(客户标识)或 order_id(订单标识)查询,就要结合查询模式选择,避免跨库聚合成为常态。”
热门面试题
问题(基础题):9.3 分库分表话术 这一节在 MySQL(关系型数据库) 面试中主要解决什么问题?
- 考点:概念边界、核心作用、适用场景。
- 回答思路:先用一句话定义 9.3 分库分表话术,再说明它在系统稳定性、性能或一致性中的作用,最后结合 订单流水、库存扣减、支付对账、分库分表 说一个使用场景。
- 进阶追问:如果这个机制使用不当,线上最容易出现什么故障?如何监控和止血?
问题(原理题):9.3 分库分表话术 底层是怎么工作的?请按执行流程讲一遍。
- 考点:底层数据结构、状态流转、关键线程或组件、性能成本。
- 回答思路:按“触发条件 -> 核心流程 -> 关键数据结构 -> 成功/失败分支 -> 资源释放或回滚”来讲,避免只背结论。
- 进阶追问:如果并发量、数据量或故障率扩大 10 倍,这个流程里哪个环节会先成为瓶颈?
问题(项目追问题):订单表扩容到新分片时,双写、回填、校验和切读如何保证可回退?
- 考点:工程落地、异常场景、幂等、补偿、可观测性。
- 回答思路:订单量增长时先按商家和时间分析数据倾斜、查询入口与归档比例;确需扩容时实施旧表写入、新旧双写、按主键范围回填、行数与校验和比对、灰度切读,最后停止旧写入。跨分片查询优先异步汇总,扩容失败可按路由版本切回旧表,不能在同一请求里做全库广播。
- 进阶追问:如果服务重启、网络抖动或第三方接口超时,如何保证数据不丢、不重、不乱?
10. 高频面试题与追问
10.1 为什么 InnoDB(事务存储引擎)用 B+Tree(多路平衡树)?
B+Tree(多路平衡树)非叶子节点只存键和指针,单页能放更多键,树高更低;叶子节点有序链表,范围查询友好。相比 B-Tree(多路搜索树),B+Tree(多路平衡树)更适合磁盘页读取和范围扫描。
10.2 MVCC(多版本并发控制)解决什么问题?
MVCC(多版本并发控制)让读写可以并发。快照读不加锁,通过 Read View(读视图)和 undo log(回滚日志)版本链读取历史版本,减少读写阻塞。
10.3 redo log(重做日志)和 binlog(二进制日志)有什么区别?
redo log(重做日志)属于 InnoDB(事务存储引擎),用于崩溃恢复,是物理日志;binlog(二进制日志)属于 MySQL(关系型数据库)Server(服务层),用于主从复制和归档恢复,是逻辑日志。事务提交要通过两阶段提交保证它们一致。
10.4 MySQL(关系型数据库)锁会升级吗?
InnoDB(事务存储引擎)不像某些数据库那样把大量行锁自动升级成表锁。面试中更准确的说法是:如果 SQL(结构化查询语言)没走索引、范围过大、使用当前读,锁范围会扩大,表现上像锁了很多行甚至整表;另外 DDL(数据定义语言)会涉及元数据锁。
10.5 分库分表最大的问题是什么?
分库分表带来的主要问题是跨库事务、跨库 join(连接查询)、全局排序分页、全局唯一 ID(全局唯一标识)、热点分片、数据迁移和运维复杂度。因此分库分表前要先确认业务增长模型和查询模式。
模块综合热门面试题补强
10.6 InnoDB(事务存储引擎)为什么以页为 I/O(输入输出)单位?
- 问题:InnoDB(事务存储引擎)为什么以页为 I/O(输入输出)单位?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.7 B+Tree(多路平衡树)为什么适合范围查询?
- 问题:B+Tree(多路平衡树)为什么适合范围查询?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.8 聚簇索引和二级索引有什么区别?
- 问题:聚簇索引和二级索引有什么区别?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.9 覆盖索引为什么能减少回表?
- 问题:覆盖索引为什么能减少回表?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.10 MVCC(多版本并发控制)如何判断版本可见?
- 问题:MVCC(多版本并发控制)如何判断版本可见?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.11 Read Committed(读已提交)和 Repeatable(可重复注解) Read(可重复读)的 Read View(读视图)差异?
- 问题:Read Committed(读已提交)和 Repeatable(可重复注解) Read(可重复读)的 Read View(读视图)差异?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.12 undo log(回滚日志)、redo log(重做日志)、binlog(二进制日志)分别解决什么问题?
- 问题:undo log(回滚日志)、redo log(重做日志)、binlog(二进制日志)分别解决什么问题?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.13 两阶段提交为什么必要?
- 问题:两阶段提交为什么必要?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.14 Buffer Pool(缓冲池)如何管理热点页?
- 问题:Buffer Pool(缓冲池)如何管理热点页?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.15 脏页什么时候刷盘?
- 问题:脏页什么时候刷盘?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.16 Change Buffer(变更缓冲)适合什么索引?
- 问题:Change Buffer(变更缓冲)适合什么索引?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.17 Doublewrite Buffer(双写缓冲)解决什么问题?
- 问题:Doublewrite Buffer(双写缓冲)解决什么问题?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.18 间隙锁和临键锁如何防幻读?
- 问题:间隙锁和临键锁如何防幻读?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.19 MDL(元数据锁)为什么会阻塞 DDL(数据定义语言)?
- 问题:MDL(元数据锁)为什么会阻塞 DDL(数据定义语言)?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.20 死锁如何定位和规避?
- 问题:死锁如何定位和规避?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.21 慢 SQL(结构化查询语言)如何系统优化?
- 问题:慢 SQL(结构化查询语言)如何系统优化?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.22 主从复制延迟怎么处理?
- 问题:主从复制延迟怎么处理?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.23 binlog(二进制日志)如何做误删恢复?
- 问题:binlog(二进制日志)如何做误删恢复?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.24 分片键怎么选?
- 问题:分片键怎么选?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
10.25 跨库分页和扩容迁移怎么设计?
- 问题:跨库分页和扩容迁移怎么设计?
- 考点:核心概念、底层机制、失败边界、项目落地。
- 回答思路:先给结论,再讲工作流程和关键取舍,最后结合 订单流水、库存扣减、支付对账、分库分表 说明线上怎么兜底。
- 进阶追问:如果出现并发冲突、数据不一致、性能下降或服务重启,你如何定位、恢复和复盘?
11. 本模块复习清单
- 能画出 B+Tree(多路平衡树)索引结构。
- 能解释聚簇索引、二级索引、回表、覆盖索引。
- 能用数据演绎 MVCC(多版本并发控制)版本链和 Read View(读视图)可见性。
- 能讲清 undo log(回滚日志)、redo log(重做日志)、binlog(二进制日志)职责。
- 能解释两阶段提交。
- 能用索引范围解释行锁、间隙锁、临键锁。
- 能排查慢 SQL(结构化查询语言)、锁等待、死锁。
- 能讲清 ShardingSphere(分库分表中间件)、MyCat(数据库中间件)和分片键选择。
- 能把 MySQL(关系型数据库)乐观锁、Redis(远程字典服务)原子脚本和业务幂等组合成库存/支付一致性方案。
