首页/数据/备份与容灾速查/cron 与 flock 防重入备份

cron 与 flock 防重入备份

cron 是经典调度器;备份任务用 flock 加锁可避免上一次未结束又启动下一次,防止并发读写同一备份存储。

备份与容灾速查数据更新于 2026-10-13

cron 与 flock 防重入

定时备份最常见的故障不是脚本写错,而是上一次还没跑完、下一次又启动了:两个进程同时读写同一个备份目标,产物互相覆盖,或者把存储 IO 挤到崩溃。flock 用文件锁把任务串行化,是给 cron 上的备份任务加的最便宜的一道保险。

基本信息

适用平台Linux 各发行版;cron 由 cronie / cron 提供,flock 来自 util-linux
执行环境cron 的环境变量极简,脚本内应使用命令全路径并自行设置 PATH
锁行为flock -n 拿不到锁立即退出(跳过本次);不加 -n 则等待锁释放
替代方案systemd timer 配合服务单元的 ExecStart 与超时设置,管理更清晰

典型使用场景

  • 每日全量备份:数据量增长导致任务偶发超过间隔时,防止任务叠加
  • 密集增量任务:每 15 分钟一次的快照任务,避免前一次未结束时重入
  • 远程同步任务:链路慢导致 rsync 长时间运行,需要锁保护目标目录
  • 多任务共享同一备份存储:用同一把锁串行化写操作,减少 IO 争抢
  • 发布前后临时任务:临时备份脚本与例行任务互斥,避免产物命名冲突

crontab 示例与锁写法

crontab 示例与锁写法
# 每天 02:30 执行,持锁运行,锁被占用则跳过本次
30 2 * * * /usr/bin/flock -n /var/lock/backup.lock /usr/local/bin/backup.sh >> /var/log/backup-cron.log 2>&1
# 脚本内自行加锁(推荐,脚本手工执行时也受保护)
exec 9>/var/lock/backup.lock
flock -n 9 || { echo "$(date -Is) 已有任务在运行,跳过"; exit 0; }
# 跳过次数要计数并可告警,长期跳过说明窗口规划有问题

两种锁行为对照

写法行为适用判断
flock -n拿不到锁立即退出,本次跳过任务间隔短、宁可跳过也不排队
flock(不加 -n)等待锁释放后继续执行任务必须完成、允许延后启动
锁文件位置建议放 /var/lock 或专用于备份的目录放在备份目标目录会被清理任务一起删掉
退出码拿不到锁应返回 0 而非失败返回非零会触发无意义的失败告警
cron 环境精简:脚本内使用命令全路径并自行设置 PATH,避免出现『手工跑正常、cron 跑失败』这类问题。
cron 的输出邮件通常无人阅读:把标准输出与错误重定向到日志文件,另外配置基于结果的告警,否则失败会长期无人发现。

易错点

  • 不加锁导致任务叠加:两个进程写同一目标,产物互相覆盖且存储 IO 被挤满
  • 锁文件放在备份目录里:清理任务把锁文件删掉后锁失效,防重入形同虚设
  • 拿不到锁时返回非零退出码:告警系统收到大量误报,真正的失败被淹没
  • 依赖 cron 的默认环境:命令找不到或时区不符,任务静默失败且无日志

数据来源与参考

  • man 5 crontab
  • man 1 flock(util-linux)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