{ "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": [] } ] }