现场是这样的。每天凌晨两点的对账任务要跑三小时,数据量涨上来后三点那一轮和上一轮叠在一起,数据库出现重复对账记录,调度用的是 crontab。
中间走过弯路,把「脚本里没有超时控制,卡住的进程一直留在后台」当成主因,改完现象没变。
原因不止一个,得分开看。任务没有互斥锁,上一轮没结束下一轮照常启动;执行时间已经超过调度间隔,但没人调过频率;异常退出时锁文件没清,后续几轮全被挡住。
先确认当前是否有并发实例在跑
ps -ef | grep -c '[r]econcile.sh'
然后用 flock 给任务加互斥
flock -n /var/lock/reconcile.lock -c '/opt/scripts/reconcile.sh'
给脚本加超时并记录耗时
timeout 5400 /opt/scripts/reconcile.sh >> /var/log/reconcile.log 2>&1
剩下的就是改成上一轮结束再排下一轮
crontab -l | grep reconcile
恢复的判定其实很直接。连续三天观察同一时刻只有一个进程在跑,对账记录不再重复,任务耗时稳定在两小时四十分。
cron 只管按点触发,不管上一轮是否结束;有状态的任务要么加锁,要么换成 systemd timer 的 inactive 间隔触发。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
