概括

概括

概括

禁用(“静态”)且仅应由计时器触发的 systemd 服务单元在每次重新启动时运行。

背景

这是一个服务单位(在/etc/systemd/system/),之前有一个[Install]部门并且是systemctl enabled。

[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

答案1

好吧,在写这篇文章的过程中,我注意到我的计时器单元部分Requires=mysql_tzinfo.service中有一个。[Unit]

我想到启动时计时器的启动(由 systemd 进行依赖解析)可能会因此而启动服务Requires。果然,从计时器中删除这一行并重新启动......服务不再启动。这就是我在关注“技术博客”时没有仔细检查每个配置选项所得到的结果。

对于尝试从 cron 迁移到 systemd 计时器的人来说,要点总结:

  • 不要将一个[Install]部分添加到您的服务单元中,并且不要将您的服务单元添加systemctl enable到您的服务单元中。
  • 不要将 a 添加Requires=<SERVICE_NAME>.service到您的定时器单元。
  • 如果您希望计时器记住它何时运行并在启动时运行错过的运行,请添加Persistent=true到您的计时器。
  • 计时器在启动时运行得相当早,因此您应该 After=向服务单元(您的计时器单元运行)添加必要的要求,以确保服务单元在所有必需的服务(网络、数据库等)都在线之前不会运行。否则很可能会失败。

相关内容