备份不演练等于没备份:用 systemd timer 做每日打包,并做一次恢复演练

举报
yd_286747025 发表于 2026/11/11 12:39:37 2026/11/11
【摘要】 自托管服务跑了一段时间,我才意识到一个问题:数据一直在服务器上,但我从来没验证过“坏了能不能恢复”。这篇记录我用 systemd timer 做每日备份、保留最近几份,并真的做了一次恢复演练的过程。 一、备份脚本假设服务数据都在 /opt/myapp/data,备份放到 /var/backups/myapp。脚本尽量简单,出错就退出:#!/usr/bin/env bashset -euo p...

自托管服务跑了一段时间,我才意识到一个问题:数据一直在服务器上,但我从来没验证过“坏了能不能恢复”。这篇记录我用 systemd timer 做每日备份、保留最近几份,并真的做了一次恢复演练的过程。

一、备份脚本

假设服务数据都在 /opt/myapp/data,备份放到 /var/backups/myapp。脚本尽量简单,出错就退出:

#!/usr/bin/env bash
set -euo pipefail
SRC=/opt/myapp/data
DST=/var/backups/myapp
KEEP=7
mkdir -p "$DST"
STAMP=$(date +%Y%m%d-%H%M%S)
tar -czf "$DST/myapp-$STAMP.tar.gz" -C "$(dirname $SRC)" "$(basename $SRC)"
# 只保留最近 KEEP 份
ls -1t "$DST"/myapp-*.tar.gz | tail -n +$((KEEP+1)) | xargs -r rm --
echo "backup ok: myapp-$STAMP.tar.gz"

保存为 /usr/local/bin/myapp-backup.sh,chmod 700。如果数据是 SQLite,别直接 tar 正在写的库文件,先用 sqlite3 的 .backup 命令导出一份再打包,否则可能备份到写到一半的状态。

二、为什么用 timer 而不是 cron

timer 的好处是日志统一进 journal,出错能用 systemctl status 直接看到,还能补跑错过的任务。先写 service:

# /etc/systemd/system/myapp-backup.service
[Unit]
Description=Daily backup of myapp

[Service]
Type=oneshot
ExecStart=/usr/local/bin/myapp-backup.sh

再写 timer:

# /etc/systemd/system/myapp-backup.timer
[Unit]
Description=Run myapp backup daily

[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target

启用并立刻手动跑一次:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp-backup.timer
sudo systemctl start myapp-backup.service
systemctl list-timers | grep myapp
journalctl -u myapp-backup.service -n 5 --no-pager

Persistent=true 的意思是:如果服务器恰好在 03:30 关机,开机后会补跑一次,不会漏掉。

三、恢复演练

这是最容易被跳过的一步。我的做法是不碰线上目录,解压到临时目录,再对比:

mkdir /tmp/restore-test
tar -xzf /var/backups/myapp/myapp-XXXX.tar.gz -C /tmp/restore-test
diff -rq /opt/myapp/data /tmp/restore-test/data && echo "一致"

如果服务还在写数据,diff 会有少量差异,属于正常;重点是确认压缩包能解开、关键文件都在、应用能用这份数据启动。真正的演练可以再进一步:用备份起一个临时实例,看能不能正常登录、数据是否完整。

四、踩坑

  1. 备份和数据放同一块盘,盘坏了就全没了。所以光有本机备份不够,至少再同步一份到别处(对象存储、另一台机器或网盘),本机这份只是防误删。
  2. 脚本没写 set -e 时,tar 失败了脚本照样“成功”,空文件占着名额,把好备份挤掉。加上 set -euo pipefail 后失败会让 service 变成 failed,一眼就能发现。
  3. 备份文件权限默认可能让其他用户读到。里面常常有密钥和数据库,目录建议 chmod 700,脚本以 root 运行即可。
  4. Persistent 只对 OnCalendar 类 timer 生效,改成 OnBootSec 之类就没这个效果了,别混用。

五、小结

整套东西不到五十行配置:一个脚本、一个 service、一个 timer。真正有价值的是最后那次恢复演练——它让“我有备份”从一种感觉变成了一个验证过的事实。建议每次改了备份方式之后,都重新演练一遍。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。