@ghosert
2014-11-02T22:46:29.000000Z
字数 9040
阅读 18414
Ubuntu
继续上篇的内容,在最初使用开发者系统的时候,无论是构建Ubuntu系统基础设施,还是安装配置各种软件都是一个费心劳力的过程:由于开发者系统是一个需要付出脑力成本换取高效率的系统,它因此被设计成一个高可定制又极度自由的系统,暂且不说你可以自由地从编译源码的方式配置安装整个操作系统,即便是大多数的常用软件例如:vi,emacs等等通过变更配置文件都可以玩出无数的操作方式,用户需要花费时间去变更尝试这些配置,使得操作这些软件的方式最符合自己的习惯,达到高效的目的。因此经过一段时间调配,每一个Linux用户都会有一个自己专属的高效系统,有1000个用户就会有1000个专属高效系统,每一个系统上安装的软件和配置方法都各不一样,并且每一个用户在打造这个专属系统的过程中都会耗费大量的精力和时间。丢失自己的专属系统,就意味着时间精力的丢失,对于一个长期使用Linux的用户更是如此:用户已经在这个系统上积累太多软件和操作习惯,如果因为系统崩溃而需要从头开始配置一个全新的系统,在事前又没有任何备份措施,那剩下的简直就是一场灾难。这也是有经验的Linux用户很注意备份的原因。介于此,笔者在本章节结合自己的一些经验来介绍一下Ubuntu系统的备份恢复以及升级策略:
这些备份恢复策略不仅适用于Ubuntu,对于使用其他发行版的Linux用户,同样可以参阅以下内容,对其中的步骤稍加改造即可。
我们前面介绍过Ubuntu系统的一个特色就是可以从自己的源通过apt-get命令来下载需要的软件,因此用户可以建立一个脚本文件,通过写入常用的apt-get install命令的方式来备份需要的软件(参见上一篇中的在云端保存一个软件安装的脚本部分),同时在这个脚本文件中加入某些需要手工干预的个性化配置的具体步骤,例如:更改激活拼音输入法快捷键的具体步骤(大多数拼音输入法抢占了ctrl+space,如果不更改,开发者用户就无法在诸如Eclipse这样的IDE里使用这个快捷键激活智能代码提示的功能),又例如:你可能对 Firefox 的默认字体并不满意,需要替换一下,这些详细的步骤都应该以注释的形式记录在这个脚本里,如果这些步骤实在太过繁琐,也可以在配置以后,找到对应的配置文件,直接保存在Dropbox里,方便今后直接从云端恢复这些配置到本机。例如,你自己定制化了Vim的行为并且加装了Vim插件,那你只需要将~/.vimrc ~/.vim备份在云端即可。
所以一旦建立了这样一个脚本文件,即使需要重装系统或者面对一台全新的计算机,只需要执行这个脚本文件,查看脚本里的注释记录,就可以保证软件没有丢失,配置软件的步骤可以还原,重要的资料都被存储在云端:Dropbox(二进制文件),GitHub(文本文件,以后详述)。自然这个策略的前提是:你在使用系统的时候必须保持勤于更新脚本的习惯,用于日后的系统恢复。
优点
这种方法比较适用于希望将现有系统迁徙到更高版本的情形。例如:迁徙 Ubuntu 10.04 至 12.04的时候,在格式化系统,重新安装12.04以后,用户就可以通过这个脚本恢复原先计算机的面貌。并且由于Ubuntu源里的软件版本和Ubuntu发行版版本之间存在对应关系(例如:10.04源里的firefox版本可能在某个版本以后不再提供更新),如果12.04在目前还是一个比较新的LTS版本,那么就可以保证在12.04上使用apt-get install安装的软件版本都比较新。同时如果你大多数的配置恢复是通过还原具体步骤完成的,那么就有机会检查这些步骤在新版本软件上是否仍旧适用。也不会出现从云端恢复旧版本软件的配置到新版本软件以后无法适用的状况,当然理论上这也不是一个太大的问题,Linux下许多著名的软件都非常尊重用户的旧有习惯,轻易不会变更自己读取配置文件的方式,大多数情况下恢复旧有软件的配置到新版本不会出现太多状况。
缺点
由于没有采用全盘备份的方式,这种备份恢复策略的缺点同样明显,尽管可以保证在升级以后,计算机的原始面貌不会有任何丢失,但是相对来说,手动恢复许多软件的配置仍旧需要投入相当的时间和精力,即使在备份策略完善的前提下,笔者通过这种方式将Ubuntu 10.04升级到12.04的时候仍然花费了整整5天的国庆长假。因此个人建议只在每隔两年发布一次的LTS版本出现的时候才做这样的升级,以此保证计算机的全新状态。
我们前面提到过独立/home分区的原因在于用户大多数重要的个性化配置和数据都保存在这个目录,以至于Ubuntu官方的云端备份软件Ubuntu One在默认情况下就是协助用户备份/home分区所在的数据到云端。因此如果可以在重装系统的时候沿用这个分区的数据,无疑可以为我们节省大量的数据恢复和配置恢复的时间,更何况某些数据如电影,照片可能占据几百个G的空间,没有独立/home分区,用户在重装系统,格式化分区的时候根本就没有可以容纳那么大数据的第二个媒介做临时的备份,除非你有第二块硬盘。另一方面在恢复系统的时候因为配置和数据仍旧在/home目录,你只需要执行前面提到的脚本重新安装软件即可,无需手工还原配置软件的步骤。
为了使用这种恢复策略,在首次安装Ubuntu的时候可以参考上一篇博客的分区推荐方案独立出/home分区,在使用系统的过程中时刻保证只在这个目录下存储自己重要的数据和配置,如果一定有一些特例状况也一定要在恢复脚本中加以记录,在云端有另外的备份措施。只要你的/home分区没有被损坏,再次恢复的代价就相当的小。重装系统的时候可以格式化 / 目录所挂载的分区,但是记得在以下Installation type界面上千万不要选择格式化 /home 所在的分区,否则就无法沿用这个分区的数据。
优点
显而易见,这种策略很经济,省去很多的麻烦,是非常常见的系统恢复策略,同样也适用于在重新安装一个高版本的Ubuntu以后恢复计算机原先的面貌,例如从10.04LTS升级至12.04LTS。
缺点
沿用过去/home分区的数据毕竟在保留了数据的同时也保留了旧有的配置和目录结构,如前所述虽然在匹配新版本软件的时候,这不会是一个太大的问题,但是一旦出现状况,例如两个软件版本之间的差异过大,导致新版本无法正常工作在旧配置或者目录结构上,用户要有一定解决问题的能力,仍然需要通过查看脚本注释手动还原配置步骤。
上述两种恢复策略免不了还是需要在分区以后,插入启动U盘或者光盘,从头开始安装操作系统本身,并且安装完操作系统以后继续安装软件,恢复配置,熟悉Windows下大名鼎鼎的Ghost的同学一定在想,Ubuntu下是否也有这种一站式的全盘备份方案:无论计算机系统当前的状态,我可以对整个系统的每一个字节都做数据备份,当需要恢复系统的时候甚至都不必再次安装Ubuntu本身就可以把当初备份的那个状态复原到新的机器或者格式化以后的当前机器上,甚至是虚拟机上。这也是一般公司的IT部门在帮员工重装机器的时候最常用的策略,没有其它原因,就是因为这种方式最快捷。备份恢复一个系统的时间不会超过一个小时。
优点
最迅速快捷的备份恢复方式,可以通过刻录母盘的方式在各处恢复自己的备份。你既可以在一台物理机上做备份恢复到另一台物理机或者虚拟机,你甚至也可以将一台虚拟机里的备份恢复到一台物理机或者另一台虚拟机上,非常的灵活方便。
缺点
采用这种方式的一个问题在于,如果需要还原的目标机器和做备份的源机器硬件配置差异过大,可能会发生恢复以后某些驱动程序工作不正常的状况,例如计算机没有声音,或者图形分辨率特别低,无法联网等状况。这个时候需要用户自行尝试解决。第二个问题在于由于全盘备份,意味着如果你备份的是10.04的系统,那你也只能恢复到10.04的系统,这种恢复方式没有办法升级你的Ubuntu到更高的版本。第三个问题:一定的学习实践成本,以下就我个人的实践经验提供tar包全盘备份的基本步骤和原理,也许你在网络上可以找到更方便的脚本或者备份软件替代这些工作,但是如果遇到问题回到这些具体的步骤和原理可以帮助你了解到底是哪里出了问题,怎么解决这些问题。
1. 全盘备份
得益于Linux系统强大的命令行和系统设计,全盘备份一个Ubuntu系统的基本原理相当简单:使用tar命令打包必要的文件目录即可,也就是说备份系统和备份数据基本没有区别。
新建一个脚本文件BACKUP_SYSTEM.sh,在其中添加以下内容:
mkdir ~/BACKUP_SYSTEM
sudo tar --exclude /proc --exclude /mnt --exclude /tmp --exclude /media --exclude /home/jiawzhang/Downloads --exclude /home/jiawzhang/Templates --exclude '/home/jiawzhang/VirtualBox VMs' --exclude /home/jiawzhang/BACKUP_SYSTEM -jpcvf ~/BACKUP_SYSTEM/Ubuntu-12.04-20121114-home-pc.tar.bz2 /
这两条命令首先在home目录新建了一个BACKUP_SYSTEM的目录用于放置备份后的tar包。随后tar命令的 --exclude 参数排除了某些你认为没有必要进行备份的目录,例如 Download, Templates 目录,同时我的案例里也排除 VirtualBox VMs 这个目录,因为安装虚拟机以后,Virtualbox所在的这个目录会极度膨胀,我们没有必要把几十个G的虚拟机镜像全都备份进tar包。-jpcvf 这个命令中:j 表示使用 bzip2 格式打包,这是一种压缩耗时但是压缩比很高的格式,经常用于压缩大数据。p 表示在制作tar包的时候保留目录结构的用户权限信息,最大程度的对文件系统做现场保护。cvf 表示创建一个压缩包,并且列出详细的压缩过程。~/BACKUP_SYSTEM/Ubuntu-12.04-20121114-home-pc.tar.bz2 指定了压缩包的文件名,我个人偏向于在这个文件名里写清楚版本信息,打包的时间和在哪一台机器上做的备份,有助于今后做恢复操作。这条命令的最后有一个 “/” 字符就是表示从本机的根目录开始做全盘备份,你本机的所有东西除了被 --exclude 的目录都会被打进最终的压缩包。即使是全盘备份,事前一定要甄别清楚到底哪些目录是没必要备份的,否则压缩和解压过程都会变得无法接受的漫长。
开启终端运行 sh BACKUP_SYSTEM.sh 开始备份。取决于用户备份数据的多少和硬件配置的好坏,备份的时长会有所不同。在笔者本机上,去除非必要目录的全盘备份花费了大约1个小时,把 40G 的资料压缩在 9G 大小的压缩包内。如果你想时刻了解压缩的进度,可以开启另一个终端,运行以下命令:
watch -d -n 5 ls -alh ~/BACKUP_SYSTEM/
这个watch命令用于每隔5秒执行一遍随后的 'ls -alh ~/BASHUP_SYSTEM/' 幷高亮出两次执行之间的不同,因此你可以观察到正在制作中的压缩包大小的变化。
2. 全盘恢复
恢复系统的步骤会比备份繁琐许多,以下是主要步骤,我会尽量解释每个步骤的含义。
确保事先备份的压缩包在某个分区可以被访问到,这里假设你的备份压缩包位于/home/jiawzhang/BACKUP_SYSTEM/UBUNTU-2012-02-05.tar.bz2
通过Ubuntu的启动U盘或者光盘重启电脑,进入试用Ubuntu的模式。
在试用模式的Ubuntu中开启终端,运行命令
sudo su -
切换至 root 权限,取得 root 权限以后类似 fdisk -l, df -h 这些命令才能返回准确的结果。
sudo gparted
打开Linux下的分区软件gparted,如果提示需要安装,则运行
sudo apt-get install gparted
之后可以按照上一篇博客的分区推荐方案进行分区,如果你对自己的分区已经满意,也可以略过分区的步骤,只需要格式化 / 所在分区即可,/home 所在分区因为用于存放备份压缩包,可以选择暂时不做格式化。
mkdir /tmp/root
mkdir /tmp/root2
mount /dev/sda1 /tmp/root
mount /dev/sda2 /tmp/root2
cd /tmp/root2/jiawzhang/BACKUP_SYSTEM/
sudo tar -jpxvf UBUNTU-2012-02-05.tar.bz2 -C /tmp/root
使用U盘启动到live Ubuntu模式幷不会实际上挂载你的物理分区,所以这里需要使用mount命令手动挂载你刚才格式化以后的 / 分区并且将压缩包解压导入。新建两个目录/tmp/root /tmp/root2,将分区/dev/sda1 /dev/sda2分别挂载到这两个目录。确保sda1是系统恢复以后挂载 / 目录的分区,sda2是原来/home目录挂载的分区,其中有我们需要的备份压缩包存在。挂载完毕以后,/tmp/root 对应了 sda1 分区,/tmp/root2 对应了 sda2 分区,进入 /tmp/root2/jiawzhang/BACKUP_SYSTEM 就是我们原先的备份存储的位置。运行 sudo tar -jpxvf xxx.tar.bz2 -C /tmp/root 做解压操作,jpxvf 中的 x 指解压,-C /tmp/root 则指定了需要解压的目标目录,这里实际上就是 sda1 分区所在的根目录。完成这个操作以后,所有的数据就已经被还原到 sda1 分区。你应该可以查看到类似 /tmp/root/etc, /tmp/root/home/ 这样的目录,它们对应的目录就是原先的 /etc, /home。我们下面的步骤会指定启动系统的时候把 sda1 分区挂载回 / 目录,sda2分区挂载回 /home 目录,这样在系统的目录结构就完全恢复了。另外由于/home目录对应的 sda2 分区之前没有进行过格式化操作,此时你可以选择删除/tmp/root2/jiawzhang/下除了BACKUP_SYSTEM以外的所有数据,然后运行
cp /tmp/root/home/. /tmp/root2/ -r
rm /tmp/root/home -rf
将刚才从备份压缩包中解压出的/tmp/root/home部分的数据重新拷贝到/tmp/root2,然后删除/tmp/root/home,即完成了从sda1分区转移恢复后的home数据到sda2分区的工作:sda2 分区是过后用来挂载 /home 目录的分区,理应把home下的数据恢复在这个分区。
经过格式化,分区等等步骤以后,即便你是在现有硬盘上恢复自己的系统,分区的 uuid 都可能已经被改变,因此当初备份在压缩备份包里的启动引导信息诸如:GRUB/MBR都已经不再和目前实际的信息相匹配,我们因此要做修复工作。
仍旧在 live ubuntu 模式下运行:
$ sudo add-apt-repository ppa:yannubuntu/boot-repair
$ sudo apt-get update
$ sudo apt-get install -y boot-repair
$ sudo boot-repair
下载运行启动修复软件 boot-repair,启动后点击默认推荐方式即可。如果想了解这个软件具体做了哪些工作,可以在这里参看手工修复的步骤。不过由于笔者并未验证其正确性,不能保证一定可用。
$ ls -al /dev/disk/by-uuid
再次查看各个分区的 uuid 信息,确保这些 uuid 和 /tmp/root/etc/fstab 中使用的 uuid 一致, 需要挂载的 /, /home,swap 在 /tmp/root/etc/fstab 中也和相应的 uuid 匹配。因为我们恢复的备份使用的是旧有的 uuid 信息,如果不一致:手工打开/tmp/root/etc/fstab这个文件做更正,主要工作就是替换其中的 uuid 字符串和上述命令中的一致。在启动系统的时候,/etc/fstab 这个文件指定了分别挂载sda1 sda2 sda3分区到 /,/home,swap,如果没有正确的 uuid 以及分区目录挂载匹配,系统就无法正确启动。大家可以大致参看一下 /etc/fstab 这个文件的内容片段:
# / was on /dev/sda1 during installation
UUID=f381f8cd-ca11-4227-b9ce-8de330bf0e9f / ext4 errors=remount-ro 0 1
# /home was on /dev/sda2 during installation
UUID=b4b376c7-9ef0-48dc-9f50-28decd899190 /home ext4 defaults 0 2
# swap was on /dev/sda3 during installation
UUID=d770aa08-a3f3-4469-a682-f161cff16135 none swap sw 0 0
另外如果你加装第二块硬盘以后也可以通过 'ls -al /dev/disk/by-uuid' 查看新硬盘的 uuid,幷新建这块硬盘分区对应的挂载目录以后,将这些信息一并写入 /etc/fstab,这样,系统在启动以后就会自动加载你的新硬盘分区。
这些目录就是我们当初做备份时加在 --exclude 参数后面的目录。
mkdir /tmp/root/proc /tmp/root/mnt /tmp/root/tmp /tmp/root/media
chmod 777 /tmp/root/tmp
记得一定要赋予 /tmp/root/tmp 777 权限,这是一个系统级别的临时目录,需要完全的读写权限,否则你的系统无法启动成功,我自己在最初实践全盘备份恢复的时候就因为忽视了这个小细节,导致屡次恢复系统失败,差点放弃。
关闭计算机,幷从硬盘重启计算机,一切顺利的话,全盘恢复已经成功,至此,你可以别无二致的使用备份当时的专属高效系统了。
全盘备份恢复的操作对初学者来说有一定的风险,如果担心操作不当丢失数据,可以先在虚拟机环境里练习,笔者实践过这种方法对虚拟机一样适用。
另外有一些用户最初是在Windows上通过Wubi的方式试用Ubuntu,最后决定彻底抛弃Windows的时候才发觉已经在Wubi里积累了太多的软件和配置,重装系统的代价很大,笔者自己最初也是在Wubi系统中操练Ubuntu,一年半以后才正式迁移到独立分区,彻底告别Windows。所以这里简要介绍一下如何将一个Wubi系统移植到物理分区。
在Windows下使用分区工具从现有的分区中划分出两个分区,假设分别叫做 /dev/sda5 用作安装系统, /dev/sda6 用作 swap 分区。(如果需要独立的/home分区,可以再多分一个)
进入Wubi系统
下载运行移植脚本
点击下载Wubi移植脚本后解压运行
sudo zxvf wubi-move.tar.gz
sudo bash wubi-move.sh /dev/sda5 /dev/sda6
如果有独立的/home分区,读者可参考前面解压备份压缩包小节中恢复/home分区数据的部分。
一切顺利的话,系统会出现Grub引导菜单,你可以通过选择菜单选择进入Windows还是物理分区上的Ubuntu系统,这个Ubuntu系统的内容和你的Wubi系统也同样地别无二致。
这个脚本的使用方法和更新也在持续进行中,目前支持从Ubuntu 8.04 到 12.04 之间的所有版本。这里只是做了一些摘要,读者可以自行访问Ubuntu Forums查看这个脚本更多的用法和其它详细信息。
频率
Ubuntu官方一直以来每隔半年就会发布自己的新版本,对于用户来说实质上是一个不小的负担,往往还没有适应现在的版本,新的版本又推送过来,所以我个人的意见是不用追新,只升级两年一次的LTS版本即可。
时机
我们之前还说过Ubuntu某个版本源里的软件版本都会和Ubuntu自己的版本存在对应关系,例如:Ubuntu 10.04上的输入法软件iBus只会更新到1.2版本,如果你想使用最新的1.4版本,要么自己去编译安装,要么设法说服软件作者或者其它爱好者打包更新Ubuntu10.04源里的iBus版本或者找第三方源,相当的不方便。对于一个太早的发行版很多软件作者没有动力和热情再去为其做兼容性开发,测试和更新源的工作。所以当你发现自己手上的发行版源里的软件都过于腐旧,互相之间出现越来越多的兼容性问题的时候,这也是一个提醒你应当对现有系统做一次升级的信号。举我自己的例子,两个月前决定从10.04升级到12.04就是因为10.04下的拼音输入法fcitx和firefox较新版本之间存在冲突,总是导致页面假死。询问fcitx的源打包者又无果:不愿意更新10.04下的fcitx版本解决这个问题,才有了这次升级。
方式
虽然Ubuntu自己也提供了'sudo apt-get dist-upgrade'这样的命令做发行版之间的大升级,但是从一些用户反馈来看效果并不理想,采用这种方式升级的系统总会存在各种问题。因此还是建议读者可以参照本文前面的备份恢复策略进行跨大版本的升级,一般这样的升级不会有太多问题,除非某些软件的差异过大,用户自行适应一段时间即可。另一方面在 Ubuntu Server 上做大版本升级的时候,我又推荐使用'sudo apt-get dist-upgrade'这种方式,其一没有GUI软件的升级会更平滑,其二以我自己的实践:在 Server 端做这样的升级会相当顺利,运行apt命令以后,只用了半小时就完成了Ubuntu版本的升级和全部软件的更新。
未完待续......