事情本身不复杂,线索都在日志里。凌晨对时之后系统时间往回跳了几分钟,同一条定时任务被触发两次,重复写入了两批相同的数据。
把日志和配置对完,能解释这个现象的基本就这几处。时间回跳让同一个时间点被再次匹配。少数情况下是对时方式用了直接跳变而不是渐进校正。
还有一种情况,任务本身没有做幂等保护。
动手时先确认时间跳变记录
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()'
那几天正好在做别的变更,先把时间线对齐才敢动手。
改完先别撤,确认这几项。对时不再产生跳变,任务在同一时间窗口只执行一次,数据量恢复正常。
这里还有个坑。虚拟机暂停恢复也会让时间跳变;关键任务用唯一键或者状态表去重,比调时间参数可靠得多。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。