UrBackup 日常运维手册

UrBackup 日常运维手册:备份存储目录结构与容量治理、保留策略与清理机制、verify-hashes 等维护命令、用户组与权限体系、服务端/客户端日志与轮转配置、Lua 告警脚本体系与 Webhook 告警闭环(脚本、接收器、SQL 注入、真实触发记录全量公开),以及八类高频故障的实测排查路径。基于 Server 2.5.38 / Client 2.5.31 实测环境编写。

UrBackup备份恢复运维告警2026/10/19

UrBackup 日常运维手册

一、运维体系概览

UrBackup 服务端日常运维围绕四个对象展开:备份存储(磁盘目录 + 元数据库)、客户端与策略(设置项 + 调度窗口)、日志与告警(结构化日志 + Lua 告警脚本)、用户与权限(Web 端账号体系)。本手册全部内容基于 Server 2.5.38 / Client 2.5.31(Ubuntu 22.04)实测环境编写,所有命令输出均为真实回显。

运维相关的文件位置速查:

位置说明
/etc/default/urbackupsrv服务端主配置(端口、日志、临时目录等)
/var/log/urbackup.log服务端日志(logrotate 管理)
/var/urbackup/服务端元数据库与身份密钥(backup_server.db 等)
<备份存储目录>/备份数据本体(实测为 /media/BACKUP/urbackup)
/etc/default/urbackupclient客户端配置
/var/log/urbackupclient.log客户端日志
/usr/local/var/urbackup/客户端元数据(tar 安装形态;deb 安装在 /var/urbackup)

二、存储管理

2.1 备份存储目录结构

UrBackup 按"客户端名/备份点"组织数据。实测存储目录:

/media/BACKUP/urbackup/
├── backup-client1/
│   ├── 261019-0841/        # 备份点:日期-时间(YYMMDD-HHMM)
│   │   ├── ubdata/         # 与客户端目录结构一致的完整视图
│   │   │   ├── data1.bin   # 硬链接(链接数 2+ 表示复用历史块)
│   │   │   └── ...
│   │   └── .hashes/        # 每个文件的分块哈希元数据(treehash)
│   ├── 261019-0844/
│   ├── 261019-1242/
│   └── current -> /media/BACKUP/urbackup/backup-client1/261019-1247   # 指向最新备份点
├── clients/                # 客户端镜像备份登记
└── urbackup_tmp_files/     # 传输临时文件

关键机制:未变化的文件通过硬链接复用(ls -l 可见链接数大于 1),增量备份点的磁盘增量只有实际变化的块;.hashes 目录与数据目录结构镜像,存放每个文件每块的哈希,是增量比对与完整性校验的基础。current 符号链接始终指向最新备份点,脚本化消费备份时建议引用该链接。

2.2 容量监控与配额

Web 端 Statistics 页提供按客户端的存储统计,实测(文件备份累计约 12.6 MB):

{ "usage": [ { "files": 12583000.0, "images": 0, "name": "backup-client1", "used": 12583000.0 } ] }

服务端设置中有软配额项(实测默认值):

global_soft_fs_quota = 95%

即备份存储所在文件系统用量超过 95% 时,服务端会主动清理旧备份腾出空间。运维上应另建磁盘级监控(如 Prometheus node_exporter),因为"软配额触发清理"意味着旧的还原点会被删除,这属于业务决策而不只是技术事件。

2.3 保留策略参数

备份保留由"最多/最少份数"双阈值控制(实测服务端默认值,Web 端 Settings → General 或客户端设置中可改):

参数默认值含义
max_file_incr100文件增量备份最多保留份数
min_file_incr40文件增量备份最少保留份数(清理不低于此数)
max_file_full10文件全量(合成全量)最多保留
min_file_full2文件全量最少保留
max_image_incr / min_image_incr30 / 4镜像增量保留
max_image_full / min_image_full5 / 2镜像全量保留
update_freq_incr18000 秒(5 小时)文件增量调度间隔
update_freq_full2592000 秒(30 天)文件全量调度间隔
update_freq_image_incr / update_freq_image_full604800 / 5184000 秒镜像增量/全量间隔
backup_window_incr_file 等 4 项1-7/0-24备份时间窗口(周一至周日全天)
cleanup_window1-7/3-4后台清理时间窗口(每天 03:00-04:00)

调大保留份数会线性增加存储占用;调整调度间隔与时间窗口是控制"备份风暴"(大量客户端同时备份打满网络/磁盘 IO)的主要手段。

