Restic: 处理大修剪更有效

创建于 2019-02-04  ·  52评论  ·  资料来源: restic/restic

restic version的输出

restic 0.9.3 在 linux/amd64 上用 go1.10.4 编译

restic 应该做些什么不同的事情? 您认为我们应该添加哪些功能?

总的来说,我非常喜欢 restic,并且创建/恢复快照工作得非常好。
但是使用大型存储库运行 restic 几乎是不可能的。 我有一个包含 5 TB / 30 个快照的存储库。
意图是像循环缓冲区一样执行此操作(删除最旧的,添加最新的)。

添加快照并删除它们效果很好,但是由于您必须修剪存储库,因此可能需要 WEEKS 才能释放 1 TB(因为重写)。
这使得几乎不可能再使用restic,因为在此期间您无法创建新快照。

正如你在这里已经提到的
你可以做一些事情来改善这一点。

例子:
发现 7336415 个数据 blob 中的 5967884 个仍在使用中,删除了 1368531 个 blob
将删除 144850 个包并重写 142751 个包,这将释放 1.082 TiB(耗时 2 周!)

特别是在您刚刚购买存储(通过 ssh 访问)且 CPU 资源有限的远程存储库上,它再次上传整个存储库的速度要快得多。

prune feature enhancement

最有用的评论

我最近一直在做这个。 这是我所做的:

  • 加载现有索引而不是扫描所有包(然后扫描任何不在索引中的包)
  • 并行扫描已使用 blob 的快照
  • 并行重写部分使用的包
  • 使用内存中已有的索引信息写入新索引

我目前正在努力确定用于重写部分使用的包的并行度级别(我计划将此基于为后端配置的连接数)。 我还需要在各种错误场景中做更多的测试。

以下是一些性能数据(使用具有 875 GiB 数据、大约 180,000 个包和 36 个快照的存储库,使用环回休息服务器作为后端):

  • 当前代码:

    • 35-40分钟(每个)在修剪开始和结束时建立索引(总共70-80分钟)

    • 4-5 分钟找到用过的 blob

    • 几秒钟重写部分使用的包

  • 到目前为止我的变化:

    • 加载现有索引需要几秒钟(如果需要扫描未索引的包,则需要更长的时间)

    • 不到 2 分钟即可找到使用过的 blob

    • 几秒钟写入新索引

我还计划建立一个生成的测试用例,这将涉及更多的包重写。

所有52条评论

现在, @ifedorenko的乱序分支解决了带有大文件的大型 repos/repos 的还原性能,看起来这是在 repo 不在本地的多 TB 环境中使用 restic 的下一个巨石磁盘并且没有通过环回接口上的 REST 服务器访问。

目前,在理论带宽为 10gbit/sec 的高端 AWS 实例上,针对 AZ 本地 S3 存储桶中的存储库进行空修剪(修剪与先前快照 100% 相同的快照)运行在:

1) 建立新索引——~160 包/秒
2) 查找仍在使用的数据——总共 56 秒
3) 重写包——~3包/秒

160 包/秒的速度很慢,但仍然可以忍受(对于 3TB 的存储库,运行时间约为 80 分钟)。

但是重写@ 3 包/秒将运行近 10 个小时,即使对于我的 noop prune (将删除 0 包并重写 111098 包,这将释放 180.699 GiB)。 为了对大型 repo 进行有意义的修剪,您将新备份冻结 24 小时以上。

看起来包重写当前发生在单线程中,因此允许跨多个工作人员运行可能会有所帮助,即使当前的复制然后清除方法保持不变。

就个人而言,我不会花时间优化当前的阻塞剪枝实现,我认为非阻塞剪枝是更好的长期解决方案。

我最近一直在做这个。 这是我所做的:

  • 加载现有索引而不是扫描所有包(然后扫描任何不在索引中的包)
  • 并行扫描已使用 blob 的快照
  • 并行重写部分使用的包
  • 使用内存中已有的索引信息写入新索引

我目前正在努力确定用于重写部分使用的包的并行度级别(我计划将此基于为后端配置的连接数)。 我还需要在各种错误场景中做更多的测试。

以下是一些性能数据(使用具有 875 GiB 数据、大约 180,000 个包和 36 个快照的存储库,使用环回休息服务器作为后端):

  • 当前代码:

    • 35-40分钟(每个)在修剪开始和结束时建立索引(总共70-80分钟)

    • 4-5 分钟找到用过的 blob

    • 几秒钟重写部分使用的包

  • 到目前为止我的变化:

    • 加载现有索引需要几秒钟(如果需要扫描未索引的包,则需要更长的时间)

    • 不到 2 分钟即可找到使用过的 blob

    • 几秒钟写入新索引

我还计划建立一个生成的测试用例,这将涉及更多的包重写。

