RDB 的触发方式
RDB 是某一时刻的内存全量快照,落盘为 dir 目录下、由 dbfilename 指定名字的二进制文件(默认 dump.rdb)。它的产生有三类来源:配置的 save 条件自动命中、显式执行 SAVE 或 BGSAVE、以及特定事件连带触发(正常停机、复制全量同步、调试重载)。排查「快照为什么在这个时间点发生」「磁盘为什么突然 IO 高」时,先分清是哪一类触发,比翻日志猜要快得多。
基本信息
| 自动触发 | save <秒> <变更数> 条件命中,任一组合满足即触发 |
|---|---|
| 手动触发 | BGSAVE 后台执行、SAVE 前台阻塞执行 |
| 路径与命名 | dir 指定目录、dbfilename 指定文件名,默认 dump.rdb |
| 事件触发 | SHUTDOWN 正常停机、主从全量同步、DEBUG RELOAD |
| 结果字段 | LASTSAVE 时间戳、INFO persistence 的 rdb_last_bgsave_status |
| 失败不重试 | BGSAVE 出错只写状态字段,没有监控就不会有第二次提醒 |
典型使用场景
- 日常持久化:靠 save 条件自动落快照,配合 AOF 覆盖不同恢复时间窗
- 发版或迁移留档:变更前手工 BGSAVE 一份,出问题可以回到明确的时间点
- 新从库首次同步:主库需要生成全量数据传给从库,此时主库磁盘与 CPU 会出现一次明显波动
- 停机维护:正常关停会自带一次快照,确认日志里的保存结果再动手
- 排查快照异常:用 LASTSAVE 判断距上次成功快照过了多久,用状态字段判断是否有失败
触发与核对
触发与核对
redis-cli CONFIG GET save # 查看当前自动快照条件
redis-cli CONFIG SET save "900 1 300 10" # 运行期调整,重启后失效,要写回配置文件
redis-cli BGSAVE # 后台快照,命令立即返回
redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|rdb_bgsave_in_progress|rdb_changes_since_last_save'
redis-cli LASTSAVE # 上次成功快照的 unix 时间戳
redis-cli INFO memory | grep used_memory_rss # 快照期间 RSS 会因写时复制短时上升
sudo tail -n 50 /var/log/redis/redis-server.log | grep -i 'saving\|background save'触发来源对照
| 来源 | 入口 | 阻塞情况 | 主要用途 |
|---|---|---|---|
| 自动条件 | save 配置行 | fork 瞬间停顿,之后不影响 | 常规持久化基线 |
| 手动后台 | BGSAVE | 仅 fork 瞬间停顿 | 变更前留档、临时备份 |
| 手动前台 | SAVE | 全程阻塞主线程 | 仅停机维护或离线导出 |
| 正常停机 | SHUTDOWN | 停服过程本身不可用 | 关停时保留最后一份快照 |
| 复制全量同步 | 从库接入触发主库快照 | 主库 fork 加磁盘与带宽开销 | 新从库首次拉取全量数据 |
| 调试重载 | DEBUG RELOAD | 阻塞 | 验证快照能否被正确加载 |
save 条件里的变更数是「自上次成功快照以来的写入次数」,包含过期删除等内部变更,不是累计写入量;秒数与变更数两个条件是与关系,多个 save 组合之间是或关系。写入很稀疏的实例可能几个小时都凑不满一个条件,这个时间窗是否可接受要和业务对一遍丢失容忍度。
磁盘写满、fork 失败、内存不足都会让 BGSAVE 静默失败,只把结果写进 rdb_last_bgsave_status。没有针对这个字段的告警,实例可以带着几天前的旧快照一直运行,直到真正需要恢复时才发现没有可用数据。