概括
每次重新启动时都会运行一个被禁用(“静态”)并且只应该由计时器触发的 systemd 服务单元。
背景
这是一个服务单元 (in /etc/systemd/system/
),之前有一个[Install]
部分并且是systemctl enable
d。
该[Install]
部分已删除,服务已禁用。该服务现在由计时器触发。计时器设置为每月运行一次并且是持久的,因此它会跟踪上次运行并且不会在重新启动时触发,除非在关机时错过了运行。
systemctl --system daemon-reload
我在做出改变后跑了。
计时器工作正常,并按预期触发服务。
问题
重新启动时,服务单元始终运行,而不管计时器的最后一次运行以及计时器是持久的事实。我已经(通过systemctl list-timers
)验证了触发服务单元的不是定时器单元(除非list-timers
关于上次触发时间的输出是错误的)。
systemctl is-enabled <service-unit>
显示static
(又名禁用,[Install]
单元中没有部分)。
find /etc/systemd/system/*.wants -name <service-unit>
不显示之前安装/启用此服务时剩余的任何已安装符号链接。
我怀疑以前安装此服务单元时存在“遗留”的东西,导致该服务在重新启动时启动,但不知道在哪里查找。
这是在 ubuntu 20.04 上(以防发生已知的错误/问题)。
有没有办法调试 systemd 为什么启动一个单元?(例如,单元 X 开始是因为想要文件 Z 中的 Y)。
有没有办法仔细检查这个服务真的不是由计时器启动的(而不是仅仅通过list-timers
输出)?
服务单位
# cat /etc/systemd/system/mysql_tzinfo.service
[Unit]
Description=mysql_tzinfo
Wants=mysql_tzinfo.timer
[Service]
Type=oneshot
Environment=
WorkingDirectory=/tmp
ExecStart=/bin/sh -c "/usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo | /usr/bin/mysql --user=root mysql"
User=root
Group=root
定时器单元
# cat /etc/systemd/system/mysql_tzinfo.timer
[Unit]
Description=Timer for mysql_tzinfo.service
Requires=mysql_tzinfo.service
[Timer]
Unit=mysql_tzinfo.service
OnCalendar=*-*-05 04:00:00
AccuracySec=30s
Persistent=true
[Install]
WantedBy=timers.target
好的,在写这篇文章的过程中,我注意到我
Requires=mysql_tzinfo.service
的[Unit]
计时器单元部分中有一个。我突然想到,启动时计时器的启动(systemd 的依赖解析)可能会因此而启动服务
Requires
。果然,从计时器中删除这条线并重新启动....服务不再启动。这就是我在关注“技术博客”时没有仔细检查每个配置选项的结果。对于尝试从 cron 迁移到 systemd 计时器的人的要点总结:
[Install]
部分,也不要在您的服务单元中添加部分systemctl enable
。Requires=<SERVICE_NAME>.service
到您的 TIMER 单元。Persistent=true
到您的 TIMER。After=
向 SERVICE 单元添加必要的要求,以确保服务单元在所有必需的服务都在线(网络、数据库等)之前不会运行。否则很可能会失败。