2.4 手动清理与维护命令

服务端命令行提供一组维护子命令(urbackupsrv <command> --help 均可查看):

# 手动触发存储清理(按目标腾出的空间大小)
urbackupsrv cleanup -a 1%
urbackupsrv cleanup -a 10G      # 支持 %/M/G/T 单位

--help 实测回显:

USAGE:

   urbackupsrv cleanup  [-u <user>] -a <%|M|G|T> [--] [--version] [-h]

   -a <%|M|G|T>,  --amount <%|M|G|T>  (required)
     Amount of storage to cleanup

   Cleanup file/image backups from backup storage

其余维护命令:

urbackupsrv verify-hashes      # 校验备份存储中所有文件哈希(深度完整性检查,耗 IO)
urbackupsrv remove-unknown     # 清理存储中不属于任何备份点的孤儿文件并修复符号链接
urbackupsrv repair-database    # 元数据库损坏时的修复尝试
urbackupsrv defrag-database    # 重建元数据库(回收 SQLite 空间、消除碎片)

verify-hashes 与 remove-unknown 的用途说明(--help 实测原文):

verify-hashes : Verify file backup hashes
remove-unknown: Remove unknown files and directories from backup storage
                and fix symbolic links in backup storage

运维建议:defrag-database 在长期运行后(数据库文件达数 GB)有明显收益;verify-hashes 用于怀疑存储损坏(磁盘坏块、意外断电)后做全量校验;remove-unknown 在手工动过备份目录后必跑。

三、用户与权限管理

3.1 账号体系

Web 端 Settings → Users / Groups 管理账号与组。账号信息存储于服务端设置库的 si_users 表(实测表结构):

CREATE TABLE si_users(id INTEGER PRIMARY KEY, name TEXT, password_md5 TEXT, salt TEXT,
                      report_mail TEXT, report_loglevel INTEGER, report_sendonly INTEGER,
                      pbkdf2_rounds INTEGER);

密码存储为 PBKDF2(rounds) 加盐摘要(实测管理员记录:pbkdf2_rounds=10000,64 位十六进制摘要),报告邮件与报告级别也挂在账号上(report_mail/report_loglevel/report_sendonly),实现"按用户订阅备份报告"。

安全底线(官方安装文档原文强调):必须创建管理员账号,否则任何能访问 55414 端口的人都可以通过 Web 界面读取全部备份数据。忘记密码时在服务器上重置:

sudo urbackupsrv reset-admin-pw -a admin -p '新密码'

实测输出:

2026-10-19 12:39:07: Changed admin password.
2026-10-19 12:39:07: Updated admin rights.

3.2 权限粒度

权限按"用户 → 组 → 客户端"三个维度叠加,可控制的功能点在 Web 端用户/组编辑页呈现(实测服务端设置中的权限项包括):查看/浏览/恢复/删除备份(allow_file_restore、allow_all_clients_restore 等)、启动全量/增量备份(allow_starting_incr_file_backups 等)、修改客户端设置(allow_modify_clients)、日志查看(allow_log_view)、暂停备份等。实测环境管理员拥有全部权限(Web API 返回节选):

{
  "admin": true,
  "allow_add_client": true,
  "allow_modify_clients": true,
  "remove_client": true,
  "browse_backups": "all",
  "logs": "all",
  "settings": "all"
}

3.3 登录审计

服务端设置库中有 login_access_log 与 access_tokens 表记录 Web 登录行为,并配套导出命令:

sudo urbackupsrv export-auth-log > auth_log.csv

实测 --help 确认该命令无额外参数,直接输出 CSV 格式的认证日志到标准输出。建议纳入月度安全检查流程。

四、日志管理

4.1 服务端日志

服务端日志默认写 /var/log/urbackup.log,级别由 /etc/default/urbackupsrv 的 LOGLEVEL 控制(默认 warn,可选 debug/info/warning/error)。日志轮转由 deb 包自带的 logrotate 配置管理(实测 /etc/logrotate.d/urbackupsrv 全文):

"/var/log/urbackup.log" {
        weekly
        rotate 12
        missingok
        create 640 urbackup urbackup
        compress
        postrotate
                test -e /var/run/urbackupsrv.pid && kill -HUP `cat /var/run/urbackupsrv.pid` || test -e /var/run/urbackupsrv.ready && /bin/systemctl kill -s HUP --kill-who=main urbackup-server.service
        endscript
}