考特尼:

听起来超级有前途! 想确认这是您所在的分支机构吗? 我很高兴测试。

https://github.com/cbane/restic/tree/prune-aggressive

不,该分支是主存储库分支的一部分。 我还没有在任何地方公开我的更改。 几天后,我应该可以将我正在开发的版本推送到 GitHub,以便您试用。

好的,我有一个版本应该可供其他人试用。 它在这个分支上: https ://github.com/cbane/restic/tree/prune-speedup

当前限制:

  • 我还没有实现任何重新包装工人数量的自动设置。 现在,将环境变量 RESTIC_REPACK_WORKERS 设置为您要使用的工人数量。 如果未设置,它将默认为 4。
  • 我需要在重新打包时处理错误。 我没有对现有的单线程重新打包进行任何真正的更改; 我需要查看各种错误情况,并确保并行重新打包不会导致任何问题。

嗯,这看起来很神奇。 感谢您的工作!

我已经使用 Amazon S3 中的 3TB+ 存储库副本对此进行了一些测试,到目前为止它看起来很棒。 需要数周时间的重新打包修剪现在在不到一个小时内完成,并且使用相对较慢的 EBS 作为 tmp 空间。

这里是真正的游戏规则改变者! 干得好,@cbane!

哎呀,我意识到我跑错了时间。

一个仍然是单线程并且看起来可以从并行化中受益的领域是“检查不在索引中的包”步骤——在多 TB 存储库中仍然需要 3-4 小时——但这仍然是一个巨大的,大大的改进,谢谢!

@cbane我无法针对您的分叉提出问题,因此请告诉我是否有更好的解决方案。

在另一次测试运行中,重新打包在最后失败(重写最后一个包),运行 32 个工人:

found 1396709 of 2257203 data blobs still in use, removing 860494 blobs
will remove 0 invalid files
will delete 119301 packs and rewrite 88485 packs, this frees 896.269 GiB
using 32 repack workers
Save(<data/c136027b25>) returned error, retrying after 723.31998ms: client.PutObject: Put https://ak-logical-db-backup.s3.dualstack.us-west-1.amazonaws.com/xxxxx: Connection closed by foreign host https://ak-logical-db-backup.s3.dualstack.us-west-1.amazonaws.com/xxxx. Retry again.
Save(<data/09d4692900>) returned error, retrying after 538.771816ms: client.PutObject: Put https://ak-logical-db-backup.s3.dualstack.us-west-1.amazonaws.com/xxxxx: Connection closed by foreign host https://ak-logical-db-backup.s3.dualstack.us-west-1.amazonaws.com/xxxxx. Retry again.
Save(<data/23d0d4f842>) returned error, retrying after 617.601934ms: client.PutObject: Put https://ak-logical-db-backup.s3.dualstack.us-west-1.amazonaws.com/xxxx: Connection closed by foreign host https://ak-logical-db-backup.s3.dualstack.us-west-1.amazonaws.com/xxxx. Retry again.
[10:02] 100.00%  88484 / 88485 packs rewritten
panic: reporting in a non-running Progress

goroutine 386596 [running]:
github.com/restic/restic/internal/restic.(*Progress).Report(0xc42011c2c0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0)
        internal/restic/progress.go:122 +0x242
github.com/restic/restic/internal/repository.Repack.func2(0x8, 0xe17f58)
        internal/repository/repack.go:66 +0x136
github.com/restic/restic/vendor/golang.org/x/sync/errgroup.(*Group).Go.func1(0xc4389246c0, 0xc56f509160)
        vendor/golang.org/x/sync/errgroup/errgroup.go:57 +0x57
created by github.com/restic/restic/vendor/golang.org/x/sync/errgroup.(*Group).Go
        vendor/golang.org/x/sync/errgroup/errgroup.go:54 +0x66

我有一个可用的新版本,与以前在同一个分支。 我还针对master进行了调整。

以下是与上一版本相比的主要变化:

  • 将重新打包从让每个工作人员执行将单个包重新打包到管道的所有阶段。
  • 修复了重新打包结束时报告的崩溃。
  • 现在,重新打包会根据 CPU 数量和后端配置的连接限制自动调整管道阶段的工作人员数量。 (不再使用RESTIC_REPACK_WORKERS环境变量。)
  • 对查找使用过的 blob 进行了微调。
  • 并行扫描未知包。

我仍然想在查找使用过的 blob 方面做更多的工作。 目前,每个快照都由一个工作人员处理。 如果快照数量少于 CPU,或者快照之间存在较大的大小差异,这可能会使 CPU 资源闲置。 我想让它在不同的工作人员之间传播子树处理; 我想我知道该怎么做,我只需要实际实现它。

