【问题标题】:Simple systemd timer won't fire简单的 systemd 计时器不会触发
【发布时间】:2020-02-05 07:50:20
【问题描述】:

我编写了这个脚本来备份我的 sql 文件,包括物理备份(复制数据库)和逻辑备份(pg_dumpall)。

#!/bin/bash

# Backup-Skript für Postgresql

# Dump aller Datenbanken.
/opt/postgresql/bin/pg_dumpall > /mnt/backup/postgresql/pg_backup.bak

# "Physisches" Kopieren des Datenbankverzeichnises.
/opt/rsync/bin/rsync -avu /mnt/evc/postgresql/var/data /mnt/backup/postgresql/
# Dieser Ordner enthält auch die Konfigurationsdateien.
# Daher müssen diese nicht separat kopiert werden.

以下 systemd 单元使用此脚本。

[Unit]
Description=Sicherung der Datenbanken (Postgresql)
DefaultDependencies=no
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=postgresql
Group=postgresql
ExecStart=/opt/postgresql/Scripts/backup.sh

[Install]
WantedBy=multi-user.target

未启用。

那么下面启用的计时器单元应该每 15 分钟运行一次服务。

[Unit]
Description=Backup des Postgresql-Servers alle 15 Minuten
Requires=backup-postgresql.service

[Timer]
# Alle 15 Minuten.
OnCalendar=*:0,15,30,45
Persistent=true
Unit=backup-postgresql.service

[Install]
WantedBy=timers.target

但计时器不会触发。一旦第一次命中为零,服务就会被执行

sudo systemd list-timers --all

显示:

NEXT                         LEFT     LAST                         PASSED       UNIT                         ACTIVATES
Thu 2020-02-06 00:00:00 CET  15h left Wed 2020-02-05 08:25:59 CET  20min ago    shadow.timer                 shadow.service
Thu 2020-02-06 08:40:57 CET  23h left Wed 2020-02-05 08:40:57 CET  5min ago     systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
n/a                          n/a      Wed 2020-02-05 08:45:00 CET  1min 32s ago backup-postgresql.timer      backup-postgresql.service

附加信息:我使用的是内核 5.5.1-arch1-1 的 arch。

【问题讨论】:

  • 我可能是错的(这不会是第一次或最后一次)但不是 OnCalendar 每 15 秒输入一次(minutely 映射到*-*-* *:*:00)?不应该是*:0,15,30,45:0吗?
  • @paxdiablo:我认为每 15 秒触发一次它需要一个额外的*:(例如*:*:0,15,30,45)。也许试试OnUnitActiveSec=15min 看看是否可行。
  • 一个好主意,但不幸的是没有任何改变。即使在重新启动后。
  • 启用 timer 单元,是吗?
  • 我认为RemainAfterExit=yes 是问题所在。这意味着服务将保持启动直到停止。计时器不会停止服务。它只是每 15 分钟启动一次。因此,由于该服务已经启动,它不会再次启动。尝试删除RemainAfterExit=yes

标签: bash timer systemd archlinux


【解决方案1】:

对于您的服务文件,您不需要:

  • DefaultDependencies=no,
  • RemainAfterExit=yes,或
  • [Install] 部分。

我认为RemainAfterExit 是问题所在,因为它使服务保持启动,即使在进程完成后也是如此。这意味着当计时器告诉服务重新启动时,它将被忽略,因为服务仍在运行。

对于您的计时器文件,只要您的计时器与您的服务同名,您就不需要以下内容:

  • Requires=backup-postgresql.service
  • Unit=backup-postgresql.service

事实上,Requires 可能是个问题,因为它会在您启动计时器时立即触发备份,并且如果服务无法启动,也会使计时器失败。

更改这些文件后使用systemctl daemon-reload 以允许systemd 重新读取它们。检查systemctl status backup-postgresql 以查看服务是否在RemainAfterExit 问题后挂起,如果它被卡在运行,请使用systemctl stop backup-postgresql 进行恢复。


为了给出一个简单的模板,我只是从零开始创建了一个简单的计时器:

# /etc/systemd/system/timeprint.timer
[Unit]
Description=Print time every minute

[Timer]
OnCalendar=*:0/1

[Install]
WantedBy=timers.target
# /etc/systemd/system/timeprint.service
[Unit]
Description=Print time

[Service]
Type=oneshot
ExecStart=/bin/date

如果您对这些文件进行更改,您需要运行 systemctl daemon-reload

我启用了:

systemctl enable timeprint.timer
systemctl start timeprint.timer

然后我检查了计时器:

$ sudo systemctl list-timers timeprint
NEXT                         LEFT     LAST                         PASSED  UNIT            ACTIVATES
Wed 2020-02-05 13:00:00 CET  16s left Wed 2020-02-05 12:59:08 CET  35s ago timeprint.timer timeprint.service

1 timers listed.
$ sudo journalctl -u timeprint
-- Logs begin at Tue 2020-01-28 06:55:16 CET. --
Feb 05 12:58:24 stewbian systemd[1]: timeprint.service: Succeeded.
Feb 05 12:58:24 stewbian systemd[1]: Started Print time.
Feb 05 12:59:08 stewbian systemd[1]: Starting Print time...
Feb 05 12:59:08 stewbian date[185510]: Wed  5 Feb 12:59:08 CET 2020
Feb 05 12:59:08 stewbian systemd[1]: timeprint.service: Succeeded.
Feb 05 12:59:08 stewbian systemd[1]: Started Print time.
Feb 05 13:00:24 stewbian systemd[1]: Starting Print time...
Feb 05 13:00:24 stewbian date[185540]: Wed  5 Feb 13:00:24 CET 2020
Feb 05 13:00:24 stewbian systemd[1]: timeprint.service: Succeeded.
Feb 05 13:00:24 stewbian systemd[1]: Started Print time.

【讨论】:

  • 这个答案与this documentation 相矛盾,它说你应该启用.timer 单元而不是.service 单元。哪个是正确的?
  • 你是对的,启用.timer,而不是.service。答案固定。启用该服务不会做任何事情,因为没有 [Install] 部分。
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多