Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
29 lines (20 sloc) 3.79 KB
title tags categories date
cubic-backup
Python
作品
计算机
2016-09-07 02:39:43 -0700

最近自制了一个文件备份工具,称为cubic-backup,已发布到GitHub。这个工具用来解决的最主要的一个问题就是:当我同时有固态硬盘和机械硬盘时,如何将固态硬盘作为主要工作区域,而机械硬盘中自动备份文件历史记录?以下是我设想的一些理想场景:

  • 新学期开始,要做大物实验了,为了加快打开速度,我要把大物实验相关的文档放进固态硬盘;
  • 从朋友那里拿到了《生活大爆炸》全集高清资源,为了和USB3.0传输速度相匹配,我把它们复制进固态硬盘,一下子就传输完成了;
  • 打算把那些《生活大爆炸》重命名一下或者放进一个文件夹里,我肯定不希望这导致它们在备份里占用两倍空间;
  • 安装了Visual Studio,固态硬盘的空间有点紧张了,为了腾出空间,随便删掉了一些大文件,包括之前的《生活大爆炸》视频。

据我目前所知,cubic-backup是唯一能满足我的需求的工具。

首先,我尝试了Windows的“文件历史记录”功能。令人遗憾的是,这个功能设计的初衷应该是容灾性备份,不适合经常提取。要从文件历史记录中提取文件,必须使用一个速度相当慢的程序,找到一个正确的时间点(在文件创建后、删除前),才能提取出想要的文件。另外,如果将一个大文件删除后再提取出来,就会导致它在历史记录中占据两倍的空间(备份系统认为我创建了一个新文件,于是重新备份了一次),这一点是绝对不能接受的。

其次,以前常常考虑的git也不合适,它的哈希表存储系统既是优点又是缺点。一方面,它保证了相同文件只存储一份。但另一方面,如果用git管理许多大文件,每隔几分钟自动commit一次,计算哈希值会产生巨大的CPU和IO开销。

最终,我认为自己做一个工具是最顺手的。cubic-backup需要在配置文件中指定若干“缓存-库”对,所谓缓存就是固态硬盘中的一个文件夹,而库是机械硬盘中由cubic-backup管理的另一个文件夹。在提交(commit)时,它会用极小的开销检查一下变更并将新东西存进库中。除此之外,没有任何操作是需要通过cubic-backup才能实现的——即使是想从库中提取文件,也只需要直接打开库,复制想要的东西即可。与git不同,cubic-backup的库对人类非常友好,所有文件的最新版本都是用原本的相对路径和文件名直接存储的。而文件的历史版本,仅仅是文件名中多了一个日期和时间而已。

为了实现“相同文件只存储一次”,我借鉴了git的思路并加以改进,决定让所有相同文件在库中互为硬链接。所谓“硬链接”,是一种特殊的文件系统功能——两个看起来不同的“文件”的文件名不同,路径也可以不一样,但实际上是同一个,在硬盘中只存一份,打开任何一个并修改,都会导致两个文件一起发生变更。然而,这个技术的不利之处是增加了用户不小心编辑库中文件的坏处——所有库中的相同文件都会变化,产生不可预料的结果。不过好在这种错误至少是可以检查出的,由于“.cubicpool”这个目录的存在,每个文件正确的哈希值都是有记录的,若定期检查其中各文件哈希是否相符,即可知道库有没有遭到破坏。

最后,顺便一提,按照我的一贯标准,这个工具是跨平台兼容,并在各平台上都能做到文件名安全(无论处理的文件名多么奇怪都不会有问题)的~