我倾向于继续讨论这个问题(或未来的拉取请求),以便所有内容都保留在主存储库中而不是分散开来。

刚测试过。 它解决了重新包装结束时的崩溃问题,并且工作得非常非常好。

唯一可以从增加的并行性中受益的地方是删除包,它目前是单线程的。

这在以前无法修剪的回购的第一次修剪期间特别难,因为有_lot_需要删除的包。

然而,即使使用单线程删除,每天对 1.7TB、356k 包存储库(重写 14.7k 包并删除 33k 包)进行忘记/修剪现在只需不到 20 分钟。
以前,根本不可能修剪。

出色的工作,谢谢!

好的,我有另一个版本可用。 这次唯一真正的变化是它现在并行删除未使用的包(加上对以前的一些变化的一些小调整)。 我实现了修改后的快照扫描,但它没有提供足够的加速,也没有向用户报告进度的好方法,所以我再次删除了它。

假设没有任何问题,我计划很快为此打开一个拉取请求。 (不过,我会先清理历史记录。) @fd0 ,你想先看看这个吗?

在我们的测试运行中工作得很好。 在 225 秒内重写 30k 包,在 50 秒内删除 73k 包。

针对 S3 中 1.74TiB 存储库(具有 32 个幸存快照)的总运行时间刚刚超过 6 分钟。

出色的工作。

@cbane我试过你的分支https://github.com/cbane/restic/tree/prune-speedup

