强制 rsync 逐字节比较本地文件而不是校验和

4 linux bash shell backup rsync

我写了一个 Bash 脚本来备份一个文件夹。脚本的核心是一条rsync指令

rsync -abh --checksum /path/to/source /path/to/target
Run Code Online (Sandbox Code Playgroud)

我使用--checksum是因为我既不想依赖文件大小也不想依赖修改时间来确定源路径中的文件是否需要备份。然而,大多数——如果不是全部——我在本地运行这个脚本,即连接了一个包含备份目标文件夹的外部 USB 驱动器;没有网络备份。因此,不需要增量传输,因为这两个文件将完全由同一台机器读取和处理。在这种情况下,计算校验和甚至会降低速度。如果它们都存储在本地,那么如果rsync只是diff文件会更好。

阅读联机帮助页后,我偶然发现了--whole-file似乎可以避免昂贵的校验和计算的选项。联机帮助页还指出,如果源和目标是本地路径,则这是默认设置。

所以我想把我的rsync陈述改为

rsync -abh /path/to/source /path/to/target
Run Code Online (Sandbox Code Playgroud)

请问rsync现在字节检查本地源文件和目标文件的字节还是会使用修改时间和/或大小,以确定是否要备份源文件的需要?我绝对希望依赖于文件大小或修改时间来决定是否备份应该发生。

更新

注意说明中的-b选项rsync。这意味着在替换目标文件之前将对其进行备份。因此,盲目地同步源文件夹中的所有文件,例如,--ignore-times按照评论中的建议提供,不是一种选择。它会创建过多的重复文件并浪费存储空间。还要记住,我正在尝试减少本地机器上的备份时间和工作量。只是备份一切会破坏这个目的。

所以我的问题可以改写为,是否rsync能够逐字节进行文件比较?

hme*_*ia1 5

问题: rsync 是否能够逐个字节地进行文件比较?

严格来说,是的:

  • 这是逐块比较,但您可以更改块大小。
  • 你可以使用--block-size=1, (但它基本上对每个人来说都是不合理的低效和不合适的)

基于块的滚动校验和是网络上的默认行为。

使用该--no-whole-file选项在本地强制执行此行为。(见下文)

语句 1. 在这种情况下,计算校验和甚至会降低速度。

这就是本地传输默认关闭的原因。

使用该--checksum选项强制读取整个文件,而不是默认的逐块增量传输校验和检查

语句 2. rsync 现在会逐字节检查本地源文件和目标文件,还是
       会使用修改时间和/或大小来确定是否需要备份源文件?

默认情况下,它将使用大小和修改时间。

您可以使用的组合--size-only--(no-)ignore-times--ignore-existing
--checksum修改此行为。

声明3.绝对希望依赖于文件大小或修改时间来决定是否备份应该发生。

然后你需要使用--ignore-times和/或--checksum

声明 4. 按照评论中的建议提供--ignore-times不是一个选项

也许使用--no-whole-file and --ignore-times是你想要的?这会强制使用增量传输算法,但对于每个文件,无论时间戳或大小如何。

您(在我看来)只有在避免无意义写入至关重要的情况下才会使用这种选项组合(尽管至关重要的是您要避免的特别是无意义的写入,而不是系统的效率,因为它不会对本地文件进行增量传输实际上并不是更有效),并且有理由相信具有相同修改戳和字节大小的文件确实可能不同。

我看不出修改戳和字节大小是识别更改文件的合乎逻辑的第一步。

如果您比较以下两个文件:

  • File 1 (local) : File.bin -79776451 bytes并在15 May 07:51
  • 文件 2(远程):File.bin -79776451 bytes并在15 May 07:51

默认行为是跳过这些文件。 如果您不满意应该跳过这些文件,并希望对它们进行比较,您可以使用强制逐块比较和差异更新这些文件--no-whole-file --ignore-times

所以关于这一点的总结是:

  1. 使用默认方法进行最有效的备份和存档
  2. 如果出于某种原因这是必要的,请使用--ignore-times--no-whole-file强制增量更改(逐块校验和,仅传输差异数据)
  3. 使用--checksum--ignore-times完全偏执和浪费。

语句 5. 注意-brsync 指令中的选项。这意味着在替换目标文件之前将对其进行备份

是的,但是这可以按照您的意愿工作,这并不一定意味着每次更新文件时都进行完整备份当然也不意味着完全传输会发生。

您可以将 rsync 配置为:

  • 保留文件的 1 个或多个版本
  • 将其配置--backup-dir为完整的增量备份系统。

除了保留差异数据所需的空间外,这样做不会浪费空间。我可以在实践中验证这一点,因为我的备份驱动器上几乎没有足够的空间让我以前的所有版本成为完整副本。


一些补充信息


为什么 Delta-transfer并不比在本地复制整个文件更有效?

因为您没有跟踪对每个文件的更改。 如果您确实有一个 delta 文件,您可以合并更改的字节,但您首先需要知道这些更改的字节是什么知道这一点的唯一方法是阅读整个文件

例如:

  • 我修改了 10MB 文件的第一个字节。
  • 我使用rsyncdelta-transfer 来同步这个文件
  • rsync立即看到第一个字节(或第一个块中的字节)已更改,并继续(默认情况下--inplace)仅更改该块
  • 但是rsync不知道只是第一个字节发生了变化。它将保持校验和直到整个文件被读取

出于所有意图和目的:

  • 考虑rsync一个工具,它根据文件时间戳或大小是否已更改有条件地执行 a --checksum。覆盖它--checksum本质上等同于--no-whole-fileand --ignore-times,因为两者都将:
    • 每个文件进行操作,无论时间和大小
    • 读取文件的每个块以确定要同步的块。

那有什么好处呢?

整个事情是传输带宽速度/开销之间的权衡。

  • --checksum 是只通过网络发送差异的好方法
  • --checksum 而忽略具有相同时间戳和大小的文件是一种好方法,既可以通过网络发送差异,也可以最大限度地提高整个备份操作的速度

有趣的是,这可能是很多更有效地使用--checksum为掩盖选择比这将是强制的增量传输的每个文件


Erk*_*i A 1

无法按照您期望的方式对文件进行逐字节比较而不是校验和。

工作方式rsync是创建两个进程(发送者和接收者),它们创建文件及其元数据列表,以相互决定哪些文件需要更新。即使在本地文件的情况下也会这样做,但在这种情况下,进程可以通过管道进行通信,而不是通过网络套接字进行通信。确定更改文件的列表后,更改将作为增量文件或整个文件发送。

理论上,一个人可以将文件列表中的整个文件发送给另一个人进行比较,但实际上在许多情况下这效率相当低。接收器需要将这些文件保存在内存中,以防检测到需要更新文件,或者需要重新发送文件中的更改。这里任何可能的解决方案听起来都不是很有效。

关于(理论)机制有一个很好的概述rsynchttps://rsync.samba.org/how-rsync-works.html