515acbcc7f
Deploy Examination / deploy (push) Successful in 4s
- 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 校验
229 lines
12 KiB
JSON
229 lines
12 KiB
JSON
{
|
||
"topic": "redis-persistence",
|
||
"type": "single_choice",
|
||
"schema_version": "1.0.0",
|
||
"generated": "2026-09-07T00:00:00+08:00",
|
||
"questions": [
|
||
{
|
||
"id": "sc-001",
|
||
"type": "single_choice",
|
||
"difficulty": 1,
|
||
"tags": [
|
||
"Redis",
|
||
"持久化",
|
||
"AOF",
|
||
"RDB"
|
||
],
|
||
"question": "Redis 的 AOF(Append Only File)与 RDB(快照)两种持久化方式,下列说法正确的是?",
|
||
"options": {
|
||
"A": "AOF 每隔固定时间做一次全量内存快照,文件小、重启加载快",
|
||
"B": "RDB 记录每条写命令文本,重启时依次重放命令来恢复数据",
|
||
"C": "AOF 通过记录每条写命令文本并在重启后重放来恢复数据;RDB 是定时全量快照",
|
||
"D": "RDB 与 AOF 都记录的是写命令序列,二者唯一的区别是文件格式文本/二进制"
|
||
},
|
||
"answer": "C",
|
||
"explanation": "AOF(Append Only File)的本质是把每条写命令按序追加到文件,重启后从文件头部开始按顺序重放这些命令恢复内存数据;RDB 则是把某个时刻的完整键值对状态序列化成一个体积较小、重启加载更快的二进制快照文件,两次快照之间写入的数据在宕机时会丢失。A 把 AOF 说成快照、B 把 RDB 说成命令重放、D 声称二者都记录命令,均错误;C 准确描述了二者差异。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-002",
|
||
"type": "single_choice",
|
||
"difficulty": 1,
|
||
"tags": [
|
||
"Redis",
|
||
"持久化",
|
||
"RDB"
|
||
],
|
||
"question": "下列关于 RDB(快速文件快照)持久化的说法,错误的是?",
|
||
"options": {
|
||
"A": "RDB 生成的是某时刻内存键值状态的全量快照文件",
|
||
"B": "RDB 文件尺寸更小,重启后加载恢复速度远快于重放海量 AOF 命令",
|
||
"C": "RDB 采用定时触发,两次快照之间发生的写操作在宕机后会丢失",
|
||
"D": "RDB 会记录下每一条写命令,因此始终能恢复到任意一条指令级时刻"
|
||
},
|
||
"answer": "D",
|
||
"explanation": "RDB 是内存状态的定时快照,只保存某个格式点时刻的全量数据,两次快照之间写入的数据在宕机时确实会丢失(C 正确)。其文件小、重载快(B 正确),保存的是状态本身而非命令序列(A 正确)。D 中“记录每一条写命令”是 AOF 的隐式,RDB 并无命令级别的恢复能力,因此 D 是错误说法。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-003",
|
||
"type": "single_choice",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"Redis",
|
||
"AOF",
|
||
"AOF重写",
|
||
"状态快照",
|
||
"命令序列"
|
||
],
|
||
"question": "AOF 重写(Rewrite / BGREWRITEAOF)的核心本质是什么?",
|
||
"options": {
|
||
"A": "把追加文件里的命令逐条压缩成更短的命令,仍然是命令序列",
|
||
"B": "把命令序列重新生成为键值(状态快照)的等价描述,丢弃大量被最终值覆盖的中间命令,文件因此被“压缩”",
|
||
"C": "将 AOF 文件按时间切片,只保留最近一天的写命令",
|
||
"D": "把 AOF 与 RDB 混合份成一个文件,以便同时利用两者优势"
|
||
},
|
||
"answer": "B",
|
||
"explanation": "AOF 重写的本质是“状态快照 vs 命令序列”的转换:它扫出当前内存里每个 key 的最终值,只生成恢复这些极简值所需的最小命令集(如直接 SET / RPUSH),把大量被后续命令覆盖的中间命令丢弃,从而大幅缩小文件。它并非简单的压缩/截断/混用 RDB,故 B 正确,A、C、D 均偏离本质。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-004",
|
||
"type": "single_choice",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"Redis",
|
||
"AOF",
|
||
"AOF重写"
|
||
],
|
||
"question": "有一段 AOF 命令流:SET k 1;INCRBY k 5;DEL k;SET k 9。执行 AOF 重写后,恢复同样状态的最小等价命令序列最可能是?",
|
||
"options": {
|
||
"A": "SET k 1; SET k 6; DEL k; SET k 9",
|
||
"B": "SET k 9; INCRBY k 0",
|
||
"C": "只保留 SET k 9",
|
||
"D": "SETDEL: 只保留 DEL k"
|
||
},
|
||
"answer": "C",
|
||
"explanation": "重写生成的是能重建当前内存状态的命令,mid 命令(SET k a、INCR k 5、DEL k)都被最终结果 k=9 覆盖/湮灭,因此只需保留末尾写 k=9 的 SET 即可。A、B 保留冗余中间命令不符合“最小等价”目标,D 错误因为最终 play 值应为 9 而非删除。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-005",
|
||
"type": "single_choice",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"AOF",
|
||
"binlog",
|
||
"追加日志",
|
||
"重放",
|
||
"复制"
|
||
],
|
||
"question": "关于 Redis AOF 与 MySQL binlog 的对应关系,下列说法正确的是?",
|
||
"options": {
|
||
"A": "两者都只记录物理页的最终状态,且都天然支持到任意事务时刻的点恢复",
|
||
"B": "两者都属于记录写操作并可重放的逻辑追加日志,但 binlog 支持原生时间/位置切片点,AOF 没有,需要手动截断文件来定点重放",
|
||
"C": "AOF 是物理日志而 binlog 是逻辑日志,二者原理完全不同",
|
||
"D": "binlog 不具备重放能力,只是改库主从同步的审计文件"
|
||
},
|
||
"answer": "B",
|
||
"explanation": "AOF 与 binlog 都按追加的方式,把写操作记录成可回放的重放日志(statement/row)后者。binlog 提供 --start-position/--stop-position 精确位点与 --start/--stop-datetime 近似时间来点恢复(PITR 核心工具);AOF 没有原生的按时间点切片重放能力,要回到过去某个时刻,通常需要手动根据 appendfile 做截断后再重放。B 正确。C 误把 AOF 当物理日志,D 假言 binlog 不可重放,均错误。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-006",
|
||
"type": "single_choice",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"AOF",
|
||
"redo log",
|
||
"binlog",
|
||
"物理日志",
|
||
"一致"
|
||
],
|
||
"question": "相比 binlog 的 statement/row 逻辑格式,InnoDB 的 redo log 之所以是物理日志,是因为它记录的是?",
|
||
"options": {
|
||
"A": "每条 SQL 语句的完整文本,用于主从重放",
|
||
"B": "某个事务提交的行级前后镜像(before/after 值),用于回滚",
|
||
"C": "已提交事务可能修改过的页面、页号与偏移位置的增量变更,描述“物理页的最终状态变化”",
|
||
"D": "对数据库数据的完整状态快照(类 BTCA 快照)"
|
||
},
|
||
"answer": "C",
|
||
"explanation": "redo log 记录的是对数据页物理层面的连续变更:哪个页(页号/偏移)、哪些字节被改成了什么,属于“逻辑日志”的物理状态。它不记录 SQL 文本(那是 binlog statement),不记录行 before/after 镜像(那是 undo log 的回滚图),也不做全量状态快照(RDB 的职责)。崩溃恢复依靠 redo 进行前向重做,C 正确。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-007",
|
||
"type": "single_choice",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"redo log",
|
||
"环形缓冲",
|
||
"追加日志"
|
||
],
|
||
"question": "InnoDB 的 redo log 采用固定大小环形缓冲结构,因此它天然不会无限膨胀,其根本原因是?",
|
||
"options": {
|
||
"A": "它定期把日志导出到外部保存,磁盘满了就丢弃最旧日志",
|
||
"B": "环形固定大小,允许覆盖旧页,旧页写盘后再循环复用,旧记录被隐式覆盖弃——无需显式“压缩/重写”",
|
||
"C": "只允许写入固定字节数后强制关闭数据库要求人工清理",
|
||
"D": "InnoDB 每一条 redo 记录都写成后来会话内的最终状态,不再产生新日志"
|
||
},
|
||
"answer": "B",
|
||
"explanation": "redo log 被设计成固定大小的循环(circular)缓冲:数据页在检查点后已写入磁盘,其对应日志就允许被覆盖,环形缓冲因此不断循环倒约 map 同一块存储空间,永远只占固定磁盘空间,不需要像 AOF 那样显式重写压缩(BG技术重写)。这就是“隐式覆盖” vs AOF“显式重写合并”的核心差别。B 正确。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-008",
|
||
"type": "single_choice",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"AOF",
|
||
"redo log",
|
||
"AOF重写",
|
||
"环形缓冲"
|
||
],
|
||
"question": "关于 AOF 与 InnoDB redo log 在“日志膨胀控制”上的时机差异,正确的是?",
|
||
"options": {
|
||
"A": "两者都靠固定大小环形缓冲天然防膨胀,无需任何压缩",
|
||
"B": "redo 靠固定大小环形覆盖旧页隐式防止膨胀;AOF 是追加式命令日志,会持续放大,需要显式手动/触发 AOF 重写(BGREWRITEAOF)合并压缩",
|
||
"C": "AOF 一经开启就自动压缩命令,从不会膨胀;redo 反而会无限增长",
|
||
"D": "两者都靠定时全量快照替代全部日志才能防膨胀"
|
||
},
|
||
"answer": "B",
|
||
"explanation": "AOF 追加记录的是命令序列,随写操作无限累积,只有通过显式重写(rewrite)把命令序列重实为等价的状态快照才能缩小文件;而 redo 位于固定大小的环形缓冲内,旧页写入盘后即可被覆盖复用,系统隐式防膨胀。因此“隐式覆盖 vs 显式重写合并”是二者膨胀控制时机的核心差异,B 正确。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-009",
|
||
"type": "single_choice",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"AOF",
|
||
"binlog",
|
||
"重放",
|
||
"互斥"
|
||
],
|
||
"question": "要让 MySQL 通过 binlog 精确回放到某个事务提交的物理写入点,首选工具与参数是?",
|
||
"options": {
|
||
"A": "使用 mysqldump 全备份并重灌,配合 --secondary-drop-root",
|
||
"B": "用 mysqlbinlog --start-position/--stop-position 定位 binlog 文件位置精确回放,或用 --start/--stop-datetime 按时间近似回放",
|
||
"C": "直接重放 redo log 环形缓冲即可定位到任意事务",
|
||
"D": "仅靠 undo log 回滚未提交事务就能精确到物理点"
|
||
},
|
||
"answer": "B",
|
||
"explanation": "binlog 是 MySQL 按位置(pos)与时间组织的事件流,mysqlbinlog 的 --start-position/--stop-position 可精确到事件字节位置,--start/--stop-datetime 提供近似时间点,是点恢复(PITR,Point-In-Time Recovery)核心工具。A 是全备份非精确位点;C 的 redo 是环形覆盖记录,只用于崩溃恢复前向重做,不能指定任意历史点;D 的 undo 只负责回滚未提交事务,B 正确。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "sc-010",
|
||
"type": "single_choice",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"AOF",
|
||
"binlog",
|
||
"undo log",
|
||
"一致",
|
||
"恢复"
|
||
],
|
||
"question": "MySQL 崩溃恢复时,redo log 与 undo log 的分工关系是?",
|
||
"options": {
|
||
"A": "只用 undo log 把已提交数据全部回滚到事务前状态",
|
||
"B": "redo log 对未写入物理页的已提交事务做前向重做,undo log 回滚尚未提交的事务,二者是物理重做/滚两阶段恢复的前提,配合保证恢复后一致性",
|
||
"C": "redo 用于逻辑回滚,undo 用于物理前向重做",
|
||
"D": "崩溃恢复完全依赖 AOF 重放命令,redo/undo 只在宕机前起作用"
|
||
},
|
||
"answer": "B",
|
||
"explanation": "崩溃恢复遵循两条线索:对已经 commit 但脏页尚未落盘的事务,用 redo log 前向重做其物理页变更使其最终持久化;对尚未 commit 的事务,用 undo log 回滚已写入页中的部分改动,保证其最终被撤销。因此 redo 重做已提交 + undo 回滚未提交,配合完成恢复后的一致性与持久性,B 正确。",
|
||
"source": null,
|
||
"related": []
|
||
}
|
||
]
|
||
} |