持久化失败为何拒绝写入
Redis 把「存不下来」当成严重状态:RDB 保存失败时,默认的 stop-writes-on-bgsave-error yes 会让写命令返回 MISCONF 错误;AOF 写入失败时同样会拒绝写入并把状态字段置为 err。应急处置的目标不是让报错消失,而是让实例回到「能写且真正落盘」的状态。
基本信息
| 常见诱因 | 磁盘写满、目录权限变化、挂载被覆盖、底层 IO 报错 |
|---|---|
| 观察字段 | rdb_last_bgsave_status、aof_last_write_status、rdb_last_save_time |
| 默认行为 | stop-writes-on-bgsave-error yes 时快照失败会禁写 |
| 恢复判据 | 状态字段回到 ok,且手动快照或重写成功一次 |
应急处理顺序
- 定位:df -h 看挂载、du -sh 找占用目录,分清是 AOF 目录还是快照文件吃满空间
- 查句柄:df 显示满而 du 不涨,多半是已删除但仍被进程占用的文件,用 lsof +L1 找出来
- 止血:扩容、迁移持久化目录,或清理确认可安全删除的旧备份与日志
- 恢复写入:确认状态字段回到 ok,而不是先关掉写保护掩盖错误
- 善后:安排一次重写与快照,把失败期间积压的内容补齐并复核磁盘水位
排查命令
排查命令
df -h /data # 看挂载是否真的满了
du -sh /data/redis/* | sort -h # 定位是哪个目录占用大
lsof +L1 2>/dev/null | head # 找出已删除但仍占空间的句柄
redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|aof_last_write_status'
redis-cli INFO persistence | grep -E 'rdb_last_save_time|aof_current_size'
dmesg | tail -20 # 排除 IO 错误与文件系统异常状态字段怎么读
| 字段 | 含义 | 异常时的动作 |
|---|---|---|
| rdb_last_bgsave_status | 最近一次快照的结果 | err 表示快照失败,清出空间后手动 BGSAVE 验证 |
| aof_last_write_status | 最近一次 AOF 写入的结果 | err 表示写入失败,此时写命令会被拒绝 |
| rdb_last_save_time | 上次成功保存的时间戳 | 长时间不更新说明保存一直没成功 |
| aof_last_bgrewrite_status | 最近一次重写的结果 | err 需在空间充足后重新执行重写 |
把 stop-writes-on-bgsave-error 改成 no,或者干脆关掉持久化,只是让报错停下来:数据依旧没有落盘,此时重启实例还会以最后一次成功的快照启动,丢掉故障期间的全部写入。
迁移持久化目录是有停机成本的变更:先确认目标目录的属主与权限和服务账号一致、空间足够,重启后核对加载来源与 DBSIZE,再放业务写入。