备份策略
广义上讲,我们可以识别出两种类型的备份:系统备份,它是操作系统和应用程序的备份(只有系统管理员才能更改的内容),以及用户备份,它是用户文件的备份(我不知道是否还有其他人使用这些术语,但它们对于本文的目的来说足够了)。正如我们将看到的,系统备份和用户备份应该区别对待。
进行系统备份的原因是为了在崩溃后,最大限度地减少使系统恢复到灾难发生前状态所需的工作量。然而,您不想把半辈子都花在备份磁盘上;没人说这很有趣!有效备份的关键是只备份绝对必要的内容,以便在灾难发生时能够快速恢复。
想想看:您的大部分系统都是相当稳定的——/usr/bin 的内容不会经常更改,对吧?为了使事情更简单,您可能已经拥有系统的粗略副本;大多数人从某种发行版安装 Linux,然后进行自己的自定义。原始发行版很可能是我们许多人恢复的起点。
Linux 与大多数其他操作系统不同,因为操作系统和大量应用程序通常一次性安装,而基于 DOS 的系统,甚至 Linux 以外的基于 Unix 的系统,往往以更零散的方式安装;首先是操作系统,然后是每个应用程序,逐个安装。对于这些系统,备份整个系统是有意义的;通常,在最初设置系统时投入了大量时间和精力。相比之下,安装或重新安装基本的 Linux 系统(包括应用程序)通常是一件快速而轻松的事情。
刚刚说过您的大部分系统都相当稳定,现在让我们考虑一下可能发生变化的内容。您自定义系统的一种方式是添加新程序(发行版中未包含的软件)。在安装新软件时,您应该严格要求自己,并将任何新程序与发行版上的程序分开。它们最好的位置是在 /usr/local 层次结构中。顾名思义,/usr/local 旨在包含 您的 系统本地的程序。这样做的好处是您可以轻松查看哪些程序可以从您的发行版恢复,以及哪些程序需要从其他地方恢复。
您可能要更改的另一件事是标准程序使用的配置文件。许多标准 Linux 实用程序的行为由简单的文本文件控制,您可以编辑这些文件以根据您的需求定制系统。有时,发行版会根据您对某些问题的回答,为您“隐式地”编辑其中一些文本文件,但通常您必须自己编辑它们。
许多重要的文件都位于 /etc 目录中
/etc/printcap—描述如何与您的打印机通信
/etc/fstab—描述您拥有的文件系统
/etc/passwd—包含所有用户及其(加密)密码的列表
/etc/inittab—告诉 init 如何为给定的运行级别设置系统
/etc/XF86Config—描述 XFree86 的初始设置
根据您的系统,可能还有许多其他文件。如您所见,/etc 目录非常重要,它包含的文件很可能是数小时工作的成果。我不知道我是否典型,但我花了很长时间才把 XF86Config 调整到我想要的样子。想到要再次经历这一切就让我不寒而栗。当然,有些程序会使用其他位置的文件,但大多数基本的 Linux 系统都是使用 /etc 中的文件配置的。
当您修改现有程序使用的配置文件时,您不能将它们移动到其他地方;程序(通常)会在特定位置查找它们。因此,重要的是跟踪您所做的更改,这样,如果发生灾难,您可以轻松地恢复它们。记下您对系统所做的所有修改,无论它们当时看起来多么微不足道。
这项工作最好的工具是笔和纸。为自己写下您所做的事情以及原因的详细描述。不要陷入认为在六个月后您会记得如何编译应用程序 Y,或者通过 ghostscript 过滤您的 postscript 文件的 printcap 条目是什么的陷阱,因为很可能您不会记得。即使您将新软件安装在单独的目录中以便于跟踪,写下您安装的内容、安装时间以及当时是否有任何不明显的事情也不会有什么坏处。
现在我们已经确定了需要备份的哪种类型的系统文件,让我们考虑多久备份一次。刚刚进行更改后可能是最重要的时间,但不要忘记保留最新更改之前系统状态的备份,以防事情稍后因您的更改而出错。关键是只有当您更改它们时,事情才会发生变化,这可能不是很频繁,并且您的备份频率应该反映这一点。
用户备份与系统备份不同,因为用户的文件容易频繁更改。您几乎肯定不可能拥有给定用户文件空间的最新备份,您甚至不应该尝试。在备份用户文件时,您正在为您的用户提供一个虚拟的安全网——他们文件的相当新的副本,如果他们做了傻事(例如 rm * bak 而不是 rm *.bak——这种情况确实会发生!),或者如果硬盘驱动器发生故障,他们可以退而求其次。
用户备份必须比系统备份更频繁地进行,甚至可能是每天一次(cron 程序使您能够定期运行程序,而无需每次都发出相同的命令——请参阅 cron 侧边栏)。
许多备份程序(包括 tar)的一个有用功能是能够仅备份自某个日期(例如,上次进行备份的时间)之后更改的文件。这可以大大减少用户备份的工作量,因为用户在给定时间可能只处理少量文件。您可以将用户空间的完整备份与更频繁的增量备份结合起来。
虽然可以使用软盘进行备份,但每张磁盘只能容纳少量数据。许多程序允许备份跨越多个磁盘,但这意味着您必须在那里更换磁盘,备份才能进行。如果您只有一个用户很少的小型系统,那么这可能是可行的,但通常并非如此。磁带或数字磁带可能是更好的选择,仅仅是因为它们的容量更大。Linux 通过 ftape 模块或其 SCSI 支持(数字驱动器几乎总是 SCSI)支持各种各样的磁带驱动器。磁带驱动器的价格在过去 18 个月左右的时间里大幅下降,现在它们对我们许多人来说是一个现实的选择。或者,您的 Linux 机器可能与另一台带有磁带驱动器的机器在同一网络上。Linux 可以访问远程机器上的磁带,但这超出了本文的范围。
无论您选择哪种介质,您都应该妥善保管它。您的备份是为了在出现问题时使用的,因此您可以依赖它非常重要。您应该始终验证您的备份;人们常说,未经验证的备份比没有备份更糟糕。
您还应该保留多套备份。一种流行的策略是基于“祖父-父亲-儿子”的想法。您有三套备份;最后一套(儿子),之前的一套(父亲),以及再之前的一套(祖父)。当您进行下一次备份时,您会覆盖祖父,因此儿子变成父亲,父亲变成祖父,而祖父被新的儿子取代。这种策略的优点是,如果其中一套备份失败,您至少还有可以依靠的东西,但您不必一次进行多次备份。
接下来的一条建议乍一听可能很奇怪:始终将至少一份备份远离您的机器,最好是在完全不同的建筑物中。为什么?好吧,如果建筑物被烧毁了怎么办?您可以更换机器,并获得新的 Linux 发行版,但您将无法更换备份磁带。您计算机上的数据是其最宝贵和不可替代的组件,因此请小心对待它。
好了,闲聊就到这里——让我们看一些例子。有许多不同的备份程序可用,包括免费软件和商业软件。每种程序都有其优点,但在这些示例中,我将使用 tar(GNU 版本 1.11.2)。
假设您刚刚在 /usr/local 中安装了大量新软件,并且认为现在是时候更新您对整个 /usr/local 树的备份了。您没有磁带驱动器,因此您正在使用软盘。像这样的命令
$ tar -cWMf /dev/fd0 /usr/local
将完成这项工作。c 选项表示创建归档文件,W 表示尝试在写入后验证归档文件,M 告诉 tar 如果需要,可以跨越多个软盘,f 选项告诉 tar 将归档文件写入何处,在本例中为 /dev/fd0——软盘驱动器。在许多系统中,您必须是 root 用户才能直接访问 /dev/fd0。
即使我已经请求验证,检查一下也没有坏处。命令
$ tar -tMf /dev/fd0
将显示已备份的所有文件的列表。根据您的 /usr/local 树的大小,您可能需要多个软盘。您可以使用 tar 的压缩选项来减少所需的磁盘数量;z 标志将告诉 tar 通过 gzip 过滤归档文件,从而节省磁盘空间。这是一个好主意吗?嗯,是的,也不是。虽然节省磁盘(或磁带)空间很有吸引力,但将大量文件压缩在一起是有风险的。这意味着最轻微的损坏都可能破坏整个备份,而如果归档文件未压缩,则可能可以读取任何错误,并至少检索到一些数据。有些程序在备份之前单独压缩文件,这可能是一个更好的主意。
我之前提到过,可以备份自某个时间以来修改过的文件。使用 tar,您可以使用 N 选项来实现这一点。例如,
$ tar -cf /dev/ftape -N yesterday /home
将备份 /home 下自昨天以来更改的所有文件,这次备份到软盘磁带设备 /dev/ftape。另一种方法是结合使用 find 和 tar
$ find /home -cnewer /etc/last_backup \ -type f i-print > back_these_up $ tar -cf /dev/ftape -T back_these_up $ touch /etc/last_backup
在这里,find 命令查找 /home 下所有自上次修改文件 /etc/last_backup 以来内容已更改的文件,并将它们的名字写入名为 back_these_up 的文件。T 选项告诉 tar 命令备份 back_these_up 中列出的文件。然后我们 touch 文件 /etc/last_backup,以便下次我们执行此命令序列时,我们得到自上次备份以来修改的文件。像这样组合多个命令非常有用;作为副作用,我们得到了已备份的文件列表,以及上次备份的时间(文件 /etc/last_backup 的时间戳)。
我们可以做的另一件事是过滤文件列表,以便某些文件不被备份。例如,您可能不想备份目标文件或 DVI 文件,因为它们可以很容易地从源代码重新创建(源代码通常是一个小得多的文件!)。如果只有一种您想忽略的文件,简单的 grep -v 就可以完成这项工作;egrep 可以用来忽略几种类型的文件。将上面的第一行更改为类似
$ find /home -cnewer /etc/last_backup \ -type f i-print | egrep -v '<<<>.o$|<<<>.dvi$' \ > back_these_up
以忽略目标文件和 dvi 文件。对于这个简单的示例,也可以使用 find 做同样的事情,尽管它没有 egrep 强大的正则表达式
$ find /home -cnewer /etc/last_backup \ -type f ! \( -name \*.o -o -name \*.dvi \) \ -print > back_these_up
您的确切备份要求很可能无法通过单个 tar 命令轻松满足,因此不要害怕编写自己的小脚本来完成这项工作。它们可以像上面三行的示例一样简单,也可以像您喜欢的那样复杂。几个简单的脚本,使用 cron 定期运行,可以使备份成为一个非常容易的过程。
备份不必是一种漫长的折磨形式。它需要完成,作为系统管理员,您必须这样做,但一点计划和清晰的思路大有帮助。很容易感觉到您必须始终拥有整个硬盘驱动器的完整当前快照,并且同样容易相信某个地方散落的几个文件的六个月前的副本就可以了。最好的策略介于两者之间。
Malcolm Murphy (Malcolm.Murphy@bristol.ac.uk) 记得曾经 256K 内存被认为足以满足您所有的计算需求,而不是现在的最低缓存要求,并且想知道我们现在是不是有点被宠坏了。