Linux环境下的增量文件工具
整理了一些Linux环境下进行增量备份的工具、创建增量文件的工具的使用方法。
tar的增量功能
tar命令本身是可以支持创建增量包的,通过使用-g参数指定一个文件用于存放快照,一个例子如下:
tar -g test.tar.snapshot -zcvf test.tar.gz test
此处,test.tar.snapshot为快照文件,用于存放上一次创建压缩档案时的文件列表和最后修改时间。
例如,先后执行以下命令:
# 创建test文件夹,在文件夹内创建file1、file2
tar -g test.tar.snapshot -zcvf test.tar.gz test
# 此时,test.tar.gz包含test文件夹和文件夹内的file1、file2
# 在test文件夹内修改file1,创建file3
tar -g test.tar.snapshot -zcvf test.inc1.tar.gz test
# 此时,test.inc1.tar.gz只包含test文件夹和文件夹内的file1和file3,而file2未改动,故不包含在压缩档案内
# 在test文件夹内删除file3,创建file4
tar -g test.tar.snapshot -zcvf test.inc2.tar.gz test
# 此时,test.inc2.tar.gz只包含test文件夹和文件夹内的file4,而file1和file2未改动,file3不存在,故都不包含在压缩档案内
# 依次解压几个压缩包
rm -r test
tar -zxvf test.tar.gz
tar -zxvf test.inc1.tar.gz
tar -zxvf test.inc2.tar.gz
# 此时,test文件夹中将包含修改过的file1以及最后的file2、file3和file4
tar的增量功能可以只记录新增的文件和修改的文件,但是无法记录文件的删除行为。
rsync
rsync是一个很方便的文件同步工具。在Debian系统可直接通过apt安装rsync软件包。rsync可以用于本地文件同步或远程文件同步,并可启用压缩、增量等功能。一个本地同步的例子如下:
# 假设已有备份文件夹/mnt/sda1/backup/,该命令将$HOME下的Documents同步至/mnt/sda1/backup/Documents
rsync -av ~/Documents /mnt/sda1/backup
其中-a参数为archive模式,-v参数可显示出更多的信息。该命令等价于cp -r ~/Documents /mnt/sda1/backup,但只复制新增和修改的文件。如果要求完全同步,即支持把源文件中删除的文件在目标文件夹中移除,可附加--delete参数:
rsync -av --delete ~/Documents /mnt/sda1/backup
请注意,使用--delete参数时,一定要确认目标文件夹正确,否则可能导致文件被误删。
在使用远程备份时,可实现类似scp命令的功能,例如:
rsync -avz --progress ~/Documents user@192.168.1.1:/mnt/sda1/backup
其中,-z参数表示启用压缩,一定程度上可以提高同步的速度,--progress表示显示进度。
另外需要注意,rsync的远程同步依赖于保存在文件系统的时间戳,双方的系统时间不一致的情况下,可能导致文件同步不全/文件误覆盖的情况。
bsdiff和rdiff
bsdiff是一个文件级的增量补丁生成工具,它也被用于安卓的增量包的生成。在Debian系统可直接使用apt安装bsdiff软件包。
一个例子如下:假如我编译了一个程序program_v1,并已分发给用户。后来我对程序做了一些更新,得到了程序program_v2,我可以将program_v2分发给用户,也可以生成一个增量文件program_v1_to_v2_patch,将增量文件分发给用户,用户通过对program_v1打补丁得到program_v2:
# 创建增量文件(通过program_v1和program_v2得到program_v1_to_v2_patch)
bsdiff program_v1 program_v2 program_v1_to_v2_patch
# 使用增量文件(通过program_v1和program_v1_to_v2_patch得到program_v2)
bspatch program_v1 program_v2 program_v1_to_v2_patch
对于多个文件,也可以先进行归档。bsdiff对tar文件创建增量文件可得到较好的效果,但对tar.gz创建增量文件则很有可能因为压缩结果的显著不一致而产生较大的增量文件。
使用补丁得到新文件时,注意使用合适的校验工具对补丁后的结果进行校验。
另外按照[https://manpages.ubuntu.com/manpages/xenial/en/man1/bsdiff.1.html[1] 的说法,bsdiff需要8倍源文件大小的RAM空间用作工作集以及最高约17倍源文件大小的峰值RAM空间;按照https://www.daemonology.net/bsdiff/的说法,bsdiff需要最高max(17n, 9n+m)的内存空间,其中n是源文件大小,m是新文件的大小,除此之外还需要一块固定的RAM空间占用。
相比于bsdiff,rdiff不需要占用如此高的RAM空间。在Debian系统可直接通过apt安装rdiff软件包。但与bsdiff相比,rdiff多一个创建signature文件的步骤。一个例子如下:
# 对源文件program_v1分块并校验,生成一个签名文件program_v1.sig
rdiff -sv signature program_v1 program_v1.sig
# 利用签名文件program_v1.sig,对新文件program_v2创建增量文件program_v1_to_v2.rdiff
rdiff -sv delta program_v1.sig program_v2 program_v1_to_v2.rdiff
# 利用源文件program_v1和增量文件program_v1_to_v2.rdiff,得到新文件program_v2
rdiff -sv patch program_v1 program_v1_to_v2.rdiff program_v2
其中,-s参数用于输出统计信息,-v参数用于输出工作信息,这两个参数均可以省略。
rdiff的一个应用是分发系统镜像。例如,我创建了一个只读的系统根分区,并将该分区的镜像分发给用户。之后为了新增一些功能,对根分区进行了修改,重新创建了新的根分区,此时,只需要创建源根分区镜像到新根分区镜像的补丁文件,并将补丁文件分发给用户,用户即可通过补丁文件得到新的根分区进行,从而节省服务器网络带宽的使用。