.
.
.
.
.
完全用 Linux 已经有快半年的时间了,一直想要全盘备份一下数据,但是却一直没有做,为什么呢?
一方面是东西比较多,备份一次要很长的时间;另一方面是一直在纠结用哪种方式备份比较好。
在网上随便 Google 一下:Linux 系统备份,就能搜索出 N 多篇文章详细的介绍各种备份工具的优缺点。
选来选去最终还是选用 tar 方式。原因很简单,从几年前 LZ 开始用 Linux 的时候开始,就一直在用 tar 备份系统。虽然那时候是 Linux 小白,并不能理解使用 tar 备份时的各个选项的意思,只是把网上的命令照搬下来。但是如今对 tar 的认识已经比那个时候深入得多了,再加上 tar 包格式的通用性,也让 LZ 对 tar 备份的方式最为放心。
当然这篇博文不是来讨论到底那种备份方式更好的,只是把 LZ 备份的思路分享出来,让园子里同样遇到这个问题的园友有个参考。
先看看磁盘的各项数据:
>$ sudo fdisk -l Disk /dev/sda: 120.0 GB, 120034123776 bytes 255 heads, 63 sectors/track, 14593 cylinders, total 234441648 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x0008fa39 Device Boot Start End Blocks Id System /dev/sda1 * 2048 234440703 117219328 83 Linux Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk identifier: 0x000a1ddb Device Boot Start End Blocks Id System /dev/sdb1 2048 1922080767 961039360 83 Linux /dev/sdb2 1922082814 1953523711 15720449 5 Extended Partition 2 does not start on physical sector boundary. /dev/sdb5 1922082816 1953523711 15720448 82 Linux swap / Solaris >$
一共有两块硬盘:
sda 是 120GB SSD,只有一个分区,挂载着 / 文件系统。
sdb 是 1TB 机械硬盘,一个分区挂载在 /home 目录上,另一个是 SWAP。
>$ df -h Filesystem Size Used Avail Use% Mounted on /dev/sda1 111G 6.1G 99G 6% / none 4.0K 0 4.0K 0% /sys/fs/cgroup udev 3.9G 4.0K 3.9G 1% /dev tmpfs 3.9G 3.1M 3.9G 1% /tmp tmpfs 789M 1.3M 788M 1% /run none 5.0M 0 5.0M 0% /run/lock none 3.9G 16M 3.9G 1% /run/shm none 100M 32K 100M 1% /run/user tmpfs 3.9G 812K 3.9G 1% /var/log tmpfs 3.9G 36K 3.9G 1% /var/tmp /dev/sdb1 903G 306G 551G 36% /home >$
/ 分区使用了 6.1GB,/home 分区使用了 306 GB。
也就是说 LZ 要备份大概 300GB 左右的数据。由于数据量比较大,LZ 又希望能够经常进行备份,所以不能选择全量备份,只能采用增量备份。
LZ 曾经用 windows 的时候丢过一次代码,从此之后每星期对全盘进行一次 ghost 全量备份,导致的后果就是每周 7 天时间,却要拿出 1 天的时间进行备份。幸好持续的时间不长,LZ 转战 Linux 阵营,再也没有 ghost 这种工具供 LZ 挥霍了,所以半年以来没备份过系统了。
下面来看看 LZ 的增量备份过程:
1.首先插入一块 2TB 容量的移动硬盘。
2.在移动硬盘上建立一个专门用于增量备份的文件夹,以后所有的增量备份都放到这个文件夹中。
3.等待备份结束。
4.卸载移动硬盘并妥善保管。
注意因为是全盘备份,所以下面的命令必须是 root 来执行!否则很多系统文件普通用户是无权访问的。
>$ mkdir /media/yuhuashi/E260733260730D13/linuxbak >$ cd /media/yuhuashi/E260733260730D13/linuxbak/ >$ time tar -g increment -czvpf alldisk_`date +‘%Y%m%d‘`.tar.gz --exclude=‘/home/yuhuashi/VirtualBox\ VMs‘ --exclude=‘lost+found‘ --exclude=‘/media‘ --exclude=‘/mnt‘ --exclude=‘/proc‘ --exclude=‘/sys‘ --exclude=‘/tmp‘ --ignore-failed-read / >$ umount /media/yuhuashi/E260733260730D13/
这里最重要的就是第三条命令,我这里就专门介绍一下它,其它的命令很简单就不说了。
time(1) 这个命令可以写也可以不写,LZ 加上它只是为了计算一下这次备份花费了多少时间。
tar(1)
tar — The GNU version of the tar archiving utility tar [-] A --catenate --concatenate | c --create | d --diff --compare | --delete | r --append | t --list | --test-label | u --update | x --extract --get [options] [pathname ...]
参数列表:
-g increment:increment 是备份的过程中产生的一个文件的名字,它用于记录备份文件的状态。下次再次执行这条命令的时候,tar 命令就是通过这个文件来区分哪些文件被修改过哪些文件没有被修改过,所以这个参数是增量备份的关键所在!当然文件名字可以随便写,只要在 -g 参数后面指定就好了。千万不要把这个文件弄丢了,否则下次就无法进行增量备份了!
-c:创建一个文件包。
-z:文件包采用 gzip 方式压缩,而已就是扩展名为 .gz。
-v:显示处理文件的详细信息。
-p:保留文件权限。
-f:后面直接跟压缩文件包的名称。注意 LZ 是怎么写这个参数的吗?
alldisk_`date +‘%Y%m%d‘`.tar.gzalldisk_.tar.gz 是这个文件名中不变的地方。`` 之间的内容表示是一条命令,它会把命令的执行结果放在这里作为一个字符串。注意 ` 不是单引号,而是键盘左上角 ESC 键下方和 ~ 在同一个键子上的那个符号。`date +‘%Y%m%d‘` 表示将 date 命令的执行结果放到这个文件名中,也就是当前的 年月日。命令执行之后生成的完整文件名是:alldisk_20150418.tar.gz
--exclude:备份的时候要排除的目录。由于有些目录是不需要备份的,所以需要通过这个命令排除。具体需要排除哪些目录要根据自己的情况来决定,比如 LZ 排除了如下的目录:
/home/yuhuashi/VirtualBox\ VMs:LZ 把自己家目录中的虚拟机目录排除了,因为 LZ 不想备份虚拟机数据。lost+found:每个分区下面都有这个目录,它是 fsck 过程中部分修复的文件,类似于 windows 中的 FOUND(N) 文件夹,一般没什么用。/media:挂载磁盘用的,LZ 备份系统的移动硬盘就挂载在这里,所以当然不能备份它,否则就递归备份了。而且这里的数据也不是 LZ 电脑的内部存储数据,所以跳过。/mnt:跟 /media 的作用一样,直接跳过。一般用 gnome 的时候,插入一个新的存储设备,系统会自动把它挂载到 /media 下面。而 LZ 自己需要挂载一个设备,比如光盘镜像(iso)文件的时候,懒得跑到 /media 下面手工创建一个文件夹,用完之后还得手工删除,就会偷懒直接把它挂载到 /mnt 下面。/proc:这是 proc 虚拟文件系统默认的挂载路径,里面你看到的文件都不是真实存在于磁盘上的,一般都是驱动程序为了方便查看设备信息而创建的虚拟文件。/sys:跟 /proc 差不多,是 sys 虚拟文件系统的默认挂载路径。/proc 下面的文件更倾向于是给人看的;而 /sys 下面的文件则更倾向于是给机器看的。/tmp:临时文件存放的场所,没什么用,直接跳过。由于 LZ 把 / 挂载到了 SSD 上,所以为了减少 /tmp 对 SSD 的写入次数从而提高 SSD 的使用寿命,LZ 干脆把它挂载到内存上去了。
--ignore-failed-read:忽略读取错误而不中断备份,默认情况下读取文件遇到错误的时候是要中断备份进程的。刚开始 LZ 木有加这个参数,然而在等待了一个多小时之后,就在备份即将结束的时候,忽然 /run 目录下有一个文件报 Permission denied,虽然不知道为什么 root 读取文件也会被拒绝,但是它打断了备份进程,这让 LZ 这一个小时算是白白的浪费了。
/:它表示要打包的文件或目录,必须放在整个 tar 命令的最后,后面不能再写其它任何参数了。LZ 填写了根目录,表示挂载在根目录下面的所有目录和文件都要备份,除了被 --exclude 参数指定的文件或目录。虽然 sda1(/) 和 sdb1(/home) 是两个不同的磁盘上的分区,但是 sdb1 现在挂载在 / 下面的 home 目录上了,所以在备份 / 的时候就包含了 /home 中的内容,自然也就将两块磁盘上的数据备份到了同一个 tar 包中。
前面提到了增量备份,也就是说 LZ 下次再次备份系统的时候,只需要再次将这块移动硬盘挂载上,然后再次运行上面相同的 4 条命令,tar(1) 命令就会自动查找当前系统中哪些文件和备份包中的文件有差异了,并且会只将这些有差异的文件打入到增量包中。
那么还原的时候怎么操作呢?也很简单,想还原到哪个版本,就直接将那个版本以前的 tar 包按顺序解压缩即可。
tar xzvf alldisk_20150418.tar.gz -C / tar xzvf alldisk_20150419.tar.gz -C / tar xzvf alldisk_20150420.tar.gz -C / ....
上面的参数都认识吧?什么 x 和 C 不知道是什么意思?
x:表示解包,与我们上面指定的 c 参数正好是相反的,xc 两个参数是不能用在同一条命令中的。
C:表示指定解压缩到的位置,也就是说要把包里的文件解压缩到 / 下面。
其实最后还有一个问题要解决,这也是 LZ 为什么最终选择了 tar 备份的一个原因。
假如将来 LZ 不想还原整个系统,而只是想还原自己的家目录怎么办呢?
很简单,只需要在压缩包后面指定包中文件的路径即可。
tar xzvf alldisk_20150418.tar.gz home/yuhuashi -C /home/yuhuashi tar xzvf alldisk_20150419.tar.gz home/yuhuashi -C /home/yuhuashi tar xzvf alldisk_20150420.tar.gz home/yuhuashi -C /home/yuhuashi ....
如果你不知道那个文件在包中的哪个路径下,也可以使用 grep(1) 命令过滤一下。
tar xtf alldisk_20150418.tar.gz | grep yuhuashi
t:表示测试压缩包,它会打印出来压缩包中的所有文件的路径。这样再用 grep(1) 命令过滤一下,就能找到自己想要解压缩的文件了。
写在最后:当然如果你是服务器管理员,也可以采用 crond + tar 方式来增量备份你的服务器,这样就可以定期自动的执行备份了。