即每周轮转、保留 12 份、gzip 压缩、轮转后向主进程发 HUP 重开文件。排障时临时把 LOGLEVEL 改为 debug 并 systemctl restart urbackupsrv,查完记得改回。

除文件日志外,每次备份/恢复还会在元数据库生成结构化记录(Web 端 Logs 页展示,保留策略独立于文件日志)。每条记录由 logs(汇总:客户端、错误数、警告数、是否镜像/增量/恢复)与 log_data(逐行明细)组成。一次成功增量备份的结构化日志实例(实测全文):

Starting unscheduled incremental file backup...
Backing up "ubdata" without snapshot.
Indexing of "ubdata" done. 2 filesystem lookups 0 db lookups and 0 db updates
backup-client1: Loading file list...
backup-client1: Calculating file tree differences...
backup-client1: Calculating tree difference size...
backup-client1: Linking unchanged and loading new files...
Waiting for file transfers...
Referencing snapshot on "backup-client1" for path "ubdata" failed: FAILED
Waiting for file hashing and copying threads...
Writing new file list...
All metadata was present
Transferred 1021 bytes - Average speed: 44.384 KBit/s
(Before compression: 499 bytes ratio: 0.488737)
Time taken for backing up client backup-client1: 10s
Backup succeeded

4.2 客户端日志

客户端日志在 /var/log/urbackupclient.log(路径来自 /etc/default/urbackupclient 的 LOGFILE),默认级别 warn、单文件 20 MB 轮转保留 10 份(LOG_ROTATE_FILESIZE=20971520、LOG_ROTATE_NUM=10)。实测环境客户端日志中出现过两类典型条目:

ERROR: Creating shadowcopy of "ubdata" failed.        # 无块设备快照能力时的快照失败
ERROR: Error joining ipv6 multicast group ff12::f894:d:dd00:ef91   # 容器环境无 IPv6 组播,无害

五、告警体系与 Webhook 告警闭环

5.1 内置告警机制

UrBackup 服务端内置 Lua 告警脚本引擎:每个客户端可指定一个告警脚本(服务端设置项 alert_script,默认脚本 Default,id=1,功能是超期发邮件),服务端按客户端粒度周期性执行检查。判定的核心逻辑(内置脚本源码逻辑):

-- ret 位掩码:0=文件与镜像备份均正常;1=文件备份超期;2=镜像备份超期;3=两者均超期
local file_backup_nok = file_interval * params.alert_file_mult - params.passed_time_lastbackup_file

其中 alert_file_mult 为告警倍数(实测默认 3),即"超过备份间隔 3 倍未成功备份"视为超期。实测环境的阈值推算:增量间隔 5 分钟 × 3 = threshold=15min。

5.2 Webhook 告警脚本

内置脚本只能发邮件。要让 UrBackup 接入钉钉/企微/自建告警平台,思路是替换告警脚本中的投递通道:利用 Lua 插件的内置函数 request_url 发 HTTP 请求。完整可用的改法如下(本方案在实测环境闭环验证)。

第一步:编写 Webhook 告警脚本。 以内置 alert.lua 为模板,把邮件发送替换为 request_url GET 调用(关键函数):

--Send webhook alert via HTTP GET (params appended in URL)
function send_webhook(event, image, passed_time, alert_time)
        local btype = "file"
        if image
        then
                btype="image"
                if params.no_images
                then
                        return
                end
        elseif params.no_file_backups
        then
                return
        end

        local lastbackup_txt = "Last " .. btype .." backup was " .. pretty_time(passed_time) .. " ago"
        if passed_time==nil
        then
                lastbackup_txt = "Client has never had a " .. btype .. " backup"
        end

        request_url(params.webhook_url .. "?event=" .. event .. "&type=" .. btype
                .. "&client=" .. params.clientname
                .. "&lastbackup=" .. string.gsub(lastbackup_txt, " ", "_")
                .. "&threshold=" .. pretty_time(alert_time))
end

脚本新增一个可配置参数 webhook_url(脚本参数表 alert_script_params 中注册,类型 string,默认值指向接收器地址)。事件的语义:backup_overdue(备份超期告警)、backup_ok(恢复正常)、image_overdue/image_ok(镜像侧同义)。

第二步:把脚本注入服务端。 脚本存放在服务端主库的 alert_scripts 表中,通过 sqlite 直接写入(服务端无需重启,实测有效):

