MySQL(关系型数据库)线上排障、项目话术与综合题库
本分册把 MySQL(关系型数据库)的指标、原理、排障动作与项目表达串成一条线。你应当能在面试中先界定影响面,再用证据缩小范围,最后给出止血、修复与预防闭环。
使用说明
- 本册承接 00-知识图谱与复习路线、01-InnoDB(事务存储引擎)页、行与 Buffer Pool(缓冲池)、02-B+Tree(多路平衡树)索引与优化器、03-事务隔离与 MVCC(多版本并发控制)、04-InnoDB(事务存储引擎)锁与死锁、05-undo(撤销日志)、redo(重做日志)、binlog(二进制日志)与崩溃恢复、06-复制高可用与备份恢复、07-分库分表与迁移。
kb:knowledge后是可被知识库检索的结论;每道题按“场景、现象、定位、根因、处置、复盘”六字段组织。- “数据演绎”中的数值用于训练推理路径,不是所有集群的固定阈值;上线时以业务服务等级目标和基线为准。
一、线上排障总框架
flowchart LR
A[告警或用户反馈] --> B[界定影响面]
B --> C[保留现场证据]
C --> D{资源、等待或复制异常}
D -->|资源| E[慢 SQL(结构化查询语言)/缓存/刷盘]
D -->|等待| F[锁/事务/连接]
D -->|复制| G[主从/切主/一致性]
E --> H[止血]
F --> H
G --> H
H --> I[验证、复盘、预防]| 阶段 | 首要问题 | 最小证据集 | 常见误区 |
|---|---|---|---|
| 界定 | 哪些租户、库表、接口受影响? | 时间窗、错误率、分位耗时、实例列表 | 只看平均耗时 |
| 取证 | 发生时数据库在等待什么? | 慢日志、执行计划、事务、锁、复制状态 | 先重启丢失现场 |
| 止血 | 如何在不扩大损失下恢复? | 限流、降级、只读保护、回滚窗口 | 直接杀掉所有会话 |
| 修复 | 根因是数据、语句、容量还是流程? | 对比基线、变更记录、数据抽样 | 用参数掩盖设计问题 |
| 预防 | 同类故障如何提前发现? | 指标、演练、准入、自动校验 | 复盘只写“加强监控” |
面试开场话术
kb:knowledge:线上 MySQL(关系型数据库)排障不从“猜参数”开始,而从影响范围、时间线和可回滚性开始。先保护资金、库存、履约等不可逆业务,再用等待事件和变化点寻找瓶颈,避免用重启掩盖问题。
我会先说清楚影响的是读、写、单库、分片还是异步链路,并冻结高风险发布;随后在不破坏现场的前提下采集慢 SQL(结构化查询语言)、执行计划、活跃事务、锁等待、复制延迟、磁盘与缓冲池指标。止血优先级是保护正确性,其次恢复可用性,最后才是性能。根因确认后,我会将修复拆成短期动作、数据修复和长期准入,并通过回放或压测验证。
热门面试题
Q01:订单创建接口突然变慢,你如何在十分钟内建立排障方向?
- 场景:跨境物流下单接口的 P99(99 分位响应时间)从 180 毫秒升至 8 秒,部分订单重试。
- 现象:应用线程池排队增长,数据库连接使用率上升,错误率尚未明显升高。
- 定位:按接口、租户、库分片和读写路径拆分指标;对齐发布、批处理和流量峰值时间线;保留慢日志与活跃会话快照。
- 根因:待确认,优先区分慢 SQL(结构化查询语言)、锁等待、磁盘刷盘与连接泄漏四类。
- 处置:先关闭非关键查询和导出任务,对重试做退避与幂等保护;禁止直接重启主库。
- 复盘:沉淀十分钟证据清单,告警按 P99(99 分位响应时间)、等待与错误率联动。
Q02:为什么不能一看到数据库 CPU(中央处理器)高就扩容?
- 场景:仓储管理系统 WMS(仓储管理系统)盘点期间,主库 CPU(中央处理器)长期超过 90%。
- 现象:扩容提议与“先杀慢查询”的提议同时出现。
- 定位:比较 CPU(中央处理器)高的 SQL(结构化查询语言)指纹、逻辑读、上下文切换、锁等待和磁盘队列。
- 根因:CPU(中央处理器)只是结果,可能是索引失效、错误连接方式、排序聚合、重试风暴或复制回放。
- 处置:按单位业务请求的资源消耗排序,先限流或摘除异常调用,再修正最重语句。
- 复盘:容量规划同时纳入业务增长、语句基线和故障冗余,避免只按 CPU(中央处理器)比例扩容。
Q03:排障时为什么强调“先保留现场”?
- 场景:支付对账任务引起资金状态查询超时,值班同学准备重启实例。
- 现象:重启可能暂时恢复,但会消失事务、锁与复制延迟的直接证据。
- 定位:先采集会话、事务、锁、慢日志、错误日志和系统指标的同一时间窗快照。
- 根因:现场证据决定能否区分阻塞者、受害者、系统抖动与应用重试放大。
- 处置:若必须故障转移,先执行只读保护、快照采集和切换记录;以业务幂等防止重复扣款。
- 复盘:将证据采集脚本和权限预置到值班手册,并定期演练。
二、慢 SQL(结构化查询语言)专题
flowchart TD
A[慢 SQL(结构化查询语言)] --> B{执行计划是否合理}
B -->|否| C[统计信息、索引、谓词、连接顺序]
B -->|是| D{扫描或返回数据是否过多}
D -->|是| E[缩小范围、分页、覆盖索引]
D -->|否| F[锁等待、网络、磁盘与并发]| 检查项 | 可观察信号 | 结论方向 | 常用动作 |
|---|---|---|---|
| 扫描行数 | rows_examined 远大于返回行数 | 过滤未下推或索引选择差 | 改索引、改谓词 |
| 回表 | 二级索引后大量主键查找 | 覆盖不足 | 补覆盖列或改查询 |
| 排序 | filesort、临时表 | 排序未利用索引 | 对齐索引顺序 |
| 分页 | 深页偏移耗时线性增长 | 扫描丢弃过多 | 游标翻页 |
2.1 索引、谓词与返回集
kb:knowledge:慢 SQL(结构化查询语言)的核心不是“执行时间长”而是“每次请求完成了不必要的工作”。必须同时比较扫描行数、逻辑读、返回行数、锁等待和调用频率,才能判断索引、语义还是并发造成成本。
数据演绎 1:全表扫描的放大
订单表有 8,000 万行;接口每秒 120 次,每次只返回 20 行,却扫描 40 万行。每秒扫描量约为 4,800 万行。即使单次查询只多消耗 8 毫秒,在并发下也会挤压缓冲池命中和 CPU(中央处理器)时间片,最终使其他正常请求排队。
热门面试题
Q04:如何证明一条慢 SQL(结构化查询语言)值得优先优化?
- 场景:履约看板查询单次 1.2 秒,但每天只运行十次;另一条库存查询单次 80 毫秒,每秒 500 次。
- 现象:团队只按慢日志的单次耗时排序。
- 定位:计算调用量乘以单次资源成本,比较总扫描行数、总逻辑读、锁占用时间和业务影响。
- 根因:高频中等慢语句常比低频超慢报表更消耗共享资源,并放大峰值排队。
- 处置:先优化单位时间资源占用最大的查询;报表转只读副本或离线链路。
- 复盘:慢 SQL(结构化查询语言)治理榜单增加频次、总耗时和受影响接口字段。
Q05:深分页为什么在大表上危险,如何改?
- 场景:运营在订单表翻到第 50 万页,每页 20 条。
- 现象:
LIMIT(限制) 10000000, 20的耗时随页码持续上升。 - 定位:执行计划显示数据库必须定位并丢弃前 1,000 万行,再返回 20 行。
- 根因:偏移分页的工作量与偏移量近似线性相关,索引不能免除已跳过记录的遍历。
- 处置:以稳定且有索引的
(create_time(创建时间), id(标识))作为游标条件,限制最大翻页范围。 - 复盘:接口契约明确排序字段、游标编码和数据变动时的可见性语义。
Q06:如何避免“建了索引仍然慢”的误判?
- 场景:给
status(状态)建索引后,扫描依旧很多。 - 现象:低基数字段命中 70% 数据,优化器仍倾向全表扫描。
- 定位:对比选择性、联合索引最左匹配、回表代价、统计信息和实际返回行数。
- 根因:索引不是免费过滤器;低选择性条件可能比顺序扫描和批量读取更贵。
- 处置:把高选择性、等值过滤和排序条件按访问模式设计联合索引;删除无效索引前先验收写入收益。
- 复盘:索引评审必须附真实参数的执行计划和写放大评估。
三、优化器误判专题
flowchart LR
A[参数与数据分布变化] --> B[统计信息失真]
B --> C[优化器估算偏差]
C --> D[错误索引或连接顺序]
D --> E[扫描与临时表放大]
E --> F[接口超时]| 误判来源 | 典型表现 | 验证方式 | 修复原则 |
|---|---|---|---|
| 统计信息陈旧 | 预估行数与实际行数相差数量级 | EXPLAIN(执行计划) ANALYZE(分析) | 刷新并观察回归 |
| 数据倾斜 | 少数租户或状态占多数 | 按值统计分布 | 面向热点设计 |
| 参数差异 | 测试参数快、线上参数慢 | 抓取真实绑定值 | 覆盖典型参数 |
| 连接估算 | 小表被错误驱动 | 比较连接顺序 | 调整索引或拆分 |
3.1 统计信息与倾斜数据
kb:knowledge:优化器(查询优化器)依据统计信息估算成本,而不是读取未来。预估错误时,先验证数据分布、统计信息和真实参数,再决定是否改索引、改语句或以受控方式固定计划;不要把提示语当成永久补丁。
热门面试题
Q07:执行计划预估 100 行、实际 100 万行,你如何处理?
- 场景:大促后订单状态从均匀分布变为“待发货”集中。
- 现象:原本稳定的查询突然选择了不合适的二级索引。
- 定位:使用真实参数获取预估与实际行数,检查表统计更新时间与状态列分布。
- 根因:统计信息未反映数据倾斜,成本模型低估回表与连接代价。
- 处置:刷新统计信息,验证候选索引;必要时把高选择性条件前置并拆分宽范围查询。
- 复盘:大促、归档和批量状态迁移后纳入统计信息检查与回归压测。
Q08:什么时候可以使用优化器提示?
- 场景:紧急止血时,某版本优化器选择错误连接顺序。
- 现象:改表结构需要审批,业务接口已超时。
- 定位:确认提示在多组真实参数下均优于原计划,并量化对写入和其他查询的影响。
- 根因:短期可用性需要受控绕开错误计划,但数据分布继续变化会使提示过期。
- 处置:将提示作为有失效日期的临时措施,同时创建索引、统计或语句改造的根治项。
- 复盘:提示登记监控、适用版本和移除条件,禁止在未知参数下全局复制。
Q09:多表关联为什么会因小表变大而雪崩?
- 场景:商品标签表从 5 万行增长到 2,000 万行,库存查询仍按旧连接顺序执行。
- 现象:嵌套循环重复访问大表,逻辑读激增。
- 定位:比较每个连接节点的实际行数、循环次数与索引覆盖情况。
- 根因:旧统计和旧假设把标签表视为小表,驱动表选择导致放大访问。
- 处置:建立关联键索引,先过滤高选择性订单集合,再关联标签;必要时预聚合。
- 复盘:表规模跨量级时触发关联查询基线复查。
四、锁等待与死锁专题
sequenceDiagram
participant T1 as 事务一
participant T2 as 事务二
participant R1 as 记录一
participant R2 as 记录二
T1->>R1: 先锁记录一
T2->>R2: 先锁记录二
T1->>R2: 等待
T2->>R1: 等待
Note over T1,T2: 死锁检测回滚代价较小的事务| 问题 | 先看什么 | 不能直接得出的结论 | 优先动作 |
|---|---|---|---|
| 锁等待 | 阻塞者事务、锁类型、持锁时长 | 等待者的 SQL(结构化查询语言)一定有问题 | 找阻塞源 |
| 死锁 | 最近死锁日志、访问顺序、索引范围 | 单纯加大超时可解决 | 统一访问顺序 |
| 间隙锁 | 隔离级别、范围条件、索引 | 所有 UPDATE(更新) 都只锁单行 | 缩小范围 |
4.1 排队、阻塞与死锁重试
kb:knowledge:锁等待先找“谁持有、为何持有、何时释放”,死锁则找“循环依赖如何形成”。对库存、支付等关键写操作,重试必须建立在幂等键和有限退避之上,不能把数据库死锁转化为应用重试风暴。
热门面试题
Q10:你如何区分锁等待和死锁?
- 场景:库存扣减请求偶发超时,日志同时出现等待与回滚错误。
- 现象:部分请求持续等待,部分请求立即收到死锁错误。
- 定位:锁等待查看阻塞链与等待时长;死锁查看死锁日志中两个事务的资源交叉顺序。
- 根因:前者是资源被占用但可能释放,后者是环形等待且必须回滚一方。
- 处置:对长等待消除阻塞事务;对死锁统一锁顺序、缩小事务并安全重试受害者。
- 复盘:按业务键和 SQL(结构化查询语言)指纹聚合死锁,避免只统计错误码。
Q11:库存扣减如何避免“先查后扣”导致的超卖?
- 场景:两个请求同时读取库存为 1,均准备扣减。
- 现象:应用层判断都通过,最终库存可能为负或出现重复履约。
- 定位:确认扣减是否在单条条件更新和同一事务中完成,检查影响行数与订单幂等键。
- 根因:读和写分离使判断不具备原子性,锁保护范围不足。
- 处置:使用带库存条件的原子更新,以影响行数判断成功;订单号建立唯一约束并处理重复请求。
- 复盘:压测并发边界和重复消息场景,监控库存负数与扣减失败率。
Q12:死锁重试应如何设计才不会重复扣款?
- 场景:支付回调与人工补单并发更新同一支付单。
- 现象:数据库回滚一个事务,应用准备自动重试。
- 定位:核对支付流水唯一键、状态机单向迁移和外部扣款动作是否已发生。
- 根因:数据库事务能回滚本地更新,却不能自动撤销外部支付侧效果。
- 处置:先以业务幂等键读取已有结果,再在有限次数退避后重试本地状态变更;外部调用采用事务外可靠消息。
- 复盘:死锁重试指标区分“安全重试”“幂等命中”和“人工介入”。
五、长事务、undo(撤销日志)与历史版本专题
5.1 长事务识别与治理
kb:knowledge:长事务的危害不只在于持锁。它还会阻止 undo(撤销日志)历史版本清理,扩大版本链、拖慢一致性读,并可能让备份、复制或切换窗口不可控。治理要限制事务内交互、批量规模和空闲持锁时间。
热门面试题
Q13:为什么一个不写数据的长查询也可能造成事故?
- 场景:财务导出开启一致性读后运行两小时。
- 现象:写入持续进行,历史列表长度增长,磁盘空间逼近阈值。
- 定位:查看活跃事务开始时间、读视图存活期、undo(撤销日志)增长和清理进度。
- 根因:旧读视图要求数据库保留可见的历史版本,清理无法推进。
- 处置:终止可重跑的长导出,切换到分段导出或离线副本;保护磁盘余量。
- 复盘:导出任务设置最大事务时长、分页游标和只读副本隔离。
Q14:批量更新为什么要拆批且每批尽快提交?
- 场景:归档任务一次更新 500 万行订单状态。
- 现象:事务日志和锁持续增长,在线查询受影响。
- 定位:观察单批耗时、锁覆盖范围、undo(撤销日志)、redo(重做日志)与复制延迟。
- 根因:超大事务放大回滚成本、持锁时间和日志峰值,也使故障恢复更慢。
- 处置:按主键范围拆成可恢复小批次,在低峰执行并记录水位;每批校验影响行数。
- 复盘:批任务框架强制批量上限、暂停开关和失败续跑语义。
Q15:如何回答“长事务和长 SQL(结构化查询语言)有什么不同”?
- 场景:面试官追问两者的监控与治理差异。
- 现象:两者都可能表现为慢,但影响机制不同。
- 定位:长 SQL(结构化查询语言)关注执行计划和资源消耗;长事务额外关注开始时间、持锁、读视图和提交边界。
- 根因:一条短语句也可能处在长事务中,而一条长查询可能是自动提交的单语句事务。
- 处置:分别设置语句超时、事务超时和空闲事务告警;按业务可回滚性设计阈值。
- 复盘:值班面板同时展示最慢语句与最老活跃事务,避免指标盲区。
六、Buffer Pool(缓冲池)与脏页专题
6.1 内存命中与刷脏节奏
kb:knowledge:Buffer Pool(缓冲池)是数据库用来缓存数据页和索引页的主要内存区域。命中率高不等于健康;当脏页积压、刷脏受限或工作集突变时,前台写入仍可能因检查点推进和磁盘队列而抖动。
| 指标 | 异常含义 | 排障联动 |
|---|---|---|
| 缓冲池命中率 | 工作集可能超过内存或出现扫描污染 | 对比逻辑读与物理读 |
| 脏页比例 | 刷脏落后或写入突增 | 对比检查点与磁盘延迟 |
| 读取等待 | 存储瓶颈或缓存未命中 | 对比队列深度 |
| 页淘汰 | 热页被挤出 | 排查大范围扫描 |
热门面试题
Q16:缓冲池命中率 99% 为什么接口仍然慢?
- 场景:仓库出库高峰,命中率稳定但写接口出现周期性尖刺。
- 现象:每隔数分钟 P99(99 分位响应时间)陡升,磁盘写延迟同步升高。
- 定位:关联脏页比例、检查点年龄、redo(重做日志)压力与设备写队列。
- 根因:读取命中正常不代表写路径畅通;刷脏突发会占用磁盘并阻塞前台提交。
- 处置:先降低非关键批写与大事务,核对存储能力和刷脏策略;不盲目扩大缓冲池。
- 复盘:建立写延迟、脏页、检查点和业务 P99(99 分位响应时间)的关联告警。
Q17:一次全表扫描如何污染缓存?
- 场景:运营临时跑未限制范围的订单查询。
- 现象:随后热门商品库存查询的物理读增加。
- 定位:观察扫描期间读入页数、淘汰页数和热点查询命中变化。
- 根因:大量一次性冷数据进入 Buffer Pool(缓冲池),挤出频繁访问的热页。
- 处置:中止或迁移报表,限制查询范围,使用只读副本或离线分析链路。
- 复盘:为运营查询提供受控报表与行数上限,禁止生产库自由扫描。
Q18:脏页比例很高时能否直接重启?
- 场景:写入高峰后脏页比例升高,值班同学担心实例卡顿。
- 现象:重启会触发恢复过程并丢失当前观察窗口。
- 定位:先判断脏页是否持续上涨、检查点能否推进、磁盘是否饱和以及业务是否受损。
- 根因:高脏页可能是正常高写入,也可能是刷盘能力不足;重启不是诊断工具。
- 处置:限制背景批写、保障磁盘余量,必要时按预案切流或切换;记录恢复时间目标。
- 复盘:通过压测建立安全脏页与写入基线,演练异常恢复。
七、redo(重做日志)与 binlog(二进制日志)专题
7.1 提交路径与恢复边界
kb:knowledge:redo(重做日志)保证崩溃恢复中的已提交变更可重放,binlog(二进制日志)记录逻辑变更并承担复制与时间点恢复。两者通过两阶段提交关联,排障要同时判断持久性、复制消费与恢复点,而不是只看其中一个日志文件。
sequenceDiagram
participant A as 应用
participant I as InnoDB(存储引擎)
participant B as binlog(二进制日志)
A->>I: 写数据与 redo(重做日志)准备
I->>B: 写 binlog(二进制日志)
B-->>I: 日志持久化确认
I-->>A: 提交完成热门面试题
Q19:redo(重做日志)和 binlog(二进制日志)分别解决什么问题?
- 场景:面试官要求解释双日志而非背定义。
- 现象:有人只说“一个物理一个逻辑”,无法说明业务价值。
- 定位:从崩溃恢复、主从复制、时间点恢复和已提交一致性四个维度拆解。
- 根因:redo(重做日志)面向存储引擎的持久化恢复,binlog(二进制日志)面向服务器层的数据变更传播。
- 处置:说明两阶段提交避免“库内已提交但复制日志缺失”或反向不一致的窗口。
- 复盘:生产监控同时覆盖日志写入延迟、空间、归档和复制消费。
Q20:提交变慢时如何判断是日志刷盘而不是 SQL(结构化查询语言)执行慢?
- 场景:支付写入的执行阶段很短,但提交阶段耗时明显增长。
- 现象:大量请求卡在提交,磁盘写延迟抬升。
- 定位:分解语句执行、锁等待和提交耗时;对比 redo(重做日志)与 binlog(二进制日志)刷盘指标。
- 根因:持久化屏障受设备延迟、日志同步策略或突发写入影响。
- 处置:先降低可延后写入和大事务,检查存储服务等级;任何持久化参数调整须评估故障丢失窗口。
- 复盘:为关键支付链路定义提交延迟预算与灾难恢复目标。
Q21:如何用日志支持一次误删恢复?
- 场景:运营误执行范围过大的删除,发现时间在备份完成后一小时。
- 现象:不能仅恢复全量备份,否则会覆盖后一小时正常订单。
- 定位:确定误操作开始与结束位置、最近完整备份、binlog(二进制日志)连续性和目标恢复时间点。
- 根因:恢复目标是回到误操作前的逻辑时间点,同时保留其他正常写入。
- 处置:在隔离环境完成备份恢复与日志回放演练,校验后再按变更窗口执行正式恢复。
- 复盘:限制高危权限,建立误操作审计、延迟副本与定期恢复演练。
八、复制、切主与高可用专题
8.1 延迟、故障转移与读写语义
kb:knowledge:复制延迟不是单一数字,而是“主库已提交、日志已传输、从库已接收、从库已回放、业务读已可见”之间的差。切主前必须确认候选副本的日志完整性、延迟、只读状态与应用路由,切换后要防止旧主回写形成脑裂。
flowchart LR
M[主库提交] --> L[日志传输]
L --> R[副本接收]
R --> A[副本回放]
A --> Q[读请求可见]
M --> W[写请求]热门面试题
Q22:主从延迟出现时,你如何判断是否可以切主?
- 场景:跨境物流主库故障,候选副本显示有 20 秒延迟。
- 现象:业务希望立刻提升副本写入。
- 定位:确认延迟对应的日志位置、候选副本完整性、最近提交的订单与支付影响,以及是否存在其他更近副本。
- 根因:带延迟切换会丢失尚未回放的已确认写入,影响库存、资金和履约状态。
- 处置:优先选择最接近且健康副本;若只能带损切换,冻结高风险写入并建立补偿清单。
- 复盘:定义不同业务的恢复点目标,关键链路配置半同步或同城多副本策略。
Q23:为什么读写分离会读到旧数据?
- 场景:用户支付成功后立即查询订单,页面偶发显示“待支付”。
- 现象:写入主库成功,读请求被路由到延迟副本。
- 定位:追踪同一请求链路的写入位置、读库路由和副本回放位置。
- 根因:异步复制天然存在可见性时间差,读写分离默认不保证读己之写。
- 处置:支付后短窗口强制主库读,或携带日志位置实现副本追平后读取;明确接口一致性级别。
- 复盘:按页面与接口标注强一致、读己之写和最终一致语义。
Q24:切主后最重要的三个保护动作是什么?
- 场景:自动故障转移已完成,团队准备恢复流量。
- 现象:旧主可能仍可被网络分区中的应用访问。
- 定位:检查旧主写入隔离、新主只读解除、路由健康检查与日志位点。
- 根因:若旧主继续接收写入,会产生脑裂和难以自动合并的数据分叉。
- 处置:围栏旧主、确认新主唯一写入口、逐步恢复流量并核对关键账务与库存抽样。
- 复盘:演练网络分区、域名缓存和连接池重连,记录每一步责任人与证据。
九、数据不一致专题
9.1 发现、定界与修复
kb:knowledge:数据不一致治理先定义“以谁为准”和“允许多久不一致”。库存、资金、履约状态常跨数据库、消息队列和外部系统,修复必须基于可追溯事件与幂等补偿,不能用一次全量覆盖掩盖差异来源。
| 一致性对象 | 权威来源 | 核对键 | 修复方式 | | --- | --- | --- | | 可售库存 | 库存流水 | 商品、仓库、批次 | 重放流水或冻结校正 | | 支付状态 | 支付渠道回执 | 支付流水号 | 幂等状态推进 | | 履约状态 | 物流事件 | 运单号、事件序号 | 顺序补偿与人工兜底 |
热门面试题
Q25:发现库存表与库存流水不一致,你怎么处理?
- 场景:日终核对发现某仓商品可售库存比流水汇总多 12 件。
- 现象:无法立即判定是重复流水、漏扣还是人工盘点调整。
- 定位:按商品、仓库、批次和时间窗重放流水,关联订单、退货、盘点与异常补偿事件。
- 根因:可能是消息重复、消费失败、跨服务补偿缺失或人工调整未留审计。
- 处置:先冻结该货品的自动出库或设置安全库存;以不可变流水推导目标值,再执行带审计的校正。
- 复盘:库存变动全部事件化并使用唯一事件键,日间增量对账提前暴露差异。
Q26:资金状态不一致时为什么不能直接改订单表?
- 场景:订单显示未支付,但支付渠道已扣款成功。
- 现象:客服希望手工把订单状态改成已支付。
- 定位:以支付渠道回执、支付流水和回调记录作为事实来源,检查回调是否丢失或状态机拒绝。
- 根因:直接改订单表会跳过账务流水、通知、履约触发和审计链。
- 处置:通过幂等补单命令重放完整状态迁移;若外部状态不明,进入挂起并人工核验。
- 复盘:回调落库、可靠投递与对账任务构成闭环,禁止无审计的直接更新。
Q27:如何设计数据修复的“可撤销性”?
- 场景:需要批量纠正 3 万条历史履约状态。
- 现象:修复脚本如果条件写错,可能扩大损失。
- 定位:明确目标集合、修复前快照、预期影响行数、分批水位和回滚策略。
- 根因:数据修复是生产写操作,风险来自范围漂移、并发更新和重复执行。
- 处置:先在影子环境验证,生产按小批次和版本条件更新,逐批校验并记录反向脚本。
- 复盘:修复流程要求双人复核、审批、审计和结果对账。
十、备份恢复专题
10.1 恢复目标与演练
kb:knowledge:备份是否可靠不由“备份任务成功”证明,而由“在目标时间内恢复并通过业务校验”证明。恢复设计必须同时说明恢复点目标、恢复时间目标、备份链完整性、日志保留、密钥与权限,以及恢复后流量切换。
flowchart TD
A[故障或误操作] --> B[确定恢复目标]
B --> C[选择备份基线]
C --> D[隔离环境恢复]
D --> E[binlog(二进制日志)回放]
E --> F[一致性校验]
F --> G[正式切换]热门面试题
Q28:如何证明备份方案不是“纸面可用”?
- 场景:团队每天全量备份,但从未做过恢复。
- 现象:备份文件存在不等于可读取、可解密、可回放且满足时限。
- 定位:定期在隔离环境随机抽取备份,执行恢复、日志回放、表校验和关键业务查询。
- 根因:权限、密钥、版本、存储损坏和日志缺口都可能让备份在事故时失效。
- 处置:把恢复演练纳入服务等级目标,记录实际恢复时间与数据缺口。
- 复盘:对演练失败建立和生产故障同级的整改闭环。
Q29:恢复时为什么先在隔离环境验证?
- 场景:误删发生后,团队急于把备份直接恢复到生产。
- 现象:目标时间点、日志范围和恢复脚本都可能存在偏差。
- 定位:隔离环境验证表数量、校验和、关键订单状态与正常写入保留情况。
- 根因:直接生产恢复一旦选错点位,会二次覆盖正确数据且难以回退。
- 处置:先完成演练和业务签字,再冻结窗口执行生产切换。
- 复盘:预建隔离恢复环境和自动校验脚本,缩短真实事故的决策时间。
Q30:恢复点目标与恢复时间目标如何影响架构?
- 场景:支付账务要求分钟级数据损失上限,报表库可接受小时级。
- 现象:两类系统不能使用完全相同的备份频率和副本策略。
- 定位:量化允许丢失的数据时间和允许不可用的时间,映射到日志保留、复制模式和恢复自动化。
- 根因:目标不同决定成本投入;只谈“高可用”无法指导具体技术选择。
- 处置:账务采用更短备份链、连续日志与更强复制保障;报表使用低成本恢复方案。
- 复盘:业务负责人确认目标,并在演练中验证目标是否真实可达。
十一、分片热点专题
11.1 识别热点与均衡策略
kb:knowledge:分库分表不能自动消除热点。若路由键与流量键高度相关,例如热门仓库、爆款商品或单一大租户,单分片仍会成为瓶颈。治理需要从路由、写入合并、缓存、队列削峰和业务限额共同处理。
flowchart LR
U[热点商品请求] --> R[分片路由]
R --> S1[普通分片]
R --> H[热点分片]
H --> C[缓存与合并]
H --> Q[队列削峰]
Q --> D[数据库写入]热门面试题
Q31:分库分表后为什么仍可能单库打满?
- 场景:爆款商品的库存扣减都落到同一个商品路由分片。
- 现象:其余分片空闲,热点分片锁等待与 CPU(中央处理器)饱和。
- 定位:按分片统计请求、行锁、连接、磁盘与商品维度流量。
- 根因:哈希路由只均衡键空间,不保证真实业务访问频率均匀。
- 处置:对热点商品做库存分桶、请求合并或队列串行化,并设置购买限额与缓存预扣。
- 复盘:容量模型使用历史流量分布和峰值热点,而非只用分片数量平均值。
Q32:如何判断是热点键还是分片算法问题?
- 场景:某一分片持续高负载,团队考虑整体扩容。
- 现象:高负载可能由单客户、单仓库或路由不均引起。
- 定位:将分片负载下钻到路由键前缀、业务实体、时间段与语句类型。
- 根因:若少数键贡献绝大多数请求是热点;若键分布本身倾斜则是算法或数据布局问题。
- 处置:热点采取定向拆解;算法问题规划在线迁移,避免以盲目扩容掩盖。
- 复盘:新增分片前先做键分布模拟和未来增长预测。
Q33:库存分桶会带来哪些一致性挑战?
- 场景:把一个商品库存拆到多个桶以降低单行锁竞争。
- 现象:扣减吞吐提高,但查询总库存与补偿复杂度上升。
- 定位:定义桶选择、总量聚合、失败回滚、超卖边界与订单幂等关系。
- 根因:物理并发度提升后,逻辑库存从单行原子性变成多桶协调问题。
- 处置:以原子桶扣减和订单唯一键保证单次正确性,异步汇总展示库存,并保留对账纠偏。
- 复盘:只对被数据证明的热点启用分桶,避免全量复杂化。
十二、迁移校验专题
12.1 灰度、双写与对账
kb:knowledge:数据库迁移的风险不只在搬数据,还在于增量同步、读写切换、序列一致性和回退窗口。正确做法是把迁移视为一项可观测的状态机:全量、增量、双写、双读校验、灰度切换、全量切换和可控下线,每一步都有不变量与退出条件。
| 阶段 | 不变量 | 校验 | 回退条件 |
|---|---|---|---|
| 全量迁移 | 源目标行数与校验和可比 | 分片抽样与全量汇总 | 校验差异超阈值 |
| 增量追平 | 日志位点连续 | 延迟、漏数、重复数 | 增量不可追平 |
| 双写 | 两端写入结果一致 | 业务键对账 | 错误率上升 |
| 切读写 | 唯一权威写入口 | 核心链路回归 | 发现数据分叉 |
热门面试题
Q34:双写迁移为什么容易产生不一致?
- 场景:订单库从单库迁往分片库,应用短期同时写旧库和新库。
- 现象:网络超时、重试和部分失败使两边结果不同。
- 定位:以订单号和事件序号对账,区分未写入、重复写入、顺序错乱与字段转换差异。
- 根因:双写跨两个独立提交域,无法天然获得原子提交。
- 处置:采用主写加可靠事件驱动从写,所有写入幂等;对账任务持续补偿并设切换门槛。
- 复盘:双写只作为过渡状态,明确最长存续时间和下线条件。
Q35:切流前最关键的校验不是行数,是什么?
- 场景:新旧库行数一致,团队准备全量切换。
- 现象:行数一致仍可能有金额、状态、时间顺序或关联关系错误。
- 定位:按业务不变量校验,例如支付金额守恒、库存流水可推导、订单状态机合法、外键关联完整。
- 根因:技术行数只能证明数量相近,不能证明业务语义正确。
- 处置:把业务规则编码为可重复执行的对账任务,灰度期间持续监控差异。
- 复盘:迁移验收由研发、业务和数据共同签字,而非仅由数据库管理员确认。
Q36:如何设计可回退的读写切换?
- 场景:新分片库已灰度承接 5% 流量,出现少量数据差异。
- 现象:若新旧两端都可写,回退会扩大分叉。
- 定位:确认当前唯一写入口、双写状态、增量同步方向与已暴露用户范围。
- 根因:回退本质是状态迁移,必须避免两个权威源同时接受新写入。
- 处置:立即停止扩大灰度,冻结新端写入或将其降为只读,按事件回放补齐后再决定回退或前进。
- 复盘:切换开关设计成可审计状态机,每次变更记录位点与责任人。
十三、库存、支付与履约综合案例
13.1 跨链路故障的表达模板
kb:knowledge:库存、支付、履约案例要把“数据库问题”放回业务状态机。面试表达应明确:库存扣减是否原子、支付确认是否幂等、履约触发是否可靠、读写延迟是否影响用户可见性,以及异常后如何以流水对账和补偿收敛。
flowchart LR
O[创建订单] --> I[预占库存]
I --> P[支付确认]
P --> F[履约下发]
F --> L[物流状态]
P -.异常补偿.-> I
F -.对账补发.-> L热门面试题
Q37:库存预占成功但支付超时,如何避免库存永久占用?
- 场景:用户下单后库存预占成功,支付渠道长时间未回调。
- 现象:库存被占但订单无法进入履约,可能压缩可售量。
- 定位:关联订单创建、预占流水、支付状态、过期时间和回调消费记录。
- 根因:预占与支付是异步状态机,不能依赖单一同步调用完成闭环。
- 处置:为预占设置到期释放任务;支付成功回调以订单号幂等确认,超时后先核验渠道再释放或补单。
- 复盘:监控预占时长分布、超时释放量和支付后补单率,避免定时任务积压。
Q38:支付成功但履约消息重复,数据库如何保证不重复出库?
- 场景:消息队列重复投递“支付成功”事件。
- 现象:履约服务可能重复创建出库单。
- 定位:检查事件唯一标识、消费记录、出库单唯一约束和订单状态迁移。
- 根因:消息至少一次投递意味着重复是正常情况,消费者必须幂等。
- 处置:以支付流水号或事件号建立唯一键,事务内写消费记录与出库指令;重复事件返回已有结果。
- 复盘:对重复率、幂等命中率和唯一约束冲突做可观测化,而非把冲突当未知异常。
Q39:物流状态回传乱序,如何避免订单状态倒退?
- 场景:跨境物流事件因网络重试乱序到达。
- 现象:已签收订单被旧的“运输中”事件覆盖。
- 定位:比较事件发生时间、业务序列号、当前状态与允许迁移图。
- 根因:按到达顺序更新忽略了事件时间与状态单调性。
- 处置:仅接受序列号更大或状态机允许前进的事件;乱序事件记录审计并可重放。
- 复盘:状态表保存最后事件序号,回放任务按同一规则处理历史消息。
Q40:库存扣减、支付扣款、履约创建三者如何做一致性设计?
- 场景:高并发促销链路要求不超卖、不重复扣款且最终可履约。
- 现象:三个动作跨服务且不能依赖分布式大事务。
- 定位:划分本地事务边界、可靠事件、幂等键、状态机和对账责任。
- 根因:跨服务失败是常态,强行同步耦合会拉长锁和故障传播链。
- 处置:库存以原子预占保证边界,支付以渠道流水保证幂等,履约以事件驱动创建;失败通过补偿和对账收敛。
- 复盘:演练超时、重复、乱序、部分成功和人工介入,按链路输出对账报表。
Q41:一次慢 SQL(结构化查询语言)如何最终演变成支付重复请求?
- 场景:支付结果查询缺少联合索引,峰值时超时。
- 现象:客户端与网关重试,支付回调也重复到达。
- 定位:从慢查询扫描、连接池排队、接口超时、重试次数到支付流水重复请求串联时间线。
- 根因:数据库慢不是孤立问题;未限制的重试把原始拥塞放大为写入与回调风暴。
- 处置:先限流和退避,补充索引并让支付提交使用幂等流水号;对查询切换到明确的一致性策略。
- 复盘:重试预算与数据库饱和指标联动,关键接口区分可重试与不可重试错误。
Q42:请完整讲述一次“热点库存导致数据库故障”的项目案例。
- 场景:大促时单个爆款商品每秒数万次抢购,库存行更新成为热点。
- 现象:行锁等待增加、应用线程堆积、连接耗尽,随后部分支付确认超时。
- 定位:按商品、分片、SQL(结构化查询语言)指纹和等待链分析,确认绝大多数写入竞争同一库存记录。
- 根因:分片按商品路由并未分散单商品热点;同步扣减路径又承载所有失败重试。
- 处置:立即限购、排队和合并请求,保护支付与履约;后续对热点商品启用库存分桶与异步削峰,并以订单唯一键保证幂等。
- 复盘:压测覆盖真实热点分布,建立热点识别、自动降级和库存流水对账,明确业务、应用与数据库的责任边界。
十四、进入跨章题库前:怎样把答案讲成一次可信的线上经历
这一节是答题过渡,不新增知识点。先用 00-知识图谱与复习路线 确定机制位置:存储页与刷脏见 01-InnoDB(事务存储引擎)页、行与 Buffer Pool(缓冲池),访问路径见 02-B+Tree(多路平衡树)索引与优化器,事务可见性见 03-事务隔离与 MVCC(多版本并发控制),锁等待见 04-InnoDB(事务存储引擎)锁与死锁,日志恢复见 05-undo(撤销日志)、redo(重做日志)、binlog(二进制日志)与崩溃恢复,复制与恢复目标见 06-复制高可用与备份恢复,路由与迁移见 07-分库分表与迁移。
回答综合题时,先给出业务不变量,再说数据证据与时间线;随后区分“立刻止血”和“根因修复”,最后用量化结果、回滚边界和预防措施收束。不要把一个指标直接等同于根因,例如 CPU(中央处理器)高可能来自扫描、锁、自旋、重试或复制回放;副本延迟也不能直接等于丢数据。
| 回答层次 | 你要交代的内容 | 可被追问的证据 |
|---|---|---|
| 业务边界 | 库存、资金或履约的正确性底线 | 订单号、流水号、状态机 |
| 影响范围 | 读写、租户、分片、时间窗 | P99(99 分位响应时间)、错误率、分片热度 |
| 技术证据 | 数据库到底在等待或执行什么 | 慢 SQL(结构化查询语言)、锁链、日志位点 |
| 处置闭环 | 降级、回滚、修复与验证 | 影响行数、对账差异、恢复耗时 |
| 长期预防 | 监控、准入、演练与容量规划 | 阈值、负责人、演练记录 |
flowchart TD
A[业务不变量] --> B[影响范围]
B --> C[数据库证据]
C --> D[短期止血]
D --> E[根因修复]
E --> F[数据校验]
F --> G[预防与演练]十五、跨章综合题库:42 道 600 至 1000 字口述训练
15.1 读写性能、优化器与存储路径
kb:knowledge:综合题不是把多个名词串联,而是要求你证明因果链成立。关于性能,必须同时回答访问路径、缓存与磁盘、并发排队、应用重试和业务降级;缺少其中任一环,结论都可能失真。
数据演绎 2:高频中等慢查询为何优先级更高
库存查询单次多消耗 60 毫秒、每秒 400 次,等价于每秒额外占用约 24 秒数据库执行时间;运营报表单次慢 5 秒、每小时 20 次,平均每秒仅约 0.028 秒。前者即使单次不在慢日志最前,也更容易引发连接池排队。
数据演绎 3:深分页的扫描成本
若每个索引叶子页平均容纳 200 条记录,第 10 万页、每页 20 条的偏移分页需要跳过约 200 万条记录,至少触及约 1 万个叶子页;游标分页只从上次边界继续,工作量接近返回的 20 条加少量定位成本。
数据演绎 4:缓存污染的业务后果
一次导出读取 2,400 万行、每行索引与记录页合计约 1.5 千字节,理论读入约 34 吉字节冷数据。若 Buffer Pool(缓冲池)只有 24 吉字节,且无隔离,热点库存页会被大量淘汰,后续请求即使 SQL(结构化查询语言)不变也会增加物理读。
| 现象组合 | 优先假设 | 必须排除 | 首个安全动作 |
|---|---|---|---|
| P99(99 分位响应时间)升高且扫描行数暴涨 | 索引或统计信息问题 | 锁等待和网络延迟 | 限制异常查询 |
| 命中率稳定但提交抖动 | 脏页或日志刷盘压力 | 仅靠扩容可解决 | 暂停批写 |
| 连接数满且数据库负载不高 | 应用泄漏或慢客户端 | 数据库一定卡死 | 摘除异常实例 |
flowchart LR
Q[请求到达] --> P[执行计划]
P --> M[Buffer Pool(缓冲池)命中]
M -->|未命中| D[磁盘读取]
M -->|命中| L[锁与事务检查]
D --> L
L --> C[提交或返回]
C --> R[重试或成功]热门面试题
综合题 01:履约列表在大促时从偶发慢变成全链路超时,你怎样完成从慢 SQL(结构化查询语言)到重试风暴的闭环?
- 场景:跨境物流履约列表按商家、仓库、状态和时间筛选。大促后 P99(99 分位响应时间)由 220 毫秒升到 9 秒,网关开始重试,读库连接接近上限;页面展示可以短暂延迟,但出库裁决不能读旧数据。
- 现象:慢日志中该查询单次 700 毫秒到 1.5 秒不等,
rows_examined(扫描行数)从 3 千增长到 180 万;应用侧超时后最多重试三次,导致同一请求在高峰重复进入数据库。副本 CPU(中央处理器)升高而主库写入并未异常,说明先不能把问题归因于主库事务。 - 定位:我会先按商家、仓库、路由分片和查询参数聚合,确认是否只有头部商家触发;保留真实参数的
EXPLAIN(执行计划) ANALYZE(分析)、慢日志、连接池等待和副本回放位置。再比较预估行数与实际行数,检查联合索引是否与等值过滤、范围过滤和排序顺序一致。与此同时核对网关重试次数,计算一次用户点击最多放大为几次数据库读取,避免只优化单条语句却遗漏流量放大器。 - 根因:大促期间“待发货”状态高度集中,旧统计信息把它估算成低选择性;优化器(查询优化器)选中了仅含状态的索引,随后大量回表并排序。接口超时策略又把一次慢读放大为三次读取,副本延迟使少量读回退到主库,最终挤占了订单创建的连接资源。真正根因是数据分布改变、索引访问路径失配与无预算重试叠加,而不是单点 CPU(中央处理器)不足。
- 处置:止血阶段先将履约列表降级为异步刷新,限制深分页与导出,网关只对明确可重试的网络错误做一次带抖动退避的重试;库存和支付读保持权威主库路径。根治阶段用真实高频条件设计联合覆盖索引,并在影子流量验证扫描量、排序和写入代价;刷新统计信息后灰度发布。对超时请求通过请求标识合并,避免同一页面并发重复查询。
- 复盘:以 P99(99 分位响应时间)、总扫描行数、每请求重试倍数、连接池排队和副本回源率作为同屏指标。验收要求是大促压测下扫描行数回到万级以内、重试倍数小于 1.1、订单创建不受影响;同时为状态分布突变、深分页和报表查询设准入阈值,并保留一键摘除非关键读流量的开关。
综合题 02:优化器(查询优化器)在一个头部商家上连续误判,你如何在不滥用提示的前提下修复?
- 场景:WMS(仓储管理系统)按
merchant_id(商家标识)、状态和创建时间查询出库任务。大多数商家只有数百条待处理记录,但一个头部商家在活动期有 600 万条;同一套 SQL(结构化查询语言)在普通商家 30 毫秒,在头部商家超过 12 秒。 - 现象:执行计划对头部商家预估 2 千行、实际 420 万行,选择了状态索引后回表;临时加的索引提示让头部商家变快,却使普通商家的写入变慢且某些时间范围查询退化。团队因此不能把“提示有效”误认为是长期方案。
- 定位:我会抓取普通、头部、空结果三类真实绑定值,分别记录预估行数、实际行数、回表次数、临时表和排序成本;查询状态、商家与时间三列的分布、统计更新时间以及索引基数。还会确认查询是否真的需要宽字段,能否拆成先取主键再批量取详情,避免为了覆盖全部展示字段无限扩宽索引。
- 根因:商家维度高度倾斜,单列统计无法准确表达条件相关性;旧索引的前缀让数据库先命中巨大状态集合,再过滤头部商家。索引提示把当前一组参数固定在某条路径上,掩盖了普通商家、未来分布和写放大的差异,因此只能作为紧急窗口的临时围栏。
- 处置:先刷新统计信息并回归真实参数;若仍不稳定,建立以商家、状态、创建时间为访问顺序的联合索引,或按头部商家单独走受控查询模型。紧急期间仅对明确的头部商家和限时版本使用提示,并监控命中率与失效日期。对于需要全量运营扫描的请求,改走离线聚合而不是强迫在线事务表承担报表。
- 复盘:把预估/实际行数比、头部租户 Top N(前 N)流量和索引写入成本纳入发布前验收。索引提示必须登记适用参数、退出条件和责任人;数据规模跨量级、批量状态迁移后自动触发统计信息与执行计划回归,保证优化器(查询优化器)误判能在用户投诉前被发现。
综合题 03:为什么一次运营导出会让库存扣减抖动?请给出证据链和改造方案。
- 场景:运营在生产副本导出三个月订单明细,导出 SQL(结构化查询语言)无时间分桶且包含宽字段;随后 WMS(仓储管理系统)库存扣减 P99(99 分位响应时间)周期性升高,业务怀疑主库行锁。
- 现象:库存扣减所在主库锁等待并未增加,副本的 Buffer Pool(缓冲池)淘汰和磁盘读延迟却明显上升;读写分离路由在副本超时后将部分库存展示流量回源主库,主库连接池才开始排队。这个时间顺序说明“库存语句本身变慢”不是首因。
- 定位:我会将导出开始时间与副本物理读、页面缓存命中、路由回源率和主库连接数对齐;抽取导出执行计划,确认它扫描的页量、是否使用临时表以及是否跨越了热数据工作集。再检查库存裁决是否始终主库条件更新,确保没有把副本陈旧读用于放行扣减。
- 根因:无界导出把几十吉字节冷页读入副本,挤出高频订单和库存展示的热页,形成缓存污染;副本延迟和超时触发回源,原本隔离的报表负载穿透到主库。它不是传统意义的锁事故,而是存储层工作集、路由降级策略和业务读分级共同导致的级联拥塞。
- 处置:立即停止导出并限制副本上的大查询,展示类查询允许返回“数据刷新中”而不是无限回源;库存裁决保持主库原子更新。长期将运营导出迁至只读分析链路,要求时间范围、行数上限和异步任务;对副本路由设置陈旧阈值与熔断,回源必须按接口白名单而非全局默认。
- 复盘:验收不只看导出完成时间,还要看副本物理读、热查询 P99(99 分位响应时间)、回源率和主库连接余量。建立大查询准入、租户隔离和压测场景,把“缓存污染导致回源”写进值班手册,防止下一次以为加锁参数就能解决。
15.2 并发控制、长事务与日志提交
kb:knowledge:并发题的核心是识别“正确性约束在哪一层成立”。条件更新、唯一约束、事务、消息幂等和状态机各自承担不同边界;把它们混为一个“大事务”,会同时损害吞吐与可恢复性。
数据演绎 5:长事务的版本保留成本
若每秒有 8 千次更新、每次平均产生 600 字节历史版本,一个两小时不结束的读视图理论上可能阻挡约 34.6 吉字节历史清理。实际空间受页组织影响,但量级足以说明“只读导出”同样会威胁磁盘余量。
数据演绎 6:库存条件更新的原子边界
库存为 1 时,两个并发请求都先读取再扣减,二者都可能判断成功;改为“库存大于零才更新”的单条条件更新后,两个请求竞争同一行,只有一个影响行数为 1,另一个为 0。影响行数是裁决结果,不能再额外读副本确认。
sequenceDiagram
participant A as 请求甲
participant B as 请求乙
participant D as MySQL(关系型数据库)
A->>D: 条件扣减库存
B->>D: 条件扣减库存
D-->>A: 影响一行
D-->>B: 影响零行
Note over A,B: 订单唯一键防止重试重复成功| 约束 | 最适合承担的位置 | 失败后的处理 | 不应替代 |
|---|---|---|---|
| 库存非负 | 主库条件更新 | 影响零行则拒绝或排队 | 副本查询 |
| 重复支付回调 | 唯一键与状态机 | 幂等返回已有结果 | 盲目重试 |
| 事务过大 | 应用批次边界 | 断点续跑 | 无限延长超时 |
| 提交持久性 | 日志与存储策略 | 降低非关键写入 | 忽略丢失窗口 |
热门面试题
综合题 04:库存扣减遇到锁等待和死锁,你怎样既保护不超卖又避免重试风暴?
- 场景:WMS(仓储管理系统)大促库存扣减使用“先锁订单、再锁库存”的事务;补偿任务使用“先锁库存、再锁订单”的事务。峰值时既有锁等待超时,也有死锁回滚,业务要求不能超卖、不能重复创建预占流水。
- 现象:死锁日志显示两类事务交叉持有订单记录和库存记录;等待链中还存在一个批量补偿事务持续数十秒。应用层对任何数据库异常立即重试五次,短时间把失败请求放大,连接池和行锁队列同时增长。
- 定位:我会分别抓取死锁日志与实时锁等待,不能把两者混为一谈。锁等待需要找持锁者的开始时间、SQL(结构化查询语言)和是否在等待外部调用;死锁需要还原两个事务的访问顺序、索引范围和受害者。随后核对库存条件更新影响行数、预占流水唯一键、订单状态机与重试请求标识,确认重试是否幂等。
- 根因:根因是两条业务路径加锁顺序不一致,加上补偿任务批量持锁;重试策略又没有区分可安全重试的死锁受害者和不可盲目重试的超时或外部支付错误。数据库能回滚本地事务,却不能替应用判断外部动作是否已经完成,因此不能用“多重试几次”取代幂等设计。
- 处置:立即暂停或拆分长批量补偿,限制促销入口并对锁超时返回可轮询的受理结果;对死锁受害者仅在订单幂等键确认且未发生外部副作用时,进行有限次数的指数退避重试。根治时统一所有路径为先确定库存归属再处理订单,库存使用条件更新,预占流水建立唯一键,事务内禁止调用支付或消息外部服务。
- 复盘:用死锁数、锁等待分位数、最长事务、重试放大倍数、库存负数和唯一键冲突率联合验收。压测必须覆盖取消、补单、支付回调与补偿并发;值班手册明确何时杀阻塞者、何时暂停批任务,以及任何人不能通过直接改库存绕过流水与审计。
综合题 05:一个两小时的财务查询为何会拖垮写库?你如何止血并避免误杀?
- 场景:财务对账在主库开启一致性快照读,查询本身不更新数据却运行两小时;同一期间订单状态频繁迁移,磁盘使用率和写入延迟逐渐升高。有人建议直接杀掉所有长连接。
- 现象:活跃事务列表显示该查询很早创建了读视图,历史列表长度持续增大;锁等待不高,但 undo(撤销日志)相关空间与脏页压力上升。其他短事务的提交延迟变长,说明问题不是“查询占了一个连接”这么简单。
- 定位:我会以事务开始时间而不是当前 SQL(结构化查询语言)耗时排序,确认读视图是否仍活跃;将更新速率、历史版本增长、undo(撤销日志)空间、检查点推进和磁盘余量画在同一时间线。还要确认该任务能否从只读副本、备份或离线数仓重跑,避免误杀正在进行的恢复或关键审计。
- 根因:可重复读下旧读视图要求数据库保留它可见的历史版本,持续写入使版本链无法清理;这会放大 undo(撤销日志)和页回收压力,最终通过磁盘与刷脏影响正常提交。它不是锁住了全部写操作,而是耗尽了版本清理与存储资源。
- 处置:止血时先暂停可重跑导出,必要时终止该最老读事务,并限制新的一致性长读;同时降低非关键批量写入,预留磁盘安全空间。根治时改为按主键或时间水位分段读取,每批独立短事务并记录续跑位置;财务全量对账转移到一致备份、延迟副本或离线链路,线上只保留增量核对。
- 复盘:建立最老事务时长、历史版本增长速率、undo(撤销日志)空间、磁盘余量与提交 P99(99 分位响应时间)的联动告警。审批长查询时必须写明最大事务时长和中断策略;演练中验证杀掉长读后的回收曲线,避免值班同学因看不到即时下降就重复重启实例。
综合题 06:支付提交阶段变慢时,你如何判断日志持久化、锁还是存储故障?
- 场景:支付服务写入订单、支付流水和账务记录,语句执行通常很短,但某晚提交阶段从 15 毫秒升到 800 毫秒。用户重复点击支付,客服担心发生重复扣款。
- 现象:慢 SQL(结构化查询语言)显示执行时间不高,应用埋点显示耗时集中在提交;redo(重做日志)与 binlog(二进制日志)写入延迟上升,磁盘写队列变长。与此同时个别事务有锁等待,必须避免只凭一个指标下结论。
- 定位:我会把请求拆成取连接、执行、等待锁、提交和返回五段,按支付流水号关联渠道调用与本地事务。数据库侧查看活跃事务、锁链、redo(重做日志)检查点、binlog(二进制日志)刷盘和设备延迟;系统侧检查磁盘错误、突发限速和同时间的大批量写入。确认持久化策略后,明确任何参数调整可能改变故障时的数据丢失窗口。
- 根因:本例中批量归档与支付高峰叠加,使日志刷盘竞争存储队列;提交需等待持久化确认,所以执行快仍然整体慢。锁等待只是少量后果,重复支付风险则来自客户端超时后没有先按支付流水查询权威状态,而不是日志慢本身必然造成重复扣款。
- 处置:先暂停归档和非关键写入,保护支付库磁盘余量;支付接口超时返回“处理中”并引导轮询,不直接再次发起扣款。随后依据硬件与服务等级恢复写入能力,必要时评估只影响非关键链路的降级。根治是将归档拆批错峰、为支付设置独立资源预算,并保持本地提交、外部扣款与回调都以支付流水号幂等。
- 复盘:验收看提交 P99(99 分位响应时间)、日志刷盘延迟、磁盘队列、支付幂等命中与重复扣款为零。复盘中记录当前持久化配置对应的恢复点目标,不把“调低刷盘频率”写成无代价优化;定期压测批任务与支付峰值叠加的最坏场景。
15.3 复制、切主、数据不一致与恢复
kb:knowledge:复制题必须区分“源端提交”“副本接收”“副本回放”和“读路由可见”四个时刻。切主题必须先回答如何阻止旧主继续写入,再讨论候选副本;恢复题必须先在隔离环境证明目标数据正确,不能以实例能启动代替业务可用。
数据演绎 7:副本延迟怎样制造读己之写问题
支付成功写入主库后 0.2 秒返回,副本回放平均延迟 4 秒。若页面立即读副本,即使副本 99% 健康,首个 4 秒窗口仍可能读取旧状态;用户每秒刷新一次会触发四次无效查询,若又发起支付重试,就会把陈旧读升级为业务重复。
数据演绎 8:切主的恢复点损失量化
候选副本落后 18 秒,而高峰写入为每秒 700 笔,其中 8% 是资金或库存状态变更。直接提升该副本的理论缺口约 1.26 万笔,关键变更约 1008 笔。这个数字不是让你拒绝切换,而是要求你在切换前冻结高风险写入、记录缺口并准备对账补偿。
| 切换状态 | 唯一写入口 | 必须验证 | 禁止动作 |
|---|---|---|---|
| 故障确认前 | 原主库 | 网络、应用与代理视角 | 多点手工提升 |
| 提升候选中 | 暂停或受控写入 | 日志集合与围栏 | 让旧主继续服务 |
| 新主恢复后 | 新主库 | 路由、只读、对账 | 双侧同时写 |
| 旧主回归 | 副本重建路径 | 数据基线与复制状态 | 直接重新接写 |
sequenceDiagram
participant App as 应用
participant S as Source(源库)
participant R as Replica(副本库)
App->>S: 支付状态提交
S->>R: 发送 binlog(二进制日志)
App->>R: 立即查询
Note over R: 尚未回放会读到旧状态
R-->>App: 旧结果或受理中热门面试题
综合题 07:支付成功后页面读到“待支付”,你如何证明是复制延迟而非支付漏单?
- 场景:用户完成支付后,支付渠道回执与主库支付流水均显示成功,但订单详情偶尔显示待支付,数秒后刷新恢复。业务担心支付服务没有正确更新订单,也担心用户再次付款。
- 现象:写请求落在 Source(源库),详情查询经读写分离路由到 Replica(副本库);问题只发生在支付后很短窗口,且副本延迟监控在高峰有数秒波动。支付回调消费记录完整,但页面请求没有携带会话一致性要求。
- 定位:我会按支付流水号串联渠道回执时间、主库提交时间、binlog(二进制日志)位置、副本接收与应用位置、路由日志和页面查询时间。若主库已存在正确状态、副本随后追平,且同一订单无消费失败记录,就能区分陈旧读与漏单;同时检查是否有人把副本结果用于支付幂等裁决。
- 根因:异步复制只保证副本最终追上,不保证写后立即可见;页面把允许短暂陈旧的详情查询误当成读己之写场景。重复风险来自用户看到旧页面后再次触发支付,而不是数据库丢失了已提交状态。
- 处置:支付写后窗口内将订单详情会话粘滞到 Source(源库),或返回“支付受理成功、状态同步中”并轮询权威状态;支付入口始终按支付流水号查主库与渠道,不依据副本旧状态再次扣款。副本延迟超过阈值时,展示类请求可降级为最后更新时间,关键交易读直接走主库或排队。
- 复盘:验收指标包括写后旧读率、支付重复提交率、副本延迟分位数、主库回读比例和支付补单量。接口契约显式标注强一致、读己之写和最终一致,路由组件按接口语义而非单纯读写类型分流;压测时加入副本延迟、网络抖动和用户连续刷新场景。
综合题 08:主库故障且最佳候选副本落后 20 秒,你如何切主并控制业务损失?
- 场景:跨境物流主库不可用,三个 Replica(副本库)中最接近者仍落后约 20 秒;订单创建、库存预占和支付确认都依赖该集群。业务要求尽快恢复,但明确不能形成双写脑裂。
- 现象:代理健康检查已摘除主库,但网络分区尚未完全排除;部分应用连接池可能还保留旧主地址。候选副本的 中继日志存在待回放事务,最近窗口包含库存与支付状态变更。
- 定位:先冻结高风险写入口,收集 Source(源库)最后已知日志位置、各 Replica(副本库)接收和执行集合、网络连通性、旧主写权限与应用路由。评估每个候选的恢复点缺口和数据健康度,不能只选择延迟数字最小者;若有更近副本但存在校验差异,应优先判断其数据基线是否可信。
- 根因:异步复制下源端已确认的事务可能尚未被副本应用,网络分区还可能让旧主继续接收写入。切换的核心风险不是“提升命令失败”,而是丢失窗口与双权威写入口同时存在。
- 处置:先执行 fencing(栅栏)隔离旧主:撤销写权限、阻断网络与路由、确认旧连接失效;随后提升经核验的候选副本,设置其为唯一写入口,逐步恢复低风险读写。对落后窗口内的订单、支付和库存建立缺口清单,支付先查渠道、库存以流水对账、履约按事件补发;所有补偿以幂等键执行。
- 复盘:记录宣告故障、围栏完成、提升、路由生效和业务恢复的时间线,分别度量恢复时间目标与恢复点目标。演练必须包含旧主“假死”、域名缓存、连接池粘连和候选延迟;自动化编排只负责提升与路由,业务正确性仍由状态机、幂等和对账负责。
综合题 09:副本延迟持续扩大,你如何判断是网络、接收、回放还是大事务,并安全恢复?
- 场景:夜间批量归档后,某 Replica(副本库)延迟从秒级增长到两小时,运营查询开始超时。有人提出直接跳过报错事务或无限增加应用线程数。
- 现象:该副本 中继日志增长明显,但网络带宽没有饱和;应用线程偶有等待,源端存在一次 800 万行更新。其他副本延迟较小,说明不能简单归因于源端写入总量。
- 定位:我会分开比较接收位置和执行位置:若接收本身落后,检查网络、Source(源库)发送线程与磁盘;若接收已追上而执行落后,检查大事务大小、锁等待、应用线程忙闲、依赖关系和存储延迟。抓取长事务与错误日志,确认是否存在 DDL(数据定义语言)阻塞或复制冲突。
- 根因:本例是超大更新事务在副本顺序回放,期间又与运营读竞争资源,导致并行复制无法充分展开。增加线程无法拆开一个单一大事务;跳过事务虽然会让延迟数字变小,却会把时间问题变成数据不一致事故。
- 处置:立即把关键读流量从该副本摘除,暂停归档和大查询,保留日志与位点;允许副本在隔离资源下追平。若事务确认有问题,按原事务重放或从一致备份重建,而非跳过。长期把归档改成按主键小批提交并错峰,限制单事务日志量;运营查询转专用副本或离线系统。
- 复盘:监控拆分为接收延迟、应用延迟、中继日志积压、最大事务大小和并行度,不再只展示一个“延迟秒数”。发布批任务前做副本回放压测,设定摘流和恢复阈值;任何跳过复制错误的操作必须有变更单、数据修复方案与全量校验。
综合题 10:发现库存余额与流水不一致时,怎样避免“修复脚本制造第二次事故”?
- 场景:日终核对发现一个海外仓的三十个商品库存余额与流水汇总不一致,其中两个商品余额为负。白天仍有出入库、退货和盘点事件,业务希望立即把余额改成流水计算值。
- 现象:差异可能来自重复消息、漏消费、人工盘点、迁移期间双写失败或顺序错乱;仅看当前余额无法判断权威事实。直接更新余额会绕过预占、可售、冻结库存等子字段与审计链。
- 定位:我会先冻结受影响商品的自动分配或设置保守安全库存,记录差异快照;以商品、仓库、批次和事件序号重放不可变流水,关联订单、支付、履约、退货与盘点。按时间窗区分历史差异和仍在增长的实时差异,并核对每个事件的唯一键、消费状态和迁移位点。
- 根因:本例最终确认迁移双写时少量副写超时被错误地标为成功,补偿任务又因乱序跳过了部分库存事件。余额是派生结果,流水和业务事件才是可追溯事实;因此根因不在“余额列算错”本身,而在双写确认与事件顺序治理缺失。
- 处置:先停止扩大迁移灰度,按事件编号补齐缺失事件;在隔离环境重放并计算目标余额,双人复核影响范围后以带版本条件的小批更新校正。校正过程写入专门的调整流水,不能静默改表;对负库存商品保持冻结,待订单、预占和履约链路对账通过再放开。
- 复盘:构建分桶增量对账,既校验余额也校验预占、冻结与可售不变量;双写必须区分“调用成功”和“两端持久化成功”,失败进入可重放队列。数据修复模板要求前置快照、预期行数、暂停开关、反向脚本和业务验收,修复完成后持续观察差异是否再次增长。
综合题 11:误删了支付流水的一部分,你如何设计时间点恢复而不覆盖之后的正常订单?
- 场景:运营脚本误删某商家半小时内的支付流水,发现时已过去一小时,期间仍有大量正常支付、退款和对账写入。全量备份在误操作前完成,binlog(二进制日志)连续可用。
- 现象:直接把备份恢复到生产会丢掉误操作后的一小时正常数据;只手工补几行又无法保证关联账务、订单状态和回调消费记录完整。事故处理必须先确定误操作事务边界,而不是以发现时间做恢复点。
- 定位:我会立即停止相关高危脚本、保全审计、备份和 binlog(二进制日志),确定账号、表、主键范围、开始结束时间与日志位置;在隔离实例恢复最近基线,再将日志回放到误操作前。随后从隔离实例导出缺失的支付流水及其关联事实,以支付流水号、版本和状态机判断哪些可回补。
- 根因:根因是高危权限与脚本范围缺少保护,恢复难点则来自生产在误操作后仍持续前进。PITR(时间点恢复)解决的是构造正确历史视图,不等于可以把那个历史实例直接替换正在服务的生产库。
- 处置:先在隔离环境验证行数、校验和、金额守恒和抽样订单链路;正式回补采用幂等插入或状态机补单,避开已被正常流程重新生成的数据。若外部渠道状态不明,进入人工核验队列而非猜测;全过程控制变更窗口,回补后再次对账并保留审计。
- 复盘:验收以恢复出的业务不变量、实际恢复时间与未覆盖正常写入为准,不以“数据库可启动”为准。长期限制生产删除权限,脚本默认先预览、要求范围上限和双人审批;定期演练备份恢复、日志连续性、密钥权限与回补脚本,量化恢复点目标和恢复时间目标。
综合题 12:切主后为什么还要对账?请用库存、资金和履约三条链路说明。
- 场景:集群已完成故障切换,新主对外服务正常,技术监控也显示复制已恢复。团队倾向于宣布事故结束,但切换窗口内曾存在十几秒副本落后与部分客户端超时。
- 现象:技术层“服务可用”只能说明新主能读写,不能证明旧主隔离前是否接收过写入、候选副本是否遗漏已确认事务,或应用是否因超时重复提交。库存、资金和履约对错的后果不同,不能用同一行数校验代替。
- 定位:库存按商品仓库重放预占、释放、出入库流水,检查余额守恒与负数;资金按支付渠道回执、支付流水、账务分录和退款链路核验金额守恒;履约按订单状态机、出库单唯一键、物流事件序号检查漏发与重复。三条链路都将切换时间窗、请求标识、日志位点和补偿动作纳入审计。
- 根因:切换缩短的是可用性中断,并不能消除异步复制恢复点缺口、网络分区残留连接和超时重试造成的业务差异。若不对账,缺失或重复会在后续结算、盘点和客服投诉时才暴露,修复成本更高。
- 处置:切换后先维持高风险操作的受控流量,建立按优先级的差异队列;支付优先查单并补状态,库存优先冻结差异货品并重放流水,履约优先拦截重复出库和补发漏单。所有回补使用同一幂等键,完成一类就记录证据和剩余风险,不做无审计的批量覆盖。
- 复盘:将“切主完成”拆为技术切换完成、关键链路抽样完成、全量对账完成三个里程碑。演练中把对账耗时、差异处置时长和人工兜底能力纳入恢复时间目标;监控还应覆盖旧主访问尝试、超时重试率和切换窗口内的新旧写入差异。
15.4 分片热点、扩容迁移与跨库语义
kb:knowledge:分片解决的是容量和资源隔离边界,并不保证访问均匀,也不自动提供全局事务。扩容成功的判据不是“数据搬完”,而是路由版本、增量位点、业务不变量、读写权威与回退边界均可证明。
数据演绎 9:平均均衡为何仍会单片失火
64 个分片平均每秒 1 千次写入,看似容量充足;但一个爆款商品若集中在单片并贡献每秒 3 万次库存请求,该片负载是平均值的 30 倍。平均 TPS(每秒事务数)掩盖了热键、行锁与队列竞争,必须按路由键和分片分别看 Top N(前 N)。
数据演绎 10:双写 99.99% 成功的尾部风险
若迁移双写每秒 2 万笔,成功率 99.99%,每天理论仍有约 1728 笔副写失败。对订单浏览这也许可补偿,对支付流水或库存预占则必须进入可追溯的补偿队列;“成功率很高”不能作为忽略差异的理由。
| 迁移证据 | 证明什么 | 仍不能证明什么 | 必要补充 |
|---|---|---|---|
| 全量行数相等 | 大致没有漏搬 | 字段和业务语义正确 | 校验和与不变量 |
| 增量位点追平 | 传输未明显落后 | 两端写入都成功 | 双写结果对账 |
| 灰度无报错 | 部分路径可用 | 长尾租户与回退可行 | 分桶压测与演练 |
| 新库可读写 | 技术链路通 | 唯一权威已建立 | 路由审计与围栏 |
flowchart LR
A[旧分片全量回填] --> B[增量追平]
B --> C[旧写新副写]
C --> D[影子读校验]
D --> E[灰度新读写]
E --> F[新端单写]
C -.差异.-> G[幂等补偿]
E -.异常.-> H[按路由版本回退]热门面试题
综合题 13:爆款商品让一个分片打满,你如何判断热点、止血并设计长期方案?
- 场景:订单按商品路由分片后,大促中单个爆款商品占据一个分片绝大多数请求。该片 CPU(中央处理器)、行锁等待、连接池排队同时升高,其他分片却较为空闲;库存扣减、商品展示和订单查询都受到影响。
- 现象:平均分片 TPS(每秒事务数)仍在容量线内,导致初看监控以为数据库整体健康;下钻后发现同一
product_id(商品标识)贡献超过 80% 写入,库存行竞争最严重。若直接扩容分片数量,路由不变时热点仍会落在一个桶里。 - 定位:我会按分片、商品、仓库、SQL(结构化查询语言)指纹和锁等待链统计,确认是热键、热行还是某类查询广播。再检查读展示是否可以缓存,扣减是否为单行条件更新,支付与履约是否被同一分片的非关键读拖累;把热点请求与用户重试、机器人流量和限购规则放在同一时间线。
- 根因:哈希或按商品路由只均衡键空间,不均衡真实访问频率;单商品库存是天然串行资源。无限制抢购与同步失败重试把行锁排队放大,单纯加实例不能突破同一行的并发边界。
- 处置:短期先限购、验证码或排队,合并重复展示请求,暂停该片报表并保护支付与履约连接;扣减失败返回排队或售罄而不是立即重试。长期只为经数据证明的热点商品启用库存分桶、令牌预分配或队列串行消费,所有路径仍以订单唯一键和流水对账保证不超卖;普通商品保持简单模型,避免全局复杂化。
- 复盘:验收按热点商品单行锁等待、分片 P99(99 分位响应时间)、削峰队列积压、库存负数和售罄误判率衡量。容量规划使用 Top N(前 N)热键而非平均负载;将热点识别、降级开关、库存校验和人工兜底纳入演练,明确何时从缓存展示切换到保守售罄。
综合题 14:订单库扩容时,为什么“全量数据已搬完”仍不能切流?
- 场景:订单从 16 个分片扩到 64 个分片,历史全量回填完成且行数相等。团队计划当晚把路由规则切到新分片,但增量同步仍有几十秒波动,部分服务的路由规则缓存刷新较慢。
- 现象:行数相等只能说明快照时大致完整;在回填期间新增、更新和删除仍在旧库发生。若新旧路由同时生效,同一订单可能读写到不同位置,支付回调与履约事件会形成难以合并的数据分叉。
- 定位:我会确认全量基线水位、增量消费位置、每个分桶的追平状态、路由版本传播、双写成功率与影子读差异。校验不只看订单行数,还要看订单项绑定关系、支付金额守恒、状态机合法性、唯一键冲突和跨服务事件序号;对头部商家、历史长尾、退款单等特殊集合抽样加严。
- 根因:迁移是全量快照与持续增量的组合过程,且路由规则本身也是数据的一部分。缺少统一路由版本与唯一写权威时,即使数据库内容相同,应用仍可能把后续请求写错位置。
- 处置:保持旧端为唯一写权威,待增量位点稳定追平后开启新端副写与影子读;灰度时按确定的路由版本和租户桶切换,所有请求携带可审计版本。差异增长或位点回落即停止扩大灰度,按版本将该桶回退旧端,再通过幂等事件补齐新端;达到稳定窗口后才切新端单写。
- 复盘:将“可切流”定义为位点、双写、影子读、不变量、路由传播和回退演练六项同时通过。迁移看板按桶而非总量展示,值班人员能看到每个桶的权威端;下线旧库前保留足够的双向核对和备份窗口,避免把迁移完成误写成数据搬运完成。
综合题 15:双写期间支付回调重复到达,怎样避免新旧库双重副作用?
- 场景:订单迁移采用旧库主写、新库副写,支付渠道对同一支付流水可能重复回调;网络超时会让应用不知道副写是否成功。履约服务又订阅支付成功事件,任何重复都可能创建多张出库单。
- 现象:旧库唯一键能挡住重复支付,但新库副写偶发超时,重试时可能出现“已写入但客户端未收到响应”。若只根据调用返回值决定是否发布履约事件,会把双写的不确定性传播成业务重复。
- 定位:我会以支付流水号和事件序号作为跨库幂等键,分别核对旧端、新端、消息表和出库单;记录每次副写尝试的路由版本、结果和可重放状态。对超时不立即认定失败,而是查询权威端或消费幂等记录;同时检查双写队列是否按同一业务键保持顺序。
- 根因:双写跨两个独立提交域,没有天然原子性;支付回调又是至少一次到达。错误根因不是“唯一键不够”,而是把数据库调用成功、业务事件发布成功和两端状态一致误认为同一件事。
- 处置:旧库主事务中持久化支付状态与可靠事件,新库由幂等消费者副写;支付流水号在两端和履约侧均有唯一约束,重复回调只返回已有结果。副写失败进入可观测补偿队列,履约只消费权威事件而不消费每次双写尝试;切换期间以影子对账发现字段或顺序差异。
- 复盘:监控幂等命中、双写超时、补偿滞留、事件重复和新旧状态差异,不能只看接口成功率。迁移设计文档明确每个阶段的写权威、读权威与事件源;压测覆盖超时后重试、消息重复、乱序和切换瞬间,验证任何路径均不重复扣款或出库。
综合题 16:跨库分页和排序把数据库拖慢,你会如何改变查询模型?
- 场景:运营需要查看全站订单并按创建时间倒序翻到很深页面。订单已按商家分片,接口对每个分片执行偏移分页再在应用层归并,分片数增长后响应从 500 毫秒升到十几秒。
- 现象:单个分片语句看似都有索引,但总扫描量等于分片数乘以深偏移;应用归并占用大量内存,慢分片拖住整体。运营希望继续保留任意页码跳转,研发若只给每片加索引无法改变数量级。
- 定位:我会量化每个分片的扫描行数、返回行数、偏移量、网络传输与归并耗时,确认查询是否携带商家或时间边界。再区分在线交易详情、商家维度列表和全站运营分析三类语义:它们不能共用一个“万能分页接口”。
- 根因:分片后全局有序集合不再存在于单个数据库,深偏移要求每片丢弃大量记录;中间件只能转发和归并,不能消除物理扫描。问题是查询模型与数据布局不匹配,而不是某条索引缺失。
- 处置:交易侧要求路由键并使用稳定游标分页;商家列表保持商家同片;全站运营列表改为异步索引、数仓或物化视图,接受明确延迟。短期限制最大页深和分片并发,给运营导出异步任务;不要让所有分片在高峰为二十条展示数据扫描百万行。
- 复盘:接口文档写清楚一致性、延迟、最大范围与排序字段,前端改用游标而非页码幻觉。上线验收统计广播率、每请求分片数、扫描放大倍数和归并内存;分片方案评审必须先列举关键查询入口,避免先按容量拆表再把查询复杂度转嫁给应用,并为高频参数保留可复现的性能基线。
综合题 17:迁移后行数与校验和都一致,却发现可售库存错了,如何定位?
- 场景:库存库迁移验收中,源端和目标端每张表行数、主键集合与字段校验和均一致;灰度后却出现部分商品“可售为零”而余额充足。团队最初认为是缓存没有刷新。
- 现象:库存表包含实物余额、预占、冻结、可售等派生字段;行级相等不代表它们与订单、支付、履约事件的时间顺序一致。差异只集中在迁移窗口内发生取消后又支付成功的订单,说明需要回到业务状态机而非只查缓存。
- 定位:我会按商品、仓库、订单号和事件序号重放窗口内库存事件,比较源端与目标端每次状态迁移的先后;核对迁移过程中双写、消息消费和回放是否使用同一时区、版本与幂等条件。再检查是否有事件在目标端被“旧版本覆盖新版本”而表最终字段恰好相同。
- 根因:目标端消费了乱序的取消和支付确认,因版本比较缺失导致可售派生值被旧事件覆盖;表的最终静态校验无法发现跨表、跨时间的业务语义错误。缓存只放大了展示时间,并非根因。
- 处置:暂停受影响桶的进一步切流,以事件序号为准重放并建立调整流水;对差异商品冻结自动出库,待余额、预占、冻结和订单状态同时满足不变量后恢复。修复程序必须带版本条件、影响行数校验和可回滚快照,不能用全表重新计算覆盖仍在变化的实时数据。
- 复盘:迁移校验升级为结构、物理、业务不变量和链路四层:除行数校验外,必须校验库存守恒、事件单调性和订单到库存流水的可追溯性。灰度前注入重复、乱序、延迟事件;任何“校验和一致”的结论都要注明它证明的范围,避免误导业务放开流量。
综合题 18:路由规则发布错误导致订单查空,你如何止血、回退和防止错写?
- 场景:扩容后的路由规则把某批商家的订单查询打到新分片,但该批数据尚未完成增量追平;部分写请求也携带了新版本路由。用户看到订单为空,客服开始催促人工补单。
- 现象:旧分片仍有完整历史订单,新分片只有回填快照;查询查空并不等于订单丢失。真正危险是错误路由下的新写会在新旧端形成双权威,后续即使回退查询也难以自动合并。
- 定位:我会按订单号追踪请求使用的路由版本、命中的分片、迁移水位和新旧写入记录;立即检查所有服务的规则缓存版本以及消息消费者是否独立计算路由。区分只读查空、错写已发生和外部事件已发出三类范围,再决定回退粒度。
- 根因:路由发布没有以迁移桶的追平状态为前置条件,规则版本传播又缺少统一审计;数据位置与路由版本失配。它不是数据库查询失败,而是控制面变更越过了数据面准备度。
- 处置:先按路由版本将受影响桶回退旧端,冻结新端写入并阻止消息消费者继续按错误规则落库;对已经错写的订单,以订单号和事件序号归集后幂等回放到权威端,旧端仍作为唯一真相。用户侧返回受理中或读取旧端,不让客服通过手工造单修复查空。
- 复盘:路由发布必须与桶级迁移状态机绑定,未追平桶不能领取新版本;每个请求、事件和数据修复均记录路由版本。建立查空率、跨桶写入和新旧双写检测告警,发布前演练缓存滞后、部分服务失败与快速回退,确保控制面错误不会变成永久数据分叉,并在回退演练中验证所有消费者同步收敛到同一规则版本。
15.5 告警取证、变更控制与容量治理
kb:knowledge:排障依赖可比较基线、同一时间窗证据和清晰止损授权。告警不是结论;每次处置都要保留影响范围、变化点、操作记录和验证结果。
数据演绎 11:连接池排队的放大
数据库可稳定完成每秒 800 个请求,若应用超时后每个请求重试两次,原始每秒 500 个请求会被放大到 1500 个。先削减重试倍率,才能让排队收敛。
热门面试题
综合题 19:数据库连接耗尽但 CPU(中央处理器)不高
- 场景:跨境物流查询服务获取连接超时,数据库 CPU(中央处理器)仅 45%,连接数却接近上限。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:连接泄漏、空闲事务或慢客户端使连接资源被长期占用,超时重试继续放大排队。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:摘除异常实例并回收确认无事务的空闲连接;修复连接生命周期与池上限。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 20:一次 Online DDL(在线数据定义语言)为何造成全站阻塞
- 场景:订单表加索引期间多个接口等待,团队误以为 Online DDL(在线数据定义语言)完全无阻塞。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:长事务持有 MDL(元数据锁),等待的 DDL(数据定义语言)又形成队列效应。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:取消可回滚变更或终止可重跑长事务;低峰演练并建立 DDL(数据定义语言)准入。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 21:慢 SQL(结构化查询语言)告警消失后为何不能宣布恢复
- 场景:阈值调整后慢日志变少,但接口 P99(99 分位响应时间)和副本延迟仍不稳定。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:告警口径或流量下降掩盖了扫描、回源与重试的真实压力。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:维持保护并以固定负载回放验证;核心业务指标、等待和容量余量同时恢复才放量。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 22:怎样把容量预测升级为可执行方案
- 场景:订单库磁盘使用率 68%,业务要求说明何时归档、扩容或分片。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:磁盘只是一个边界,索引膨胀、恢复时长、复制和热点写入可能先越界。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:按峰值和故障冗余建模,短期归档与索引治理,中期规划可回退迁移。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 23:应用发布后数据库抖动如何证明因果
- 场景:发布后订单库 P99(99 分位响应时间)升高,同时定时任务启动,两个变化点接近。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:新增 SQL(结构化查询语言)、连接行为或重试可能与批任务叠加,时间接近不等于因果。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:停止扩大发布并关闭非关键任务,用小流量可逆验证确定代码、索引或任务修复。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 24:为什么止血优先级按正确性排序
- 场景:支付、库存和履约同时变慢,业务希望关闭全部保护恢复吞吐。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:将关键裁决切到副本或无界重试会把性能事件扩大成超卖和重复扣款。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:先保护支付流水、库存条件更新与唯一写入口,展示和导出类请求后恢复。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
15.6 备份演练、恢复校验与数据治理
kb:knowledge:只有在隔离环境按目标时间恢复、完成业务不变量校验并证明回补可控,才能声称满足恢复点目标和恢复时间目标。
数据演绎 12:恢复时间不能只看导入速度
2 太字节物理备份以每小时 500 吉字节恢复约需 4 小时,再加日志回放、校验和切换,实际恢复约 5 小时 50 分钟。若承诺两小时,必须预先改变基线或架构。
热门面试题
综合题 25:备份成功却无法恢复如何修复体系
- 场景:灾备演练中备份可下载但恢复失败,过去只监控任务退出码。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:备份链未被真实消费,工具、密钥、权限、日志或存储任一环都会失效。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:在隔离环境复现并修复链路,把恢复和业务校验纳入例行演练。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 26:延迟副本能否替代备份
- 场景:团队配置延迟 Replica(副本库)后希望减少备份投入。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:延迟副本只覆盖有限窗口,仍依赖日志、拓扑与只读治理,不能承担长期灾难恢复。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:先构造正确历史再按业务键回补;保留独立备份和时间点恢复能力。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 27:数据修复为何必须有反向脚本
- 场景:履约状态需要批量修正,但白天物流事件仍在更新同一批订单。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:无条件更新会覆盖新状态,重复执行会制造第二次事故。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:以版本条件小批更新,固化前快照和反向数据集,影响行数异常即停止。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 28:恢复后怎样校验支付账务
- 场景:支付库恢复后行数和校验和正确,准备切回服务。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:物理相等不能证明金额守恒、退款完整和渠道回执关联正确。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:按支付流水核验订单、渠道、分录和退款,未知状态进入人工核验。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 29:为何区分发现时间和误操作时间
- 场景:凌晨发现误删,审计显示脚本更早开始且多次重试。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:发现时间不是事务边界,错误截点会覆盖正常写入或遗漏误删数据。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:以审计和 binlog(二进制日志)确定精确窗口,在隔离环境验证候选恢复点。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 30:恢复演练如何保护敏感数据
- 场景:隔离恢复需要真实数据验证支付库存,但安全团队限制明文数据外流。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:缺少权限、网络、密钥和生命周期控制会让灾备流程变成泄露通道。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:使用受控隔离和保持关联关系的脱敏,恢复后销毁副本与临时密钥。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
15.7 库存、支付、履约与异步任务闭环
kb:knowledge:交易可靠性来自本地原子操作、唯一幂等键、可靠事件、状态机和持续对账;数据库事务不能自动回滚外部支付,消息也不会天然消除重复和乱序。
数据演绎 13:超时重试的库存放大
库存服务每秒 1200 次请求,5% 超时且最多重试三次会额外产生 180 次;当超时升到 30%,额外请求为 1080 次。必须先限重试和排队。
热门面试题
综合题 31:订单创建但库存预占结果未知
- 场景:下单后库存调用超时,库存侧可能已成功预占但响应丢失。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:跨服务调用结果与实际执行分离,客户端重试会造成重复占用。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:订单进入受理中,按订单号查询幂等流水,明确失败才释放或取消。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 32:支付回调与主动查单并发
- 场景:渠道回调延迟时系统主动查单,随后回调再次到达。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:两个事实输入乱序或重复,可能造成状态覆盖、死锁或重复事件。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:用支付流水唯一键和单向状态机幂等推进,未知冲突进入核验队列。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 33:履约消息堆积为何不能无限扩消费者
- 场景:支付成功消息积压,扩容消费者后数据库锁等待反而增加。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:热点订单和库存行具有串行边界,增加并发只会扩大竞争和重复投递。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:按业务键限流并隔离热点队列,优化短事务和幂等写入后再扩容。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 34:退款成功但库存未释放如何补偿
- 场景:渠道退款成功,本地退款状态已变更,库存预占仍然存在。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:跨服务本地事务不能自动收敛,部分成功需要可靠事件和幂等补偿。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:按预占号发布可重放释放事件,失败进入补偿队列,超过阈值人工核验。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 35:IoT(物联网)报警风暴怎样保护交易库
- 场景:设备异常时数十万报警短时写入,历史索引与复制压力影响订单库。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:重复报警没有业务价值,却放大日志、索引和热点资源竞争。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:入口去重合并限流,原始事件走异步链路,数据库保留状态快照与必要审计。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 36:Runner(执行器)重复执行怎样保证最后防线
- 场景:故障恢复后多个 Runner(执行器)领取同一对账任务,可能生成重复调整。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:调度锁和消息都可能至少一次,数据库唯一约束才是最终事实边界。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:以任务键和业务键双重幂等,外部副作用先查流水,失败可重跑不重复调整。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
15.8 项目串讲、面试追问与综合决策
kb:knowledge:项目话术要呈现量化问题、最小风险方案、回退边界、验证结果与工程化预防;不要把未经验证的细节包装成确定事实。
数据演绎 14:多指标恢复门槛
只有 P99(99 分位响应时间)连续 15 分钟低于基线 1.2 倍、错误率低于 0.1%、副本延迟低于 2 秒且关键对账差异为零,四项同时满足才扩大流量。
热门面试题
综合题 37:怎样讲一次慢 SQL(结构化查询语言)优化
- 场景:面试需要讲履约轨迹查询在峰值超时,不能只说“加了索引”。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:若没有扫描量、计划、灰度和写放大证据,优化故事无法经受追问。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:按影响、证据、止血、索引验证、灰度、结果串讲,并标明实测与估算。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 38:怎样回答库存不超卖
- 场景:WMS(仓储管理系统)包含展示、预占、支付、取消和盘点,单说加锁不完整。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:原子扣减不能替代幂等、补偿、热点治理与流水对账。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:以主库条件更新裁决、唯一流水防重、状态机收敛,异常冻结并重放流水。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 39:为何不用分布式大事务解决支付履约
- 场景:支付、库存、履约跨服务,面试官追问为什么不统一协调提交。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:外部渠道不可回滚,长事务持锁并放大网络故障,协调失败会扩散。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:短本地事务加可靠事件、幂等与对账,在边界内证明一致性并保留人工兜底。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 40:如何讲一次切主演练
- 场景:支付库高可用演练需要说明候选选择、围栏、重连、缺口和业务验收。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:技术切换成功不代表旧主残留写和异步复制缺口已经被消除。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:受控流量下验证 fencing(栅栏)和唯一写入口,随后完成资金库存履约对账。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 41:如何在索引、副本、分片和缓存中选型
- 场景:订单查询变慢时,团队提出多种方案,需说明选择而不是堆技术。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:各方案分别解决访问路径、读扩展、写容量和热点读,错误使用会破坏一致性。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:先用证据定位瓶颈,选择最小风险可验证方案,保留压测门槛和回退。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
综合题 42:怎样串讲一次负责人视角的数据库故障
- 场景:大促中热点库存、慢查询和重试叠加,支付和履约受影响。 你首先要声明正确性边界:资金、库存和履约不能为了短期吞吐而失去权威来源;展示、报表和导出则可以按业务承诺降级。这样面试官能听到你先判断风险,再选择技术动作。
- 现象:排障不能只看一个红色指标。你会把接口 P99(99 分位响应时间)、错误率、连接池等待、慢 SQL(结构化查询语言)、锁等待、复制位置、磁盘队列和变更记录放进同一时间窗,并按租户、分片、接口和版本拆分,先确定影响面。
- 定位:使用真实但脱敏的参数核对执行计划、活跃事务、等待链和路由记录;同时检查重试、消息与外部回调是否放大压力。定位的目标是区分首因、放大器和受害者,不能因最醒目的告警就跳到结论。
- 根因:单一指标或单人操作不能解释级联故障,需要业务和技术同一时间线。 这说明数据库问题常是数据分布、访问模型、并发边界和故障策略共同作用的结果;需要说清楚机制如何把局部异常放大成用户可见问题。
- 处置:限购排队、关闭非关键读写和控制重试止血,再按热点、索引、事务与对账根治。 所有动作先在最小范围验证,保留停止条件、审计记录和回退路径;对于结果未知的外部副作用,先按业务幂等键查证,再决定补偿或重试,绝不凭超时直接重复执行。
- 复盘:验收同时覆盖性能恢复、数据不变量、复制健康和业务成功率,并以压测或回放证明可重复。最终把指标联动、保护开关、准入规则、演练和责任边界固化下来,避免下一次只能依赖人工经验。
复习清单
- 你能在十分钟内说清楚影响面、证据、止血顺序与升级条件。
- 你能用实际行数、扫描量和频次解释慢 SQL(结构化查询语言)的优先级。
- 你能区分锁等待、死锁、长事务、redo(重做日志)压力与复制延迟。
- 你能说明库存、支付、履约跨链路的幂等、补偿与对账闭环。
- 你能给出迁移和恢复的校验不变量、回退条件与演练证据。
