首页/数据/数据库速查/BGSAVE 的 fork 与写时复制(COW)
Redis 运维与场景124 条

BGSAVE 的 fork 与写时复制(COW)

BGSAVE 靠 fork 复制页表 + 写时复制:内存页被改写时才复制,所以写入量大时 COW 内存峰值会接近翻倍。

数据库速查数据更新于 2026-10-13

fork 与写时复制是什么

后台快照靠派生一个子进程完成:子进程与父进程共享同一份内存页,只有当某一页被改写时才复制一份给子进程(写时复制)。因此快照期间写入越频繁,额外复制的内存越多,峰值内存可能接近翻倍;内存越大的实例,派生本身的停顿也越明显。

基本信息

派生耗时与页表规模相关,大内存实例可达数百毫秒
写时复制放大快照期间写入越多,被复制的页越多
关键指标最近一次派生耗时、写时复制体积、内存峰值
透明大页开启时会显著放大派生与复制开销,通常建议关闭
内存预留上限要留出足够余量,避免快照期间触发交换或被杀

典型使用场景

  • 周期性延迟尖刺排查:定时快照导致的毫秒级停顿是常见来源
  • 快照策略调整:把快照集中到低峰,或交由从库承担
  • 实例规格评估:按峰值内存而不是当前内存规划容量
  • 透明大页治理:确认系统层面已关闭,避免放大开销
  • 大规模写入期间的快照冲突:批量导入时主动错开快照时间

观察派生与快照开销

观察派生与快照开销
redis-cli INFO stats | grep latest_fork_usec      # 最近一次派生耗时(微秒)
redis-cli INFO persistence | grep -E "rdb_last_cow_size|rdb_last_bgsave_status"
redis-cli INFO memory | grep -E "used_memory_peak|used_memory_rss"
# 关闭透明大页(需 root,写入后立即生效)
cat /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 手动触发一次快照以验证配置
redis-cli BGSAVE && tail -3 /var/log/redis/redis-server.log

指标逐项读法

指标含义判读
最近派生耗时上次派生子进程占用的微秒数数值偏大说明单次停顿明显
写时复制体积快照期间复制出的内存量越大说明期间写入越密集
内存峰值历史最高内存占用接近物理内存即存在风险
常驻内存进程实际占用的物理内存与逻辑内存差值反映碎片与复制页
把快照交给从库承担是常见做法:主库减少派生与复制开销,从库承担磁盘写入压力。
内存已经接近上限时才触发快照:派生需要额外内存,容易触发交换甚至被系统杀掉进程。

易错点

  • 透明大页未关闭:派生与复制开销被成倍放大,延迟尖刺更明显
  • 内存接近满时才做快照:派生需要额外内存,直接触发交换或被系统终止
  • 用当前内存评估容量:必须按内存峰值加复制余量留出空间
  • 在批量导入期间触发快照:写时复制体积暴涨,磁盘与内存同时吃紧

数据来源与参考

  • Redis 官方文档: 持久化(fork 与 COW)
  • Redis 官方文档: INFO stats

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