Files
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

261 lines
16 KiB
JSON
Raw Permalink 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": "redis-persistence",
"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": [
"AOF",
"持久化",
"Redis"
],
"question": "什么是 AOF 持久化?它记录『什么类型的信息』(命令还是数据状态),重启后如何恢复数据?",
"answer": "AOF(Append Only File)是 Redis 的持久化机制之一:每一条写命令(如 SET/LPUSH/INCRBY)以 RESP 协议格式追加写入一个 aof 文件中。它记录的是『写命令(操作)』,而不是『数据的最终状态』。重启恢复时,Redis 读取 AOF 文件,从第一条命令开始按顺序逐条重新执行(重放),把命令再次应用到空的内存数据库,最终恢复到崩溃/关闭前的一致状态。",
"keywords": [
"写命令",
"追加",
"重放",
"RESP"
],
"scoring_rubric": "①答出记录写命令而非数据状态得 2 分;②答出追加写入得 1 分;③答出重启后从头顺序重放命令恢复得 2 分。",
"explanation": "AOF 区别于 RDB 的本质:记录『操作』不记录『状态』,靠重放而非读快照。这是理解 AOF 重写、命令可压缩的基础。",
"source": null,
"related": []
},
{
"id": "sa-002",
"type": "short_answer",
"difficulty": 2,
"tags": [
"AOF",
"RDB",
"对比",
"选型"
],
"question": "RDB 快照和 AOF 日志在数据安全性、恢复速度、文件大小三方面各有什么特点?如何取舍?",
"answer": "RDB(快照):存定时的全量快照,文件小、恢复快、加载快;但两次快照间隔若宕机,会丢失这段数据,安全性相对低。\nAOF(日志):存追加命令,数据更安全(丢失窗口可压到 appendfsync 粒度),但文件随命令增长、恢复需逐条重放所以较慢;自动重写可压缩体积。\n取舍:能容忍少量丢失、求恢复快文件小用 RDB;数据必须尽量不丢(如秒杀成交、订单)用 AOF 甚至 always;生产通常 RDB + AOF 混合兼顾。",
"keywords": [
"RDB",
"AOF",
"安全性",
"恢复速度",
"文件大小",
"混合"
],
"scoring_rubric": "①正确列出 RDB/AOF 在数据形式与安全性差异得 2 分;②恢复速度、文件大小差异得 2 分;③给出取舍得 1 分。",
"explanation": "RDB=状态快照、AOF=命令日志。安全、恢复速度、文件大小三维度对比是持久化选型的核心题。",
"source": null,
"related": []
},
{
"id": "sa-003",
"type": "short_answer",
"difficulty": 3,
"tags": [
"AOF重写",
"压缩",
"状态快照"
],
"question": "从数据结构角度解释:AOF 为什么可『压缩』?重写到底改变哪些内容,本质是什么转换?",
"answer": "因为 AOF 是『命令序列』(log 结构),同一个 key 的多次写命令只有最后一次才决定其最终状态,早期命令基本可被覆盖/丢弃。例如 SET a=1 → SET a=2 → SET a=3 共存时,只有最后一条有意义;被 DEL 的 key 连任何命令都不需要。大量历史命令对恢复最终状态是冗余的,这才有压缩空间。\n\nAOF 重写(BGREWRITEAOF)的本质:不复用旧命令,而是遍历当前内存数据库的键值状态,为每个 key 重新生成一条『重建其最终值』的最小命令,生成一份新文件替换旧文件。这相当于把『命令序列 / 操作日志』等价转换为『键值状态快照』——丢弃所有可被最终状态覆盖的中间命令,文件从『随命令无限膨胀的命令日志』压缩成『接近最终状态的快照』。",
"keywords": [
"命令冗余",
"只看最终值",
"状态快照",
"BGREWRITEAOF",
"遍历内存",
"最小命令"
],
"scoring_rubric": "①说明 AOF 是命令序列、大量中间命令冗余可被覆盖得 2 分;②说出重写遍历当前内存为每个 key 生成最小重建命令、把命令序列转成状态快照得 3 分。",
"explanation": "这是『AOF 为何可压缩』的核心。关键在于『log(命令时间线)→ 状态快照』的数据结构切换,丢弃被覆盖的冗余命令使文件变小。",
"source": null,
"related": []
},
{
"id": "sa-004",
"type": "short_answer",
"difficulty": 2,
"tags": [
"binlog",
"AOF",
"对应关系",
"日志对比"
],
"question": "常说 Redis 的 AOF 相当于 MySQL 的 binlog,这个类比哪里对、哪里不完全对?",
"answer": "对的地方:二者都是记录『写操作』的追加日志,都可以通过重放/执行日志恢复数据,都是持久化与复制的载体。\n不完全对的地方:\n1. 定位与服务对象——binlog 主要服务主从复制、逻辑备份、PITR(时间点恢复)、审计,是 Server 层、可跨引擎;AOF 主要服务 Redis 自身持久化与崩溃恢复。\n2. 时间点恢复能力——binlog 原生支持 --start-position/--stop-position(字节精确)与 --start/--stop-datetime(时间近似),可直接做 PITR;AOF 无原生精确到历史某个事务位置的时间切片重放工具,需要手动截断,所以『回到任意历史时刻』对 AOF 是近似/需手工的。\n3. 记录粒度——binlog 记录 SQL(statement)或行变更(row),而 AOF 记录命令(RESP)。",
"keywords": [
"写操作日志",
"重放恢复",
"binlog",
"AOF",
"PITR",
"position",
"行变更",
"RESP"
],
"scoring_rubric": "①答出两者都是写操作日志、可重放恢复得 2 分;②指出 binlog 服务主从/PITR、AOF 服务自身持久化得 1 分;③指出 binlog 原生支持 position 切片、AOF 需手动截断得 1 分。",
"explanation": "类比对在对『都是写操作日志、可重放恢复』,不完全对在服务对象与时间点恢复能力(binlog 位点精确、AOF 需手工)。",
"source": null,
"related": []
},
{
"id": "sa-005",
"type": "short_answer",
"difficulty": 2,
"tags": [
"binlog",
"redo log",
"日志",
"MySQL"
],
"question": "MySQL 中 binlog 与 redo log 有什么区别?分别是『什么时候用』?",
"answer": "本质区别:\n- redo log:InnoDB 引擎内部自己用,记录物理页变更,目的是崩溃恢复、保证已提交事务数据不丢(WAL 重放);是固定大小环形缓冲。\n- binlog:MySQL Server 层产生,记录 SQL 或行变更,供主从复制、PITR、CDC、审计使用。\n\n什么时候用:关注崩溃数据不丢、恢复一致性 → 涉及 redo 机制与配置;主从复制、误删恢复到某时间点、把变更同步到外部系统(Canal 等)、审计 → 用 binlog。一句话:redo 是引擎内层『保底不丢』,binlog 是对外扩散/复制/审计层。",
"keywords": [
"redo log",
"binlog",
"崩溃恢复",
"主从",
"PITR",
"Server层",
"物理页"
],
"scoring_rubric": "①答出 redo 记录物理变更、引擎内用于崩溃后重放得 1 分;②答出 binlog 记录 SQL/行变更、用于主从/PITR/审计得 2 分;③说清两种场景分别用哪个日志得 2 分。",
"explanation": "redo 是引擎级崩溃恢复日志,binlog 是 server 级对外扩散日志,服务对象与场景截然不同的 ESR 是核心。",
"source": null,
"related": []
},
{
"id": "sa-006",
"type": "short_answer",
"difficulty": 3,
"tags": [
"redo",
"环形",
"不膨胀",
"覆盖"
],
"question": "为什么 redo log 采用『固定大小环形缓冲』而不像 AOF 那样无限追加?覆盖不影响数据安全由什么保证?",
"answer": "redo log 是物理日志,只服务于崩溃恢复,因此容量可以固定:它采用固定大小的环形缓冲循环写入,写到末尾就回到开头覆盖最旧的记录,空间天然可控,不会像 AOF 那样随写入量无限膨胀,也就不需要 AOF 那种显式的重写压缩。\n\n覆盖之所以不影响数据安全,关键在于 checkpoint 机制:一条 redo 记录只有在它对应的脏页已经刷到磁盘之后才允许被覆盖——因为页已落盘,崩溃后不再需要这条 redo 来重做。checkpoint 会随脏页刷盘不断向前推进,推进点之前的空间才可复用。若写入速度过快、redo 快要追上 checkpoint,InnoDB 会强制推进刷脏页(表现为线上偶发的写入抖动),从而保证绝不覆盖尚未落盘的记录。",
"keywords": [
"redo log",
"环形缓冲",
"固定大小",
"checkpoint",
"脏页刷盘",
"物理日志"
],
"scoring_rubric": "总分 5 分:答出 redo 是固定大小环形缓冲、写满循环覆盖所以不膨胀、无需显式重写得 2 分;答出覆盖安全由 checkpoint 保证(对应脏页已刷盘才允许覆盖)得 2 分;答出 redo 追上 checkpoint 时会强制刷脏页得 1 分。",
"source": null,
"related": [],
"explanation": "redo 之所以不膨胀,根本在于它是物理日志且容量固定:环形缓冲写满就回到开头覆盖,空间天然可控。而覆盖不破坏安全性靠 checkpoint——只有对应脏页已刷盘,该 redo 记录才允许被覆盖,因为崩溃后已不需要它重做。若 redo 快追上 checkpoint,InnoDB 会强制刷脏页(表现为写入抖动)。"
},
{
"id": "sa-007",
"type": "short_answer",
"difficulty": 3,
"tags": [
"binlog",
"AOF",
"PITR",
"时间点恢复",
"position"
],
"question": "『可以回到有记录的任意时间节点』这句话,对 binlog 和 AOF 各成立到什么程度?请从精确性说明区别。",
"answer": "对 binlog:基本成立且是核心能力之一。binlog 每条事务都有文件号+offset(position),mysqlbinlog 支持 --start-position/--stop-position(字节精确),也可用 --start/--stop-datetime(时间近似)。配合全量备份可拼到准确的任意历史提交点;位置比时间更精确,并能停在一个完整事务边界。对 AOF:只能说『大致能回到某时刻,但需手动截断文件再重放』。AOF 本质是『从头到尾顺序重放』,命令没有内建可精确到某个事务边界的切片重放接口,因此要从历史某一刻恢复需人工截断,不是像 binlog 那样原生精确到 position 并重放到那儿。",
"keywords": [
"binlog",
"AOF",
"PITR",
"position",
"手动截断",
"从头重放"
],
"scoring_rubric": "①对 binlog 说明支持 position/时间切片、可精确 PITR 得 2 分;②对 AOF 说明默认从头到尾重放、缺原生精准切片、需要手动截断得 3 分。",
"explanation": "区别核心:binlog 有【文件+position】原生精确切片,AOF 是顺序重放日志、缺 position/时间片切入命令,需人为兜底。",
"source": null,
"related": []
},
{
"id": "sa-008",
"type": "short_answer",
"difficulty": 2,
"tags": [
"InnoDB成",
"WAL",
"redo log",
"持久性"
],
"question": "什么是 WAL(Write-Ahead Logging)?MySQL InnoDB 为什么『先写 redo log 再落数据页』?",
"answer": "WAL(预写日志)核心:先提交前先把『本次修改对应的日志』写到磁盘,再做数据页修改。InnoDB 的做法:事务的 UPDATE 先记一条 redo 并 fsync 落盘(WAL),数据页先缓存内存 Buffer Pool,延迟刷盘;redo log fsync 之后 COMMIT 才算成功。好处:①顺序写比随机写快,redo 顺序 append、数据页随机刷,用顺序写低开销换持久性;②崩溃后重放 redo 把未落盘的已提交事务补上,保证失败不丢。本质:日志先行落盘,数据页延迟落盘,『已提交不丢』由日志而非页面落盘保证。",
"keywords": [
"WAL",
"先写日志",
"Buffer Pool",
"顺序写",
"崩溃恢复一",
"持久性"
],
"scoring_rubric": "①解释 WAL 是先写日志再写数据页得 2 分;②顺序写更快为何延迟刷得 1 分;③崩溃后重放 redo 保证已提交不丢得 2 分。",
"explanation": "WAL 是 InnoDB 持久性核心:COMMIT 只刷 redo log(顺序写),数据页由 Buffer Pool 管理、量通过同盘,崩溃重放。",
"source": null,
"related": []
},
{
"id": "sa-009",
"type": "short_answer",
"difficulty": 3,
"tags": [
"innodb_flush",
"AOF",
"appendfsync",
"同步配置对比"
],
"question": "对比 MySQL innodb_flush_log_at_trx_commit 与 Redis appendfsync:各自取值与『安全 / 性能』取舍?",
"answer": "innodb_flush_log_at_trx_commit(MySQL):0=提交由系统定时批量刷,性能最高、进程崩溃可能丢最近数据;1(默认)=每次提交 fsync redo,最安全、性能最低;2=每次提交写 OS 写缓存不 fsync,由 OS 稍后刷,进程崩溃不丢但 OS 宕机丢,性能居中。\nappendfsync(Redis AOF):always=每条写命令 fsync,丢失最少、性能最差;every每秒=每秒 fsync,最多丢 1 秒、性能/安全平衡(默认);no=交给 OS,性能最好、安全最差。\n两者思想一致:用一个刷盘频率旋钮权衡『实时安全(慢)』与『批量(快)』。",
"keywords": [
"innodb_flush_log_at_trx_commit",
"0/1/2",
"appendfsync",
"always/everysec/no",
"fsync"
],
"scoring_rubric": "①列出 innodb_flush 三个值并说明取舍各等 1 分(共 2-3 分);②列出 append 三个值并取舍(2 分);③点明两者都是安全/性能权衡得 1分。",
"explanation": "二者分别对应 MySQL redo、Redis AOF 的 fsync 策略,核心是『每次提交是否立刻刷盘』带来的安全/性能权衡。",
"source": null,
"related": []
},
{
"id": "sa-010",
"type": "short_answer",
"difficulty": 4,
"tags": [
"AOF",
"binlog",
"redo",
"时间点恢复",
"综合"
],
"question": "用『记录内容、主要使用者/场景起落、覆盖/追加结构、是否便于时间点恢复』四个维度对 AOF、binlog、redo log 做横向对比。",
"answer": "1. 记录内容:AOF 记 Redis 写命令(RESP);binlog 记 MySQL SQL(statement)或行变更(row);redo 记 InnoDB 物理页变更。\n2. 使用者/场景:AOF → Redis 持久化与崩溃恢复;binlog → 主从、PITR、CDC、审计(Server 层可跨引擎);redo → InnoDB 崩溃恢复、WAL。\n3. 记录结构:AOF 追加 append、可主动重写(压缩成状态快照);binlog 追加文件、靠 rotate+过期清理不主动压成快照;redo 环形覆盖已落盘记录、天然不膨胀也无需重写。\n4. 时间点恢复:AOF 从头顺序重放、无原生切片需手工截断;binlog 支持 position/时间、可直接做 PITR;redo 面向崩溃重放到当前、不用于历史时间点恢复。",
"keywords": [
"AOF",
"binlog",
"redo log",
"记录内容",
"使用者",
"覆盖",
"环形",
"append",
"PITR"
],
"scoring_rubric": "四维度各约等 1.25 分。要点:AOF 命令日志可显式重写、binlog 带 position 可用于 PITR、redo 物理环形覆盖用于崩溃重放。",
"explanation": "横向比较最综合。四组:记录内容、对象/场景、覆盖方式、时间点恢复能力。",
"source": null,
"related": []
}
]
}