-- insert_alert.sql(节选):注册脚本与参数
INSERT OR REPLACE INTO alert_scripts (id, name, script) VALUES (2, 'Webhook alert', '-- ...完整Lua脚本...');
INSERT OR REPLACE INTO alert_script_params (script_id, idx, name, label, default_value, has_translation, type)
  VALUES (2, 0, 'webhook_url', 'Webhook URL', 'http://10.89.49.1:9999/alert', 0, 'string');
-- 让客户端 id=1 使用脚本 2
INSERT OR REPLACE INTO settings (key, value, clientid) VALUES ('alert_script', '2', 1);

执行方式(服务端上):

sqlite3 /var/urbackup/backup_server.db < insert_alert.sql

注入后验证:

SELECT id, name, length(script) FROM alert_scripts;

实测输出:

1|Default|0
2|Webhook alert|3912
100000|Pulseway API|0

可以看到服务端原生就内置了三个告警脚本骨架(Default 邮件告警、Pulseway API 接入),Webhook alert 是以同样的机制扩展的。

第三步:准备接收器。 任何能收 HTTP GET 的服务都可以作为接收端(钉钉/企微机器人、Alertmanager webhook 等)。实测用 20 行 Python 演示接收器落盘验证(接收器监听 9999 端口,UrBackup 服务器经网关地址 10.89.49.1:9999 访问):

#!/usr/bin/env python3
# webhook_receiver.py:接收 UrBackup 告警 GET 并落盘
import http.server, urllib.parse, datetime, json

LOG = '/opt/data/quzuo/urbackup-2-5-38/webhook_received.log'

class H(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        u = urllib.parse.urlparse(self.path)
        q = urllib.parse.parse_qs(u.query)
        rec = {'time': datetime.datetime.now().isoformat(), 'path': u.path,
               'params': {k: v[0] for k, v in q.items()}, 'ua': self.headers.get('User-Agent', '')}
        with open(LOG, 'a') as f:
            f.write(json.dumps(rec, ensure_ascii=False) + '\n')
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'{"errcode":0,"errmsg":"ok"}')
    def log_message(self, *a):
        pass

http.server.HTTPServer(('0.0.0.0', 9999), H).serve_fore()

第四步:触发验证。 告警只在"状态翻转"时发送(正常→超期 或 超期→正常),不会重复轰炸。实测制造一次"超期"翻转:把客户端的 file_ok 置回正常态、lastbackup 改到 6 小时前、清空下次检查时间,让服务端检查器重新评估:

UPDATE clients SET alerts_next_check=NULL, lastbackup=datetime('now','-6 hours'), file_ok=1 WHERE id=1;

等待一个检查周期(脚本内置 30 秒节奏)后,接收器日志实测捕获到真实告警:

{"time": "2026-10-19T20:53:43.502172", "path": "/alert",
 "params": {"event": "backup_overdue", "type": "file", "client": "backup-client1",
            "lastbackup": "Last_file_backup_was_4h_21min_ago", "threshold": "15min"}, "ua": ""}

恢复正常时同样捕获恢复事件:

{"time": "2026-10-19T20:44:43.498221", "path": "/alert",
 "params": {"event": "backup_ok", "type": "file", "client": "backup-client1",
            "lastbackup": "Last_file_backup_was_2min_ago", "threshold": "15min"}, "ua": ""}

闭环要点回顾:event(事件类型)→ type(file/image)→ client(客户端名)→ lastbackup(距今时长的人类可读文本)→ threshold(告警阈值),五个字段足以驱动钉钉/企微卡片或转接任何告警网关;对接真实机器人时把 webhook_receiver.py 的落盘逻辑替换为向机器人 URL POST 即可。

5.3 告警参数速查

参数默认值说明
alert_script1(Default)客户端使用的告警脚本 id(settings 表,clientid 维度)
alert_file_mult3文件备份告警倍数(超期阈值 = 备份间隔 × 倍数)
alert_image_mult3镜像备份告警倍数
alert_mail_ok1恢复正常时是否也发通知
webhook_url(自定义)Webhook 脚本的接收端地址

六、常见故障排查

以下故障均在实测环境真实复现,排查路径按"现象 → 证据 → 处置"组织。

6.1 手动备份命令报 Timeout(退出码 4)

  • 现象:urbackupclientctl start -i 回显 Timeout while waiting for server to start backup,退出码 4。
  • 证据:urbackupclientctl status 的 finished_processes 显示 success: true;服务端日志出现 Backup succeeded。
  • 处置:无需处理,属等待超时的误报;以 status 与服务端日志为准(详见《UrBackup 快速入门与实战示例》3.1 节)。

