Files
examination/topics/database/mysql-acid/short_answer.json
T
wonder 515acbcc7f
Deploy Examination / deploy (push) Successful in 4s
feat: add database topic group with 105 questions
- mysql-acid (35): undo/redo log, WAL, 崩溃恢复三阶段, 两阶段提交
- mysql-transaction-isolation (35): 四隔离级别, 三异常, Read View, 快照读/当前读, next-key lock
- redis-persistence (35): RDB/AOF/混合持久化, AOF 重写, vs binlog/redo log
- 每子主题: single_choice×10 + fill_blank×10 + short_answer×10 + code_reading×5
- 全部通过 question.schema.json 校验
2026-09-07 19:17:38 +08:00

241 lines
12 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"topic": "mysql-acid",
"type": "short_answer",
"schema_version": "1.0.0",
"generated": "2026-09-07T00:00:00+08:00",
"questions": [
{
"id": "sa-001",
"type": "short_answer",
"difficulty": 2,
"tags": [
"ACID",
"原子性",
"undo log",
"InnoDB"
],
"question": "解释 InnoDB 如何用 undo log 实现事务的原子性(回滚)。",
"answer": "InnoDB 在每个事务执行写操作时,先把旧值(修改前的数据)写入 undo log。若事务需要回滚或崩溃恢复时确定未提交,InnoDB 依据 undo log 中记录的旧值做逆操作:INSERT 对应 DELETE 反操作、DELETE 对应重新插入、UPDATE 则把新旧值互换改回,从而把数据恢复到事务开始前的状态。整个事务要么全部提交要么全部回滚,即为原子性。",
"keywords": [
"undo log",
"旧值",
"逆序回滚",
"原子性"
],
"scoring_rubric": "总分 4 分:说明修改前写 undo log(2 分);说明用旧值逆序回滚(2 分)。",
"explanation": "核心是“记录旧值 + 逆操作回滚”。答出 undo log 记录旧值、支持把数据恢复到事务前状态即可得分。",
"source": null,
"related": []
},
{
"id": "sa-002",
"type": "short_answer",
"difficulty": 3,
"tags": [
"持久性",
"redo log",
"WAL",
"InnoDB"
],
"question": "什么是 Write-Ahead Logging(WAL)?它在 MySQL InnoDB 中如何保证持久性?",
"answer": "WAL 指“先写日志再写数据”:任何数据页的修改在落盘之前,必须先把对应的 redo log 记录写入磁盘并持久化。InnoDB 修改 Buffer Pool 中的页时会先向 redo log 追加物理变更;事务提交时确保该 redo 已写入磁盘(fsync,或按 innodb_flush_log_at_trx_commit 决定)。若在数据页落盘前崩溃,重启时通过扫描并重放 redo log,把已提交事务的修改恢复到数据文件,因此已提交数据不会丢失,从而保证持久性。",
"keywords": [
"WAL",
"先写日志再写数据",
"redo log",
"重放恢复",
"持久性"
],
"scoring_rubric": "总分 4 分:给出 WAL 定义“先写日志后写数据”(2 分);说明崩溃重放 redo 恢复(1 分);结合 InnoDB 描述(1 分)。",
"explanation": "先陈述 WAL 的顺序要点,再联系 redo log 在这次重放(redo)与 fsync 的细节,符合本主题核心理解。",
"source": null,
"related": []
},
{
"id": "sa-003",
"type": "short_answer",
"difficulty": 3,
"tags": [
"redo log",
"物理日志",
"undo log",
"逻辑日志"
],
"question": "对比 redo log 与 undo log 在记录内容(物理/逻辑)和作用上的区别。",
"answer": "两者差异如下:1)记录内容:redo log 是物理日志,记录了对哪个数据页哪一处的字节所做的实际修改;undo log 是逻辑日志,记录如何把一行数据“改回旧值”的逆操作。2)作用方向:redo 用于崩溃后重做(REDO)已提交事务,保证持久性;undo 用于回滚未提交事务(或 MVCC 提供历史版本)保证原子性与隔离读。redo 是能重做的物理重放,undo 是可逆回滚的逻辑逆操作。",
"keywords": [
"redo 物理",
"undo 逻辑",
"重做已提交",
"回滚未提交",
"崩溃恢复"
],
"scoring_rubric": "总分 4 分:redo 物理日志(1 分);undo 逻辑日志(1 分);redo 重做已提交(1 分);undo 回滚未提交(1 分)。",
"explanation": "分别从“物理 vs 逻辑”“重做 vs 回滚”两个维度对比,即可覆盖核心差异。",
"source": null,
"related": []
},
{
"id": "sa-004",
"type": "short_answer",
"difficulty": 4,
"tags": [
"崩溃恢复",
"redo log",
"undo log",
"InnoDB"
],
"question": "详细描述 InnoDB 崩溃恢复的三阶段流程。",
"answer": "第一阶段(扫描 redo log):从 redo 中确定本次恢复需要处理的 lSN 范围与 checkpoint 位置,找出需要重做的日志段。第二阶段(重做已提交事务):按 redo log 将崩溃前已提交但尚未刷盘到数据文件的数据页修改重新应用(redo ),使这些已提交的修改得到恢复。第三阶段(回滚未提交事务):通过两阶段提交记录的 xid 识别哪些事务未在 binlog 中完整提交,利用 undo log 把这些未提交事务的执行进行回滚,最终使数据库恢复到崩溃前一致、没有丢失已提交数据且无未提交改动残留的状态。",
"keywords": [
"扫描 redo",
"重做已提交",
"回滚未提交",
"两阶段提交",
"checkpoint"
],
"scoring_rubric": "总分 4 分:扫描 redo 确定范围(1 分);重做已提交事务(2 分);用 undo 回滚未提交(1 分)。",
"explanation": "按顺序答出重做/回滚的职责与对象判断(以两阶段提交/是否已提交为依据)即可。",
"source": null,
"related": []
},
{
"id": "sa-005",
"type": "short_answer",
"difficulty": 2,
"tags": [
"隔离性",
"MVCC",
"undo log",
"快照读"
],
"question": "MVCC 是什么?InnoDB 使用它如何提升并发隔离性?",
"answer": "MVCC(多版本并发控制)是 InnoDB 提供一致性非锁定读的机制:通过 undo log 维护每一行的多版本链。当普通 SELECT(快照读)执行时,InnoDB 依据事务的 ReadView(可见性判断)沿版本链找到当前事务可见版本,不需要加共享锁。这样多个读事务与写事务可并发执行,读不被写阻塞,从而在维持隔离性的前提下显著提升并发吞吐。",
"keywords": [
"MVCC",
"undo log 版本链",
"ReadView",
"一致性读",
"非锁读"
],
"scoring_rubric": "总分 3 分:给出 MVCC 定义(1 分);说明 undo 多版本 + ReadView(1 分);读不加锁、提升并发(1 分)。",
"explanation": "抓住“多版本链 + ReadView + 读不加锁”即可说明 MVCC 是如何提升并发也保隔离的。",
"source": null,
"related": []
},
{
"id": "sa-006",
"type": "short_answer",
"difficulty": 3,
"tags": [
"隔离性",
"行锁",
"间隙锁",
"next-key lock"
],
"question": "在可重复读(RR)隔离级别下,InnoDB 的 next-key lock(临键锁)如何防止幻读?",
"answer": "RR 下 InnoDB 对索引范围/查找会加 next-key lock(由行锁 + 间隙锁组成的左开右闭区间锁)。它既锁住命中的记录(行锁),又锁住记录之间的间隙(gap),阻止其他事务在该扫描区间内 INSERT 新行。因为在该被锁定的范围里不可能再插入新记录,当前事务多次查询同一范围结果一致,从而防止了幻读。",
"keywords": [
"next-key lock",
"gap lock",
"锁定区间",
"防幻读",
"RR"
],
"scoring_rubric": "总分 3 分:指出 next-key = 行锁 + 间隙锁(1 分);锁区间阻止插入(1 分);讲到幻读消除(1 分)。",
"explanation": "从一个锁出发:锁间区使别人无法插入,故范围查询结果稳定,防幻读。",
"source": null,
"related": []
},
{
"id": "sa-007",
"type": "short_answer",
"difficulty": 3,
"tags": [
"两阶段提交",
"redo log",
"binlog",
"一致性"
],
"question": "为什么 MySQL 需要用两阶段提交来协调 redo log 与 binlog?",
"answer": "因为同一条事务的修改既要写 redo log(用于崩溃恢复)又要写 binlog(用于复制与恢复),若没协调,崩溃可能发生在一个日志已写另一个未写的时刻,导致主库重放后与从库/恢复点不一致。两阶段提交通过 prepare(redo 先 prepare)+写 binlog+ commit(redo 标记)的划分,并在恢复时以“binlog 是否完整作为事务是否提交”的裁决,保证 redo 与 binlog 的已提交事务集合完全一致,杜绝主从数据不一致与 PITR 偏差。",
"keywords": [
"两阶段提交",
"prepare",
"binlog 为准",
"主从一致",
"xa"
],
"scoring_rubric": "总分 4 分:指出两份日志都需要(1 分);说明子过程 prepare/binlog/commit(1 分);说明以 binlog 为准裁决提交(2 分)。",
"explanation": "核心是“防止在日志中间崩溃造成两份日志事务集不一致”,并以 binlog 为裁决者。",
"source": null,
"related": []
},
{
"id": "sa-008",
"type": "short_answer",
"difficulty": 2,
"tags": [
"redo log",
"binlog"
],
"question": "redo log 与 binlog 各自的应用场景和作用是什么?",
"answer": "redo log 是 InnoDB 引擎层专用于崩溃恢复的重做日志(物理记录页修改);binlog 是 MySQL Server 层的逻辑日志,记录事务的逻辑变更,主要场景为主从复制(从库重放 binlog)、基于时间点/位置的恢复 PITR 及审计。redo 在崩溃恢复时让 InnoDB 持久化已提交数据,binlog 面向整个实例的外部同步与运维。",
"keywords": [
"redo 崩溃恢复",
"binlog 复制",
"PITR",
"审计"
],
"scoring_rubric": "总分 3 分:redo 崩溃重做(1 分);binlog 复制 PITR(1 分);指出层与外部区别(1 分)。",
"explanation": "从时间/层和用途三方面对比即可。",
"source": null,
"related": []
},
{
"id": "sa-009",
"type": "short_answer",
"difficulty": 3,
"tags": [
"一致性",
"约束",
"ACID"
],
"question": "解释在 InnoDB 中一致性(Consistency)是如何实现的,并说明它与 A、I、D 的关系。",
"answer": "一致性指事务保证数据从一致状态到一致的状态。InnoDB 通过约束(主键、唯一、非空、外键、CHECK 等)保证提交的数据满足完整性,同时一致性依赖于另三者:若原子性被破坏会造成部分写入,隔离性破坏可能读到中间态,持久性破坏会导致状态回退。只有当原子性(全提交或全回滚)、隔离性(并发不受互扰)、持久性(提交可恢复)三者共同成立,配合约束与业务逻辑,才能把已提交事务改变成一个整体一致的状态。",
"keywords": [
"约束",
"原子性",
"隔离性",
"持久性",
"一致状态"
],
"scoring_rubric": "总分 4 分:提到约束(1 分);A/I/D 各自如何维护一致(2 分);说明三者共同保证(1 分)。",
"explanation": "一致性不是一个独立机制,而是约束 + A/I/D 的协作者;答出三者影响一致性的链路即好。",
"source": null,
"related": []
},
{
"id": "sa-010",
"type": "short_answer",
"difficulty": 3,
"tags": [
"innodb_flush_log_at_trx_commit",
"持久性",
"性能"
],
"question": "对比 innodb_flush_log_at_trx_commit 取 (0/1/2) 三种值在持久性与性能上的取舍。",
"answer": "0:每秒刷一次 redo log 盘,性能直高但进程崩溃会丢近 1 秒已提交事务;1:每次提交都 fsync 刷盘,持久性最强、最安全,但磁盘同步 IO 开销大、提交延迟高;2:每次提交把 redo 写至 OS 缓存(write,不 fsync),MySQL 进程崩溃时数据不丢,但 OS 崩溃/断电可能丢近 1 秒数据,性能比起 1 明显更高、比 0 稍低。生产 Server 建议设置为 1(严格 ACID),对可容忍少量丢亦可 2/0 提升吞吐。",
"keywords": [
"0 每秒刷盘",
"1 每次 fsync",
"2 OS 缓存",
"持久性 vs 性能"
],
"scoring_rubric": "总分 4 分:0 语义与丢数据(1 分);1 语义持久性最强(1 分);2 写 OS 缓存语义(1 分);指出取舍与推荐(1 分)。",
"explanation": "三个取值逐一说明“何时同步 fsync”即可,再补充其与几种崩溃类型的对应关系。",
"source": null,
"related": []
}
]
}