但这是我收到的错误:(

root<strong i="9">@srv</strong> ~/restic-backups # restic --no-cache prune
repository 49b87c6a opened successfully, password is correct
listing files in repo
loading index for repo
[0:28] 1.01%  30 / 2982 index files
pack cbbebd8d already present in the index
github.com/restic/restic/internal/index.(*Index).AddPack
    internal/index/index.go:266
github.com/restic/restic/internal/index.Load.func1
    internal/index/index.go:230
github.com/restic/restic/internal/repository.(*Repository).List.func1
    internal/repository/repository.go:640
github.com/restic/restic/internal/backend.(*RetryBackend).List.func1.1
    internal/backend/backend_retry.go:133
github.com/restic/restic/internal/backend/rest.(*Backend).listv2
    internal/backend/rest/rest.go:423
github.com/restic/restic/internal/backend/rest.(*Backend).List
    internal/backend/rest/rest.go:358
github.com/restic/restic/internal/backend.(*RetryBackend).List.func1
    internal/backend/backend_retry.go:127
github.com/cenkalti/backoff.RetryNotify
    vendor/github.com/cenkalti/backoff/retry.go:37
github.com/restic/restic/internal/backend.(*RetryBackend).retry
    internal/backend/backend_retry.go:36
github.com/restic/restic/internal/backend.(*RetryBackend).List
    internal/backend/backend_retry.go:126
github.com/restic/restic/internal/repository.(*Repository).List
    internal/repository/repository.go:634
github.com/restic/restic/internal/index.Load
    internal/index/index.go:202
main.pruneRepository
    cmd/restic/cmd_prune.go:202
main.runPrune
    cmd/restic/cmd_prune.go:128
main.glob..func18
    cmd/restic/cmd_prune.go:28
github.com/spf13/cobra.(*Command).execute
    vendor/github.com/spf13/cobra/command.go:762
github.com/spf13/cobra.(*Command).ExecuteC
    vendor/github.com/spf13/cobra/command.go:852
github.com/spf13/cobra.(*Command).Execute
    vendor/github.com/spf13/cobra/command.go:800
main.main
    cmd/restic/main.go:86
runtime.main
    /snap/go/3947/src/runtime/proc.go:200
runtime.goexit
    /snap/go/3947/src/runtime/asm_amd64.s:1337

@antetna看起来您的存储库有多个涵盖相同包的索引文件。 我不知道这是怎么发生的,但我已经为它添加了一个测试用例到测试套件中,我可以重现你的错误。 我会努力修复它。

@antetna好的,我刚刚将一个新版本推送到与我的重复索引测试用例一起使用的同一分支(不是快进)。 你能试一试吗?

我计划很快用这个分支的当前版本打开一个拉取请求,除非其他人注意到任何问题。

非常感谢@cbane! 标准修剪大约需要 55 个小时来修剪我的 ~860GB 12000+ 快照存储库。 使用您更积极的并行方法,它将时间缩短到 3 多个小时。

你好@cbane ,了不起的工作!

在 Debian 9 amd64 上运行此 PR,使用 Go 1.12.1 编译,在我的 30TB 存储库上运行 220 分钟后出现以下错误:

checking for packs not in index
[0:52] 16.45%  178 / 1082 packs
[5:23] 100.00%  1082 / 1082 packs
repository contains 3213929 packs (259446787 blobs) with 15.025 TiB
processed 259446787 blobs: 30090 duplicate blobs, 4.906 GiB duplicate
load all snapshots
find data that is still in use for 3 snapshots
[0:04] 0.00%  0 / 3 snapshots
tree 6f144a19eaae0e81518b396bfdfc9dd5c6c035bdba28c6a90d6f70e692aa1c55 not found in repository
github.com/restic/restic/internal/repository.(*Repository).LoadTree
        internal/repository/repository.go:707
github.com/restic/restic/internal/restic.FindUsedBlobs.func3
        internal/restic/find.go:52
github.com/restic/restic/internal/restic.FindUsedBlobs.func3
        internal/restic/find.go:74
github.com/restic/restic/internal/restic.FindUsedBlobs.func3
        internal/restic/find.go:74
github.com/restic/restic/internal/restic.FindUsedBlobs.func3
        internal/restic/find.go:74
github.com/restic/restic/internal/restic.FindUsedBlobs.func4
        internal/restic/find.go:89
gopkg.in/tomb%2ev2.(*Tomb).run
        vendor/gopkg.in/tomb.v2/tomb.go:163
runtime.goexit
        /usr/local/go/src/runtime/asm_amd64.s:1337

我应该如何从中恢复?

谢谢,
——杜瓦尔。

@DurvalMenezes看起来您的存储库缺少一些包文件。 你以前修剪过吗? restic check成功了吗? 如果没有,它应该让您更详细地了解问题所在。

您可以通过运行restic rebuild-index然后运行新备份来恢复一些。 如果丢失的包中的任何内容在备份的位置仍然可用,新的备份会将其再次添加到存储库中。 这可能会使您现有的备份再次工作。 如果这不能解决问题,我认为您需要先忘记受影响的快照,然后才能进行修剪。

感谢您的回复,@cbane。 更多,如下:

你以前修剪过吗?

不,这是我的第一次修剪。 长话短说:我的仓库有大约 95 个来自 NAS 上 3 个本地污垢的快照; 这 3 个脏器总共约 30TB 和约 60M 文件/子目录,并且备份时间越来越长,以至于仅备份 24 小时的新数据(10GB 以下)就需要超过 24 小时才能运行。 论坛上的建议是运行restic forget (我这样做了,只留下最后 3 个快照),然后运行restic prune ,我首先使用 restic 0.9.5(但它在 ~由于OOM 24 小时)。 然后我将机器(谷歌计算云上的虚拟机)升级到两倍的 RAM,然后使用你的 PR,它给出了上述错误。

restic 检查是否成功? 如果没有,它应该让您更详细地了解问题所在。

我在过去 90 小时内运行restic check (也使用你的 PR),到目前为止它已经给了我这个输出: restic-check-PARTIAL_output.txt

如上述文件末尾所述, restic check已在 3 天前显示其最新消息(“检查快照、树和 blob”)......我开始怀疑它卡住了,永远不会完成:-/ 事实上,进程上的“strace”显示它一遍又一遍地打开同一个本地缓存文件:

```日期; strace -t -f -p 2608 -e 打开 2>&1 | grep 打开 | egrep -v 未完成\|已恢复 | 头
2019 年 7 月 23 日星期二 00:41:59 UTC
[PID 26508] 0点41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2608] 0点41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 10
[PID 2615] 0时41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 5482]○点41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2615] 0时41分五十九秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 3688] 0时41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 5482] 0点41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 10
[PID 2608] 0时41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 11
[PID 2638] 0点41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2638]○点41分59秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5

And then, almost 10 hours later: 

2019 年 7 月 23 日星期二 10:14:27 UTC
[PID 2632] 10时十四分27秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2639]十时14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2634] 10点14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2613] 10点14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2634]十时14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 3688] 10点14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2617] 10点14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 3688]十时14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2634] 10点14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
[PID 2611] 10点14分28秒了openat(AT_FDCWD, “/ TMP / restic检查缓存-370688148 / abb62ab49b950e4b2ab5eb82c4386a9b199a08eb6fd93bdaccd0e4dbe10d29a2 /数据/ 53 / 53d242f8d6444bc2bd49e6689b4c7688fec8996c5e86863bf146a9eb28f54b5d”,O_RDONLY | O_CLOEXEC)= 5
```

您可能可以通过运行 restic rebuild-index 然后运行新备份来恢复一些。 如果丢失的包中的任何内容在备份的位置仍然可用,新的备份会将其再次添加到存储库中。 这可能会使您现有的备份再次工作

我想我接下来会试试这个; 如果这个restic check没有在接下来的 24 小时内完成,我会 SIGINT 它然后运行restic rebuild-index 。 对于rebuild-index,我应该使用这个PR吗? 休息大师的头? 或者是其他东西?

再次感谢,
——杜瓦尔。

是的,这看起来并不乐观。 最好的办法可能是执行restic rebuild-index ,然后运行三个目录的新备份,然后忘记所有其他快照。 之后,您应该能够成功执行restic prune

我没有触及rebuild-index代码,所以你可以用任何你想要的版本来做。

@cbane ,只是为了让你知道:我在 5 天前使用你的 PR 开始了restic rebuild-index (我知道任何版本都可以,但使用你的让事情变得更简单)并且从那时起它一直在运行。 在最初的几天令人绝望之后(从百分比推断似乎表明它将运行超过 30 天),它似乎已经加快了一些速度并且应该“只”再运行 10 天左右(至少在目前'在回购'阶段计数文件)。

假设这个rebuild-index完成正常,那么计划是用你的 PR 运行restic prune 。 会告诉你这件事的进展的。

让每个人都保持最新状态:我的 300 美元免费 GCloud 积分结束了,完全被我必须创建的 104GB 虚拟机所吞噬,以运行prune (而且,我想还有rebuild-index )。 我用完了选项:-/当/如果我找到摆脱这种混乱的方法时会更新。

我尝试了分支“prune-speedup”,结果非常有希望!

后端:S3

# bin/restic version
restic 0.9.5 compiled with go1.12.4 on linux/amd64
# bin/restic prune
repository 6240cd5d opened successfully, password is correct
counting files in repo
building new index for repo
[1:30:34] 100.00%  319784 / 319784 packs
repository contains 319784 packs (5554019 blobs) with 1.445 TiB
processed 5554019 blobs: 0 duplicate blobs, 0 B duplicate
load all snapshots
find data that is still in use for 30 snapshots
[3:38:52] 100.00%  30 / 30 snapshots
found 5376708 of 5554019 data blobs still in use, removing 177311 blobs
will remove 0 invalid files
will delete 3526 packs and rewrite 4850 packs, this frees 26.925 GiB
[1:28:21] 100.00%  4850 / 4850 packs rewritten
counting files in repo
[1:20:27] 100.00%  314240 / 314240 packs
finding old index files
saved new indexes as [b7029105 797145b1 0ed8981e 7f19c455 dff4d9be a52d8e7a 0cf9f266 ab32a9e4 f34331b3 84c84cbb 563896c9 9902e35d 817ef96c 6b4dcfef 32d3e18c 1d782d96 b12554dd d4b69bcf 8ec94a43 66cbd035 8e9cb96d d74b5246 ca7d7ca3 1f209708 9fe26189 28414ee2 88ff07fb 24280466 8757a1f9 8706ff35 5fab942b 549409c3 f781a762 9417afec 4b2361aa 6b43f992 8da8dfe7 54ec498e 5be6fb8a 17411b83 270f3ce3 ba520d35 95913ad0 f8f15108 cbc67971 a419ff7c 875cfcc7 13f55ece bd488aa4 7f5b588a cddd40b4 7a79d1ce bd7e3d0f 2cdcd635 ee6e28c3 98146287 50867bde 41a056ae 836ce971 e9451c8b 0f9cc7e6 52dedc04 c4e8e7f6 2e4966f0 ba4fa5b3 ddc9a766 b995fd36 fd6b3ac8 1c12bcc3 4c98c3c9 39ac7cd5 42ebf4c1 1a48465e b5245192 73a73c5e daa6ee8d d26ce697 9f84d9b3 bc371def b141466a 6906b3c1 282ce115 d8024363 10f0b924 ad4fad64 9450aada 31378365 65d785b3 98b085d0 768f420c f22512b3 be3223ba 031d5488 f2b7fcf6 87177471 fd269664 b239b89e 6bf972ea 0d6f8f36 87362542 fff9c2cd 5c85ac76 f91daae1 dc594a83 220bdc83]
remove 1459 old index files
[2:33] 100.00%  8376 / 8376 packs deleted
done
# 

现在使用开发版本:

# bin/restic_linux_amd64 version
restic 0.9.5-dev (compiled manually) compiled with go1.12.4 on linux/amd64
# bin/restic_linux_amd64 prune
repository 6240cd5d opened successfully, password is correct
counting files in repo
building new index for repo
[57:21] 100.00%  314240 / 314240 packs
repository contains 314240 packs (5376708 blobs) with 1.419 TiB
processed 5376708 blobs: 0 duplicate blobs, 0 B duplicate
load all snapshots
find data that is still in use for 29 snapshots
[1:48:18] 100.00%  29 / 29 snapshots
found 5356653 of 5376708 data blobs still in use, removing 20055 blobs
will remove 0 invalid files
will delete 212 packs and rewrite 1427 packs, this frees 3.114 GiB
[14:16] 100.00%  1427 / 1427 packs rewritten
counting files in repo
[57:47] 100.00%  313618 / 313618 packs
finding old index files
saved new indexes as [004d6eb2 630de131 1b85faed 0fb7a978 bc500e05 34f7d187 447c3b59 ada047d2 5430430e 768f606e a5c341ea a75059c5 71d0fbec c63f5c56 ba43e69d f47699f5 d7cd2587 5826bcae 6250ec67 6af77aa4 cbf8c1f9 a7809b5f c3242748 8bb7d037 8ca69481 5a8877c3 fb30ea48 4bdb6269 eeeba466 7cdc444a bc15ddd5 c5544612 b8a5004c 2879403a c33778b7 e692013a 41ce8a1d 55b4be0a 5714b820 1adca569 b06ccd6b 16467da7 79ed066a 64c7e397 43217ede af7350a4 73c65a0f 35260990 a232ea42 c843bfa5 332aded7 0e294517 26984755 3c36a14b 68b2024e 267bf0b2 a41c4f64 aa46affb c7a6e2ac 0d34c60f 766d21f0 0d7b8b41 4fea4363 a1a3c5cd 73809a0e 56a67410 25314d47 a32ded24 68feae36 78ef5cbb b051a740 6a51f900 d2ee860f 1ad44787 c6c4358d 89de2f69 a157bd2b 77995b94 3bc58934 b905be42 0a1df2e7 ba67a98c 263b5266 7a809abc 34ff6f07 d96adc12 8f69fc74 ebb053eb 8fb68f6a 11224e7d 990f61f8 764941fc ed95513b 1c17c8aa 3226a7cb 76988c78 e4d8f156 b4d4c952 8c379d51 e968f3c9 f9cfff55 464cf3e1 f9d23c32 136957e3 02e397b1]
remove 105 old index files
[0:32] 100.00%  1639 / 1639 packs deleted
done
#

看起来进步很大! 恭喜!
如果我在接下来的几周内尝试更多的机器,我会发布更多的结果。

@fbarbeira从您发布的输出看来,您实际上并没有使用我的改进版本。 这是我在 Backblaze B2 上修剪大型存储库时得到的输出:

repository 399dfab1 opened successfully, password is correct
listing files in repo
loading index for repo
[0:02] 100.00%  71 / 71 index files
checking for packs not in index
repository contains 208840 packs (1675252 blobs) with 1006.203 GiB
processed 1675252 blobs: 0 duplicate blobs, 0 B duplicate
load all snapshots
find data that is still in use for 32 snapshots
[0:16] 100.00%  32 / 32 snapshots
found 1675113 of 1675252 data blobs still in use, removing 139 blobs
will remove 0 invalid files
will delete 4 packs and rewrite 24 packs, this frees 26.404 MiB
[3:31] 100.00%  24 / 24 packs rewritten
saving new index
[10:31] 70 index files
remove 71 old index files
[0:04] 100.00%  28 / 28 packs deleted
done

缓慢的主要来源是我的电缆调制解调器的上传速度有限。

restic version的输出也应如下所示:

restic 0.9.5 (v0.9.5-31-g09b92d6d) compiled with go1.11.6 on linux/amd64

有合并此更新@fd0的意图吗?

我非常感谢这项改进使其成为正式版本。 可悲的是,备用轮换变得如此缓慢,以至于restic开始不再是一种选择。

@cbane ,一个绝对不是障碍但我认为我会标记的项目:随着 repos 的增长,修剪包重写变得更慢。

例如,3,984,097 包 repo 的包重写步骤在与同一 AZ 中的 S3 存储桶通信的 i3.8xlarge 上以 110 包/秒的速度重写包。

具有较小 repo (450,473) 的相同实例 + 后备存储组合以 200 包/秒的速度重写。

@pmkane ,即使他们重写相同数量的包,那里的速度差异是否存在? 还是无论有多少包被重写,它总是存在? 另外,只是包重写,还是其他阶段也变慢了?

随着存储库变大,代码中没有任何明显的东西会减慢它的速度。 我在本地版本的包重写阶段添加了分析支持,以帮助追踪缓慢的根源。 但是,我最大的存储库只有大约 200,000 个包,这并不能很好地比较您所看到的。 您愿意在启用分析的情况下运行它并提供输出文件吗?

@cbane ,不确定它是包数量还是回购大小的函数。 我可以在我们较小的 repo 的副本上运行一些测试并查看。 很高兴运行带有分析的版本并分享结果。

460k 包 repo 的一些示例时序——3.7mm 时序如下:

回购的加载索引
[0:01] 100.00% 154 / 154 个索引文件

查找仍在用于 36 个快照的数据
[0:34] 100.00% 36 / 36 个快照
[0:26] 100.00% 4555 / 4555 包重写(175 包/秒)
[0:21] 151 个索引文件
[0:01] 100.00% 11401 / 11401 包已删除

3,752,505 包回购。 还值得注意的是,在“查找仍在用于 14 个快照的数据”步骤中,内存使用量从 ~1GB RSS 激增至 8GB RSS。 Restic 最终以 ~16GB RSS 结束。 鉴于回购规模很大,这可能是不可避免的:

回购的加载索引
[0:33] 100.00% 1188 / 1188 索引文件

查找仍在用于 14 个快照的数据
[2:12] 100.00% 14 / 14 个快照
[49:07] 100.00% 339187 / 339187 包重写(115 包/秒)
保存新索引
[10:59] 1176 个索引文件
删除 1188 个旧索引文件
[4:51] 100.00% 409728 / 409728 包已删除

@cbane ,我很抱歉。 修剪速度的红鲱鱼 - 当我进行一些独立的分析时,我发现两个存储库位于不同的 AZ,所以差异完全是由于更远的 AZ 的延迟不同。

在我们的大型存储库(20.791TiB,40,522,693 blob)中,在“查找仍在使用的数据”步骤中进行修剪时出现以下错误:

在存储库中找不到树 5e40b6de93549df6443f55f0f68f24bf36671e28590579c78bc62f7557490c56
github.com/restic/restic/internal/repository.(Repository).LoadTree内部/存储库/repository.go:711github.com/restic/restic/internal/restic.FindUsedBlobs.func3内部/restic/find.go:52github.com/restic/restic/internal/restic.FindUsedBlobs.func3内部/restic/find.go:74github.com/restic/restic/internal/restic.FindUsedBlobs.func4内部/restic/find.go:89gopkg.in/tomb%2ev2.(墓).run
供应商/gopkg.in/tomb.v2/tomb.go:163
运行时.goexit
/usr/lib/golang/src/runtime/asm_amd64.s:1337

所有备份均已成功完成,并且静态检查不会返回任何错误。

@cbane ,还有什么值得在这里做的额外挖掘工作吗?

重建索引允许修剪成功。 不确定是否有一种让修剪更有弹性的好方法,所以它可以在本地解决这个问题。

嗯,今天又犯了同样的错误。 通过重建索引解决,但我开始怀疑修剪本身是否可能导致问题。 每次检查都干净。

在存储库中找不到树 7dc9112b587a2b67a2459e6badf7c14f986408e05dbe8a68e7458a30740ea951
github.com/restic/restic/internal/repository.(Repository).LoadTree内部/存储库/repository.go:711github.com/restic/restic/internal/restic.FindUsedBlobs.func3内部/restic/find.go:52github.com/restic/restic/internal/restic.FindUsedBlobs.func3内部/restic/find.go:74github.com/restic/restic/internal/restic.FindUsedBlobs.func4内部/restic/find.go:89gopkg.in/tomb%2ev2.(墓).run
供应商/gopkg.in/tomb.v2/tomb.go:163
运行时.goexit
/usr/lib/golang/src/runtime/asm_amd64.s:1337

我们每周进行一次完整还原以验证备份完整性,以补充每日现场文件还原。

虽然 restic 检查没有显示备份有任何问题,但由于缺少 blob,完全还原失败。 所以看起来确实有些东西可能在不应该的过程中被修剪了。

不清楚这是加速分支中的错误,还是基本修剪代码中的错误,或者完全是其他错误。 遗憾的是,我没有一个很好的可重现测试用例,但这是我们第二次在我们最大的 repo 中看到这种类型的 repo 损坏。 我们较小的回购没有显示任何问题。

不幸的是,由于回购的规模,用股票修剪进行测试是不可能的。

我们现在将恢复到 EBS 快照,但将继续监视此问题和其他问题,并乐于测试它的意义所在!

我添加了一个小的 PR #2507,它应该可以改善这种情况。 如果你们中的一些人可以对此进行一些测试,我将不胜感激......
谢谢!

阅读修剪代码 - 重新打包读取 blob,然后连续保存新包。 如果您要通过网络重新打包,那将成为瓶颈。

@DurvalMenezes是您的 NAS 在本地网络上还是在互联网上? 如果在本地网络上,您是通过 wifi 还是以太网连接到它?

将读取 blob/保存包并行化到网络似乎是一个简单的胜利。


另外,我想知道是否有更好的策略是尝试使修剪增量。 类似于重复的两步化石收集: https ://github.com/gilbertchen/duplicacy/wiki/Lock-Free-Deduplication#two -step-fossil-collection

另外,我想知道是否有更好的策略是尝试使修剪增量。 类似于重复的两步化石收集: https ://github.com/gilbertchen/duplicacy/wiki/Lock-Free-Deduplication#two -step-fossil-collection

有关此主题的讨论,请参阅#1141。

PR #2513 中的两个新命令“cleanup-index”和“cleanup-packs”也应该会大大改善这种情况。 使用这些命令,如果您的存储库是健全的,您可以在不重新打包的情况下进行修剪..

所以我不小心做了两件事,我每小时运行 11 次而不是 1 次每小时备份,并且在过去 384 天左右的时间里我没有运行我的忘记工作。 我有 101417 张快照。 我认为忘记/修剪它太慢了,我想我只是要删除它。

您可以尝试 #2718 - 但是,“忘记”快照没有任何改进。
如果忘记步骤是您的麻烦,我建议您:

  • 找出您想要保留的快照,例如通过查看您上次的备份日志或只是进行另一个备份。
  • 从存储库的/snapshots目录中手动删除除这些文件之外的所有文件
  • 之后,运行prune (如果你想用#2718)

我只是想保留它们几天,所以我将删除 S3 上的整个目录并重新开始。 我开始了忘记过程,这花了很长时间,我认为要么新的分支会有所帮助(看起来不像),要么至少有人会觉得它很有趣。

我真的很想试试这个分支(或者真的,希望它被拉进主人)。 我试图测试并得到

致命:无法打开配置文件:统计:您提供的 AWS 访问密钥 ID 在我们的记录中不存在。

使用主版本可以正常工作。 我还能够毫无问题地使用https://github.com/restic/restic/pull/2340上的分支。

我可以在 NFS 安装的存储库上使用这个分支,只有 AWS 存储的存储库不起作用。 我不知道如何解决...

感谢所有的好工作

@vtwaldo21您尝试了哪个分支? 是#2718吗?
您的错误消息表明您的 AWS 凭证有问题。 这也可以解释为什么 NFS 确实可以正常工作。

其他 restic 命令是否适用于您的 AWS 存储库?

@aawsome ,我是个白痴,转置了分支/问题编号,真的很困惑。 对不起。

分支 2718 工作得很好(在 AWS 和 NFS 支持的存储库上)。 我不能肯定地说它是否更快,因为它仍在运行
分支 2340 是有问题的分支,也是我出现在这个论坛帖子中的原因。

分支 2340 是基于 0.9.5 的,所以有点旧但还不错。 我正在做这样的简单测试:

restic binary is path 刚刚通过 RPM (0.9.6) 安装

静态快照
[作品]
restic.2718/restic 快照
[作品]
restic.2340/restic 快照
致命:无法打开配置文件:统计:您提供的 AWS 访问密钥 ID 在我们的记录中不存在。

因此,虽然该错误暗示了 AWS 凭证的某些内容,但我实际上是在背靠背地运行命令,没有变量更改。 这个分支似乎还有其他问题。

我的 prunes 需要几天时间才能获得 ~2TB 的 repo,所以对 2718 和 2340 都被合并到 master 非常感兴趣

@cbane非常感谢您的所有工作! 我们刚刚合并了#2718,它重新编写了修剪代码,我认为它解决了这个问题以及#2340。

对于我们如何处理您的贡献,我感到非常抱歉,希望您能接受我的道歉。 :失望的:

我和@MichaelEischer 谈过,他提到PR #2340 包含更多尚未实施的想法,所以我重新打开这个问题。

@cbane您有兴趣与我们合作将这些想法合并到当前代码中吗? 如果没有,我完全可以理解,那么我们将通过您的 PR 并自己提取它们:)

昨天我们也进行了简短的讨论,并试图找出可能出了什么问题,以便我们下次可以做得更好。 我们确定的一些要点是:

  • PR 更改了代码中的高度敏感区域(修剪,最终删除数据),因此需要额外的审查
  • @MichaelEischer@aawsome试图审查 PR 并说它太大了
  • PR 只是两次提交,其中一个用完全不同的代码替换了所有代码,这很难审查
  • PR 包含至少 4-5 种不同的想法和改进,这使得审查变得更加困难

还有什么我错过的吗?

据我所知,#2340 对 cmd_prune.go 的更改完全被@aawsome所取代的 #2718 和 #2842 所取代。 #3006 还替换了 index/index.go 的更改。

我已经从checker.go中提取了高度并行化的树遍历实现(参见 https://github.com/MichaelEischer/restic/tree/streamtrees),它允许使用一些实现并行FindUsedBlobs额外的代码行。 它也可用于复制命令。 我提到的分支还统一了用于并行化索引和快照加载的代码。 我会将分支拆分为更小的 PR。

这似乎使后端连接计数和 GOMAXPROCS 的使用自动调整为 IO/CPU 并行度作为 #2340 的剩余部分。

我注意到 #2340 和其他 prune PR 目前都没有并行化重写索引的上传。

此页面是否有帮助?
0 / 5 - 0 等级