6.2 Web 恢复报 "Starting restore failed: disabled"

  • 现象:Web 端发起恢复,轮询 completed 但文件未恢复。
  • 证据:服务端日志 Starting restore failed: disabled。
  • 处置:客户端 /etc/default/urbackupclient 将 RESTORE=disabled 改为 server-confirms,systemctl restart urbackupclientbackend。

6.3 恢复报 "Cannot read files from folder ..."

  • 现象:从某备份点恢复单个文件失败。
  • 证据:服务端日志 ERROR: Cannot read files from folder /media/BACKUP/urbackup/backup-client1/261019-0841/ubdata/data2.bin. Cannot start restore.。
  • 处置:该文件在所选备份点不存在(换正确备份点)。日志中的 261019-0841 即备份点目录名,可直接在存储目录核对文件是否存在。

6.4 客户端命令行浏览/恢复报 "No file backup access tokens found"

  • 现象:urbackupclientctl browse / restore-start 均报此错,尽管备份一直成功。
  • 证据:客户端令牌文件 /usr/local/var/urbackup/data/tokens_*.properties 中 ids= 为空。
  • 处置:重做一次完整文件备份并等待令牌刷新;期间用 Web 端浏览/恢复替代。该令牌是服务端向客户端同步的备份可见性凭证,令牌未同步时命令行侧无备份可看。

6.5 备份日志出现 "without snapshot" 与 "Referencing snapshot ... failed: FAILED"

  • 现象:每次备份日志都有这两条。
  • 处置:Linux 客户端无可用块设备快照(LVM/btrfs/dattobd)时的正常退化路径,备份仍完整成功。若要求强一致性,给客户端配置 LVM 快照或使用 --require-snapshot 参数(add-backupdir -s)让无快照时备份直接失败。

6.6 客户端日志 "Creating shadowcopy of xxx failed"

  • 同 6.5,快照创建失败退化为直接备份;持续关注数据一致性敏感目录(数据库文件目录)建议配置应用级预备份脚本或使用支持快照的存储。

6.7 客户端启动日志 "Error joining ipv6 multicast group"

  • 现象:客户端服务启动报 IPv6 组播错误。
  • 处置:环境无 IPv6 组播能力(常见于容器)时的无害告警,IPv4 广播/单播发现不受影响。

6.8 客户端始终不在线/无法自动发现

  • 排查顺序:① 客户端 urbackupclientctl status 的 servers 是否列出服务端 IP;② 服务端 BROADCAST_INTERFACES 配置(实测为空表示未限制,多网卡环境应显式指定广播网卡);③ 35623/UDP 是否被防火墙拦截;④ 跨网段环境放弃广播发现,改为在客户端显式配置服务端地址(互联网模式需服务端开启 internet_mode_enabled 并核对 55415 端口)。

6.9 元数据库异常

  • 现象:Web 端报错、备份失败信息含 database 字样。
  • 处置:先备份现状再操作:urbackupsrv repair-database 尝试修复;修复无效或长期运行膨胀时停服执行 urbackupsrv defrag-database 重建。元数据库(/var/urbackup/*.db)必须纳入备份目录持久化范围(Docker 部署时对应 /var/urbackup 卷)。

七、日常巡检清单

建议按日/周/月三级执行:

  • 每日:Web Status 页无红色客户端;file_ok/image_ok 无超期;昨日日志无 ERROR(grep ERROR /var/log/urbackup.log)。
  • 每周:备份存储增长率核对(对比 Statistics usage 周环比);urbackupclient.log 中 shadowcopy 失败是否集中;Webhook/邮件告警通道实测一条测试事件。
  • 每月:export-auth-log 审计登录记录;defrag-database(如元数据库增长明显);抽查一次真实恢复演练(删除非关键文件 → Web 恢复 → 校验 md5),备份系统的可用性只能靠演练证明。

八、参考链接

  1. 服务器管理手册(存储/设置章节):https://www.urbackup.org/ServerAdminGuide-v2.4.x.pdf
  2. 服务端命令行子命令:urbackupsrv --help(本机实测)
  3. 官方论坛告警/脚本板块:https://forums.urbackup.org/
  4. 官网下载页(版本与组件获取):https://www.urbackup.org/download.html
  5. 相关文档:《Ubuntu 22.04 安装 UrBackup 2.5.38 指南》《UrBackup 快速入门与实战示例》《UrBackup 2.5.38 介绍与选型指南》