systemd timer 没有按时执行时,先查看下一次触发时间,再核对日历表达式、时区和对应 service 的运行状态。定时器等待中不代表任务已完成,任务仍在运行时也不会自动再启动同一服务。

适用版本与前提

本文面向以 systemd 255 为基线的 Linux 系统级定时任务。内容根据发布时查阅的官方主分支及 v255 手册整理,未在目标服务器实测。请先运行下面的版本查询,并用本机 man 手册核对发行版差异。example.timer 与 example.service 均为占位名称,替换为实际单元名。

systemctl --version
systemctl status example.timer --no-pager --full

一、确认定时器已经加载并处于等待状态

systemctl list-timers --all example.timer --no-pager
systemctl is-enabled example.timer
systemctl cat example.timer

list-timers 用于核对 NEXT、LEFT、LAST 和 ACTIVATES。--all 同时显示当前未活动的定时器。is-enabled 查询启动配置,cat 展示磁盘文件和覆盖项。把输出与预期单元名逐项对照,尤其确认 Unit= 是否指向另一个服务。命令含义见 systemctl 官方手册源文件。

如果 NEXT 为空,先检查定时器状态与配置解析错误。若文件刚改动,磁盘内容和管理器加载状态可能存在差异。是否执行 daemon-reload、启动或启用定时器,应在确认配置和变更范围后决定。

二、单独验证日历表达式

timedatectl status
systemd-analyze calendar --iterations=3 '*-*-* 02:30:00'

上例表达式表示每天 02:30。calendar 会解析表达式并列出后续触发时间,便于在修改任务前核对日期与时区。把引号内内容替换为实际 OnCalendar= 的值。使用明确带时区的表达式时,也应检查解析结果中的时区。calendar 与 --iterations 的定义见 systemd-analyze 官方手册源文件。

检查系统时间同步状态,并比较运维人员理解的时区与主机时区。OnCalendar 使用墙上时钟,而 OnBootSec、OnUnitActiveSec 等使用相对时间,排查时需要先辨认实际采用哪一种。参考 v255 定时器手册。

三、区分触发延迟与任务未成功

systemctl status example.service --no-pager --full
journalctl -u example.timer -u example.service -b --since '-2 hours' --no-pager

状态和日志要同时查看 timer 与 service。时间窗口应覆盖预期触发点,跨重启时按需要调整 -b。记录任务退出状态及应用日志,并验证任务实际产物,例如备份文件的时间、完整性或业务数据。没有日志时还需核对权限及保留范围。

AccuracySec 默认允许一分钟的触发窗口,RandomizedDelaySec 可以再增加随机延迟。不要仅凭配置中的分钟数断定系统故障。对应 service 已经活动时,timer 不会为它额外启动一个并行实例,重复任务中使用 RemainAfterExit=yes 也应特别检查。这些行为在 当前官方 timer 手册 中有说明。

常见问题与验证边界

服务器关机期间的任务会补执行吗?

对 OnCalendar 定时器,Persistent=true 可在重新激活时补触发关机期间错过的任务。它记录触发时间,不能据此认定每个遗漏周期均逐次重放,也不能保证业务处理成功。随机延迟仍可能生效。具体语义见 Persistent 官方定义。

怎样确认修复有效?

修复后再次解析表达式、查询 NEXT,并在下一次自然触发后核对 service 日志和业务产物。手工 start 服务只能验证该次执行,不能证明日历配置按预期触发。本文未提供实测输出或执行效果数据。

相关阅读

如果触发已经发生而服务失败,可继续阅读 systemd 服务启动失败的状态与日志排查,按失败时间保留证据后再决定恢复操作。