事情本身不复杂,线索都在日志里。凌晨对时之后系统时间往回跳了几分钟,同一条定时任务被触发两次,重复写入了两批相同的数据。

把日志和配置对完,能解释这个现象的基本就这几处。时间回跳让同一个时间点被再次匹配。少数情况下是对时方式用了直接跳变而不是渐进校正。

还有一种情况,任务本身没有做幂等保护。

动手时先确认时间跳变记录

journalctl -u chronyd | grep -i step

再往下改成渐进式校正

grep -E 'makestep|maxslewrate' /etc/chrony.conf

给任务加锁避免重复

flock -n /tmp/job.lock /opt/job.sh

末了核对数据是否重复

mysql -e 'select count(*) from t where dt=curdate()'

那几天正好在做别的变更,先把时间线对齐才敢动手。

改完先别撤,确认这几项。对时不再产生跳变,任务在同一时间窗口只执行一次,数据量恢复正常。

这里还有个坑。虚拟机暂停恢复也会让时间跳变;关键任务用唯一键或者状态表去重,比调时间参数可靠得多。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189