编程 restic 仓库校验:check 的两层、抽样读取与修复顺序

2026-11-09 00:05:43

restic 仓库校验:check 的两层、抽样读取与修复顺序

项目地址:https://github.com/restic/restic
文档:https://restic.readthedocs.io/en/stable/045_working_with_repos.html
排障:https://restic.readthedocs.io/en/stable/077_troubleshooting.html

check 分两层,默认只查结构

官方文档把校验分成两类:Structural consistency and integrity(快照、树和 pack 文件),以及 Integrity of the actual data that you backed up。前者默认执行,后者要靠参数打开。

默认跑:

restic check

输出大致是:

load indexes
check all packs
check snapshots, trees and blobs
no errors were found

它不读取 pack 文件内容,只按索引核对结构。要确认 pack 文件本身没被改动过,得加 --read-data,输出会多一段 read all data。官方注释也提醒:这会把整个仓库下载一遍,带宽和时间成本明显更高。

所以日常备份后不做全量读取。全量 --read-data 适合放在低峰、按周或按月跑;每次备份后的自动化校验用 --read-data-subset 抽一部分,具体见下一节。

两个默认行为要先知道:

  • check 默认新建临时缓存目录 /tmp/restic-check-cache-XXXX,可以用 --with-cache 复用现有 cache。
  • check 会 create exclusive lock for repository,文档示例输出里就有这一行。

独占锁意味着 check 运行期间其它写操作要等。--read-data 持续时间可能是几十分钟到数小时,把它安排在备份窗口里会直接挤压备份任务;更稳妥的是放在两次备份之间,或者至少确认锁的等待时间可接受。

缓存目录也值得看一眼:/tmp 在很多发行版上是 tmpfs,全量 --read-data 产生的缓存会落在内存盘上,仓库大时可能把内存吃满。要么把临时目录指到磁盘分区,要么用 --with-cache 复用已有 cache 目录。

--read-data-subset 三种写法

# 1) n/t:把 pack 文件逻辑上分成 t 组,只查第 n 组
restic check --read-data-subset=1/5
restic check --read-data-subset=5/5

# 2) x%:随机抽 x% 的 pack,整数或浮点都行
restic check --read-data-subset=2.5%
restic check --read-data-subset=10%

# 3) nS:按大小抽,S 是 K/M/G/T
restic check --read-data-subset=50M
restic check --read-data-subset=10G

n/t 是可覆盖的:1/5 到 5/5 跑五次,全仓就被覆盖一遍,适合排进定时任务按天轮转。

x% 是随机抽样,文档明确说不保证足够多次后覆盖所有 pack,但适合每次备份后自动抽查一小部分。

nS 内部会把大小换算成占总仓库的百分比,行为等同于百分比方式,只是用大小表达更直观。

修复顺序

排障文档给的顺序是有依赖关系的,别跳步。

  1. 用 restic check --read-data 找损坏,并保留 check 输出。
restic check --read-data
  1. 全量复制仓库,至少拷 index/ 和 snapshots/,同时停掉 forget、prune 等常规操作。

  2. 先修索引:

restic repair index

后续步骤都依赖正确的索引。仓库没坏时不建议跑这条。

  1. 重跑所有 backup。新快照能顺带补齐旧快照缺失的数据。

  2. 仍然缺数据时,先 dry-run 看影响面:

restic repair snapshots --dry-run
restic repair snapshots --forget

--forget 会删掉不可达数据,也就是会丢一部分数据,执行前确认快照范围。

  1. 再跑一次 restic check --read-data,确认 no errors were found。

如果 check 直接提示用 repair packs,就别走 repair index,按提示走。

unreferenced packs 不等于损坏

check 可能报:

pack ... not referenced in any index
N additional files were found in the repo, which likely contain duplicate data.
You can run `restic prune` to correct this.

FAQ 明确说这不是损坏,多半是中断的备份或上传留下的重复数据,prune 清掉即可,输出结尾仍然是 no errors were found。看到这段提示不用进修复流程,更不要拿 prune 当修损坏的手段。

版本变化

0.18.0:

  • check 支持 --json(#1378)。
  • 修了 repair index --read-all-packs 生成超大索引的问题(#5249)。

0.18.1:

  • 修复 check 的下载重试被误判成仓库损坏的问题(#5467)。错误输出特征是 operation successful after 1 retries 之后又出现 check successful on second attempt, original error,并且只报 ciphertext verification failed;其他错误仍然算真损坏。
  • check 支持用 --host、--path、--tag 或直接给快照 ID 限定要验证的 pack(#3326),不必全量扫。
restic check --read-data --tag daily
restic check --read-data --host web-01

限定范围后,校验成本和影响面都能压下来,适合在多主机共用仓库的场景里按快照维度做抽查。

复制全文 生成海报 restic 备份恢复 运维实战

推荐文章

程序员茄子在线接单