红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 专栏
  3. Linux之旅
  4. 正文

Linux 之旅 6:压缩、打包和备份

2021年8月12日 1040点热度 0人点赞 0条评论

常见的压缩指令

常见的压缩文件与对应的压缩程序的关系:

压缩文件 压缩程序
*.z compress
*.zip zip
*.gz gzip
*.bz2 bzip2
*.xz xz
*.tar tar
*.tar.gz tar-->gzip
*.tar.bz2 tar-->bzip2
*.tar.xz tar-->xz

需要注意的是其中tar只是一个打包程序,可以把多个目录结构和所包含的文件打包成一个文件,但是并不会进行压缩,一般是将tar和其它一种压缩程序结合起来使用,所以上边的tar-->gzip表示用tar打包后使用gzip压缩,这个意思。

其次,在Linux中文件后缀名与具体用什么程序打开文件并没有直接关系,这里的后缀名*.z等仅是为了方便用户进行直观区分而约定的方式。当然你最要沿用这种约定来命名相关压缩后的文件,不要特立独行。

最后要说明的是,目前Linux上常用的压缩应用为gzip、bzip2以及xz,它们的压缩率是逐渐提升的,但压缩速度是逐渐下降的(高压缩率自然意味着更长的压缩时间),而compress是一个早期的压缩工具,已经不怎么使用了。

gzip

gzip是一个使用广泛的压缩应用,并且还支持compress、zip等其它软件产生的压缩文件,其一开始开发的目标是代替老式的compress命令。

使用gzip产生的压缩文件一般使用*.gz来命名。

实际使用一下:

[icexmoon@xyz tmp]$ cp /etc/services .
[icexmoon@xyz tmp]$ ls -alh services
-rw-r--r--. 1 icexmoon icexmoon 655K 8月  11 16:32 services
[icexmoon@xyz tmp]$ gzip -v services
services:        79.7% -- replaced with services.gz
[icexmoon@xyz tmp]$ ls -alh /etc/services ./services*
-rw-r--r--. 1 root     root     655K 6月   7 2013 /etc/services
-rw-r--r--. 1 icexmoon icexmoon 133K 8月  11 16:32 ./services.gz

在压缩的时候使用-v可以输出过程数据,可以看到这里压缩率有79.7%,非常厉害。使用ls对比压缩前后的文件大小也能看到压缩比很惊人。

此外,需要特别注意的是,在默认情况下gzip对源文件压缩完以后,原文件会被删除,这点和Windows下的压缩工具是不同的,当然可以使用一些参数保留原文件,比如这样:

[icexmoon@xyz tmp]$ cp /etc/services .
[icexmoon@xyz tmp]$ gzip services -c > service2.gz
[icexmoon@xyz tmp]$ ls -al /etc/services ./service*
-rw-r--r--. 1 root     root     670293 6月   7 2013 /etc/services
-rw-rw-r--. 1 icexmoon icexmoon 136088 8月  11 16:40 ./service2.gz
-rw-r--r--. 1 icexmoon icexmoon 670293 8月  11 16:39 ./services
-rw-r--r--. 1 icexmoon icexmoon 136088 8月  11 16:32 ./services.gz

虽然gzip并没有直接保留原文件的选项,但是通过-c可以将压缩结果输出到屏幕,并且保留原文件,而我们只需要使用重定向符号>将流重定向到文件service2.gz即可。

因为gzip是一个文本文件,我们甚至可以在不解压的情况下使用其它命令来查看该文件,比如zcat:

[icexmoon@xyz tmp]$ zcat services.gz | head -n 10
# /etc/services:
# $Id: services,v 1.55 2013/04/14 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2013-04-10
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, most entries here have two entries
# even if the protocol doesn't support UDP operations.
# Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports

类似的,还可以进行检索特定字符串:

[icexmoon@xyz tmp]$ zgrep -n http services.gz | head -n 10
14:#       http://www.iana.org/assignments/port-numbers
89:http            80/tcp          www www-http    # WorldWideWeb HTTP
90:http            80/udp          www www-http    # HyperText Transfer Protocol
91:http            80/sctp                         # HyperText Transfer Protocol
197:https           443/tcp                         # http protocol over TLS/SSL
198:https           443/udp                         # http protocol over TLS/SSL
199:https           443/sctp                        # http protocol over TLS/SSL
210:gss-http        488/tcp
211:gss-http        488/udp
555:webcache        8080/tcp        http-alt        # WWW caching service

这里-n参数是给结果标注行号。zgrep和grep的参数用法是完全一样的,zcat也和cat类似,看起来我们只要给常用的操作文本文件的命令前加上一个z就可以变成针对gzip压缩后的文本文件的命令,这样的命令还有zmore、zless等。

还需要说明的是gzip的压缩分为1~9个压缩等级,压缩等级越高就表明压缩比越高,压缩后的文件也越小,默认的压缩等级是6,一般来说就够用了,更高压缩等级也意味着更长的处理时间,如果你的确需要一个更高的压缩比,可以这样:

[icexmoon@xyz tmp]$ gzip -9 -vc /etc/services > services3.gz
/etc/services:   79.8%
[icexmoon@xyz tmp]$ ls -al service*
-rw-rw-r--. 1 icexmoon icexmoon 136088 8月  11 16:40 service2.gz
-rw-r--r--. 1 icexmoon icexmoon 670293 8月  11 16:39 services
-rw-rw-r--. 1 icexmoon icexmoon 135489 8月  11 16:53 services3.gz
-rw-r--r--. 1 icexmoon icexmoon 136088 8月  11 16:32 services.gz

可以看到service3.gz的确是更小了,但也小的有限。压缩算法本来就是个很看具体情况的东西,所以具体提高压缩等级能榨出多少油水取决于你的压缩算法和目标文件。

最后要说的就是解压了:

[icexmoon@xyz tmp]$ gzip -d services3.gz
[icexmoon@xyz tmp]$ ls -al service*
-rw-rw-r--. 1 icexmoon icexmoon 136088 8月  11 16:40 service2.gz
-rw-r--r--. 1 icexmoon icexmoon 670293 8月  11 16:39 services
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 16:53 services3
-rw-r--r--. 1 icexmoon icexmoon 136088 8月  11 16:32 services.gz

使用参数-d(decompress)可以解压缩,可以看到压缩文件services3.gz被解压成了service3。

与压缩一样,默认情况下gzip解压后会删除原压缩文件,这点需要注意。

bzip2

bzip2的功能和用法都与gzip类似,不过拥有更高的压缩比。此外bzip2产生的压缩文件一般使用*.bz2进行命名。

我们看具体案例:

[icexmoon@xyz tmp]$ bzip2 services -cv > services4.bz2
  services:  5.409:1,  1.479 bits/byte, 81.51% saved, 670293 in, 123932 out.
[icexmoon@xyz tmp]$ ls -al service*
-rw-rw-r--. 1 icexmoon icexmoon 136088 8月  11 16:40 service2.gz
-rw-r--r--. 1 icexmoon icexmoon 670293 8月  11 16:39 services
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 16:53 services3
-rw-rw-r--. 1 icexmoon icexmoon 123932 8月  11 17:05 services4.bz2
-rw-r--r--. 1 icexmoon icexmoon 136088 8月  11 16:32 services.gz

可以看到压缩比的确要高于gzip,甚至比gzip最高压缩级别压缩后的文件都要小。

同样,我们可以在不解压的情况下查看文件内容:

[icexmoon@xyz tmp]$ bzcat services4.bz2 | head -n 10
# /etc/services:
# $Id: services,v 1.55 2013/04/14 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2013-04-10
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, most entries here have two entries
# even if the protocol doesn't support UDP operations.
# Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports

类似的,也可以使用bzip2解压:

[icexmoon@xyz tmp]$ bzip2 -d services4.bz2
[icexmoon@xyz tmp]$ ls -al service*
-rw-rw-r--. 1 icexmoon icexmoon 136088 8月  11 16:40 service2.gz
-rw-r--r--. 1 icexmoon icexmoon 670293 8月  11 16:39 services
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 16:53 services3
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 17:05 services4
-rw-r--r--. 1 icexmoon icexmoon 136088 8月  11 16:32 services.gz

xz

xz有着比bzip2更高的压缩比,其一般产生的压缩文件使用*.xz进行命名。

实际测试:

[icexmoon@xyz tmp]$ xz -cv services > services5.xz
services (1/1)
  100 %        97.3 KiB / 654.6 KiB = 0.149
[icexmoon@xyz tmp]$ ls -al service*
-rw-rw-r--. 1 icexmoon icexmoon 136088 8月  11 16:40 service2.gz
-rw-r--r--. 1 icexmoon icexmoon 670293 8月  11 16:39 services
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 16:53 services3
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 17:05 services4
-rw-rw-r--. 1 icexmoon icexmoon 123932 8月  11 17:08 services4.bz2
-rw-rw-r--. 1 icexmoon icexmoon  99608 8月  11 17:12 services5.xz
-rw-r--r--. 1 icexmoon icexmoon 136088 8月  11 16:32 services.gz

可以看到xz的压缩率的确惊人,但这也可能消耗过长的时间。

同样的,可以不解压直接查看文件内容:

[icexmoon@xyz tmp]$ xzcat services5.xz | head -n 10
# /etc/services:
# $Id: services,v 1.55 2013/04/14 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2013-04-10
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, most entries here have two entries
# even if the protocol doesn't support UDP operations.
# Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports

甚至可以查看解压前后的大小:

[icexmoon@xyz tmp]$ xzcat -l services5.xz
Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename
    1       1     97.3 KiB    654.6 KiB  0.149  CRC64   services5.xz

解压:

[icexmoon@xyz tmp]$ xz -d services5.xz
[icexmoon@xyz tmp]$ ls -al service*
-rw-rw-r--. 1 icexmoon icexmoon 136088 8月  11 16:40 service2.gz
-rw-r--r--. 1 icexmoon icexmoon 670293 8月  11 16:39 services
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 16:53 services3
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 17:05 services4
-rw-rw-r--. 1 icexmoon icexmoon 123932 8月  11 17:08 services4.bz2
-rw-rw-r--. 1 icexmoon icexmoon 670293 8月  11 17:12 services5
-rw-r--r--. 1 icexmoon icexmoon 136088 8月  11 16:32 services.gz

关于这三种压缩应用的选择,需要具体情况具体判断,如果极为重视压缩率,而不怎么关心时间消耗,可以使用xz,并选择最高压缩等级,但如果比较关心时间消耗,就可以选择gzip。

tar

如果是开发者,肯定明白“打包”是怎么一回事,发布程序的时候总是要把工程目录下的所有文件打成一个包再发布,当然,往往还会设置一些排除目录和文件,而tar命令就可以做这个事。

前边说了,tar往往还会结合前边介绍的压缩程序,再打包的同时进行压缩。

主要参数

tar命令主要包含以下参数:

  • 运行模式:

    • -c:创建压缩文件

    • -t:查看压缩文件的内容

    • -x:解压缩

  • 所用的压缩程序:

    • -z:使用gzip进行压缩/解压缩

    • -j:使用bzip2进行压缩/解压缩

    • -J:使用xz进行压缩/解压缩

  • 其它:

    • -v:显式运行过程信息

    • -f filename:需要被处理的压缩文件

    • -C 目录:解压时候输出的目录

    • -p(小写):压缩时候保留数据的权限与属性,常用于备份配置文件

    • -P(大写):保留绝对路径

这些参数主要分为三组,第一组用于确定你的执行目的,是要创建压缩文件还是查看压缩文件内容,抑或是解压缩,这三种模式在同一时间只能选一种。第二组是指定压缩/解压缩过程中需要使用的压缩程序,第三组是一些其它的参数。

压缩、查看和解压

我们来看实际效果:

[root@xyz ~]# time tar -cpzv -f /tmp/etc.tar.gz /etc
tar: 从成员名中删除开头的“/”
/etc/
/etc/fstab
/etc/crypttab
/etc/mtab
/etc/resolv.conf
/etc/fonts/
/etc/fonts/conf.d/
/etc/fonts/conf.d/62-google-crosextra-caladea-fontconfig.conf
...省略中间数据...
/etc/scl/conf
/etc/scl/prefixes/

real    0m7.475s
user    0m2.869s
sys     0m2.338s
[root@xyz ~]# ls -al /tmp/etc.tar.gz
-rw-r--r--. 1 root root 12316549 8月  11 20:43 /tmp/etc.tar.gz
[root@xyz ~]# tar -tzv -f /tmp/etc.tar.gz
drwxr-xr-x root/root         0 2021-08-11 20:26 etc/
-rw-r--r-- root/root       902 2021-08-09 16:31 etc/fstab
-rw------- root/root         0 2021-07-24 14:32 etc/crypttab
lrwxrwxrwx root/root         0 2021-07-24 14:32 etc/mtab -> /proc/self/mounts
-rw-r--r-- root/root        78 2021-08-11 20:26 etc/resolv.conf
...省略中间数据...
-rw-r--r-- root/root       750 2020-10-13 23:54 etc/trusted-key.key
-rw-r----- root/root      3181 2020-09-30 21:18 etc/sudo-ldap.conf
-rw-r----- root/root      1786 2020-09-30 21:18 etc/sudo.conf
drwxr-x--- root/root         0 2020-10-01 01:42 etc/sudoers.d/
drwxr-xr-x root/root         0 2021-07-24 14:38 etc/scl/
lrwxrwxrwx root/root         0 2021-07-24 14:38 etc/scl/conf -> prefixes
drwxr-xr-x root/root         0 2018-10-31 03:17 etc/scl/prefixes/
[root@xyz tmp]# tar -xz -f etc.tar.gz
[root@xyz tmp]# ls -ald /tmp/etc
drwxr-xr-x. 139 root root 8192 8月  11 20:26 /tmp/etc
[root@xyz tmp]# ls -al /tmp/etc | head -n 10
总用量 1368
drwxr-xr-x. 139 root root     8192 8月  11 20:26 .
drwxrwxrwt.  25 root root     4096 8月  11 20:50 ..
drwxr-xr-x.   3 root root      101 7月  24 14:35 abrt
-rw-r--r--.   1 root root       16 7月  24 14:45 adjtime
-rw-r--r--.   1 root root     1529 4月   1 2020 aliases
-rw-r--r--.   1 root root    12288 7月  24 14:47 aliases.db
drwxr-xr-x.   3 root root       65 7月  24 14:37 alsa
drwxr-xr-x.   2 root root     4096 7月  24 14:43 alternatives
-rw-------.   1 root root      541 8月   9 2019 anacrontab
[root@xyz tmp]# ls -al etc.tar.gz
-rw-r--r--. 1 root root 12316549 8月  11 20:43 etc.tar.gz

time命令可以输出运行时间。

还是比较简单的,不过有这么几个地方需要注意:

  • -f是一个需要值的参数,即其后必须要跟待处理的打包压缩文件,所以比较好的做法是将其和不用跟值的参数分开来写,这样比较清晰,当然如果你心里能搞清楚,也可以写一起,不过需要注意的是f需要放在最后,比如tar -czvf file_name这样。

  • -p(小写)可以用来保留数据的属性和权限,就像是cp -a一样,而-P(大写)则用于使用绝对路径,在默认情况下tar命令打包时候是会去掉绝对路径的,比如示例中我们打包/etc,可以看到打完的压缩包中是只有tmp目录的,而非/etc,这种区别会导致解压的时候,前者默认会解压到当前目录中,而后者会直接覆盖/etc目录,这当然很危险,所以最好不要使用-P(大写)命令。

仅解压部分文件

此外,我们还可以不全部解压,仅解压其中的部分文件:

[root@xyz tmp]# ls -al etc.tar.gz
-rw-r--r--. 1 root root 12316549 8月  11 20:43 etc.tar.gz
[root@xyz tmp]# tar -tvzf etc.tar.gz | grep shadow
---------- root/root       793 2021-07-24 14:45 etc/gshadow
---------- root/root      1247 2021-07-24 14:45 etc/shadow
---------- root/root       785 2021-07-24 14:45 etc/gshadow-
---------- root/root      1252 2021-07-24 14:45 etc/shadow-
[root@xyz tmp]# tar -xvzf etc.tar.gz etc/shadow
etc/shadow
[root@xyz tmp]# ls -al etc/shadow
----------. 1 root root 1247 7月  24 14:45 etc/shadow

这里我们先使用tar -t结合grep命令查找到想要解压的文件,然后再使用tar -x进行解压。

打包时排除某些文件

我们还可以像打包工程文件那样再打包的时候排除某些文件或目录:

[root@xyz tmp]# tar -czvf system.gz.tar --exclude=/root/etc* --exclude=/root/system.tar.bz2 /etc /root
tar: 从成员名中删除开头的“/”
/etc/
/etc/fstab
/etc/crypttab
/etc/mtab
/etc/resolv.conf
/etc/fonts/
/etc/fonts/conf.d/
/etc/fonts/conf.d/62-google-crosextra-caladea-fontconfig.conf

上面排除了一个目录/root/etc以及一个文件system.tar.bz2,这样做可以避免在备份的时候备份某些重复的内容。

仅备份比某个时刻还新的文件

我们还可以按照“比某个文件还新”这样的目标进行打包:

先用find确认以下会有哪些文件:

[root@xyz tmp]# find /etc -newer /etc/passwd
/etc
/etc/fstab
/etc/resolv.conf
/etc/udev
/etc/udev/hwdb.bin
/etc/ssh
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key.pub
/etc/ssh/ssh_host_ecdsa_key
/etc/ssh/ssh_host_ecdsa_key.pub
/etc/ssh/ssh_host_ed25519_key
/etc/ssh/ssh_host_ed25519_key.pub

查询时间节点,并按时间进行打包:

[root@xyz tmp]# ls -al /etc/passwd
-rw-r--r--. 1 root root 2271 7月  24 14:45 /etc/passwd
[root@xyz tmp]# tar -zcvf etc.newer.then.passwd --newer-mtime="2021/07/24" /etc/*
tar: 选项 --newer-mtime: 将日期 ‘2021/07/24’ 当作 2021-07-24 00:00:00
tar: 从成员名中删除开头的“/”
/etc/abrt/
tar: /etc/abrt/abrt-action-save-package-data.conf: 文件未改变;未输出
tar: /etc/abrt/abrt.conf: 文件未改变;未输出
tar: /etc/abrt/gpg_keys.conf: 文件未改变;未输出
/etc/abrt/plugins/
tar: /etc/abrt/plugins/xorg.conf: 文件未改变;未输出
tar: /etc/abrt/plugins/oops.conf: 文件未改变;未输出
tar: /etc/abrt/plugins/vmcore.conf: 文件未改变;未输出

最后使用tar -t查看打包的结果对不对:

[root@xyz tmp]# tar -tzvf etc.newer.then.passwd | grep -v "/$"
-rw-r--r-- root/root        16 2021-07-24 14:45 etc/adjtime
-rw-r--r-- root/root     12288 2021-07-24 14:47 etc/aliases.db
-rw-r--r-- root/root        54 2021-07-24 14:36 etc/alsa/state-daemon.conf
lrwxrwxrwx root/root         0 2021-07-24 14:37 etc/alsa/conf.d/50-pulseaudio.conf -> /usr/share/alsa/alsa.conf.d/50-pulseaudio.conf
lrwxrwxrwx root/root         0 2021-07-24 14:34 etc/alternatives/ld -> /usr/bin/ld.bfd
lrwxrwxrwx root/root         0 2021-07-24 14:34 etc/alternatives/mkisofs -> /usr/bin/genisoimage
lrwxrwxrwx root/root         0 2021-07-24 14:34 etc/alternatives/mkisofs-mkisofsman -> /usr/share/man/man1/genisoimage.1.gz
lrwxrwxrwx root/root         0 2021-07-24 14:34 etc/alternatives/mkisofs-mkhybrid -> /usr/bin/genisoimage
lrwxrwxrwx root/root         0 2021-07-24 14:34 etc/alternatives/mkisofs-mkhybridman -> /usr/share/man/man1/genisoimage.1.gz
lrwxrwxrwx root/root         0 2021-07-24 14:35 etc/alternatives/cdrecord ->

解压缩后的 SELinux 问题

如果我们是对某些系统目录进行备份,比如说/etc,并且通过解压这个备份的方式进行还原该目录,则可能会导致一些奇怪的问题,比如说无法登录系统。其原因是系统相关文件还涉及一个“SELinux权限”的问题,我们使用备份还原的时候会导致某些文件,比如/etc/passwd的SELinux权限出现问题,进而导致不能登录。

可以通过以下方式进行解决:

  • 通过各种救援模式进行登录,然后修改/etc/selinuex/config文件,将SELinux改为permissive模式,然后重新开机就可以了。

  • 在使用备份复原相应目录后不要立即重启系统,先执行restorecon -Rv /etc自动修复。

  • 通过其它方式登录系统,然后创建/.autorelabel文件,然后重启,系统会自动修复SELinux类型,修复完后会自行重启,之后就正常了。

SFX文件系统的备份和还原

创建备份

关于xfsdump的相关用法,Redhat提供了相当详尽的说明,值得参考3.7. BACKING UP AND RESTORING XFS FILE SYSTEMS

xfsdump命令用于备份xfs文件系统,出了可以进行文件系统的完整备份(full backup)以外,还可以进行增量备份(或者称为累积备份)(incremental backup),也就是说在第一次完整备份之后,我们可以针对完整备份进行增量备份,即只备份在完整备份上增加和减少的部分,这样就可以节省备份所占用的空间。

image-20210811214416405

(图片来自于鸟哥的私房菜)

此外,使用xfsdump还需要注意以下问题:

  • xfsdump不支持没有挂载的文件系统

  • xfsdump需要root权限

  • xfsdump仅能备份xfs文件系统

  • xfsdump产生的备份文件仅能由xfsrestore进行解析

  • xfsdump通过UUID对文件系统进行识别,所以不能同时备份两个UUID相同的文件系统

xfsdump有以下重要的参数:

  • -L:每次备份的session标识,可以填写此文件系统的简要信息

  • -M:存储介质标识,可以填写存储介质的简要说明

  • -l:备份等级,0~9,0为完整备份

  • -f:备份文件名或设备文件名(备份到磁带设备)

  • -I:显式目前的备份信息

  • -i:交互模式

创建完整备份

使用xfsdump创建备份的基础语法:

# xfsdump -l level [-L label] -f backup-destination path-to-xfs-filesystem

其中level为备份等级,label为session标识,backup-destination为备份的目标文件或磁带设备名,path-to-xfs-filesystem为备份的目标文件系统的挂载点。

来实际操作一下:

[root@xyz tmp]# df -h /boot
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda2      1014M  172M  843M   17% /boot
[root@xyz tmp]# xfsdump -l 0 -L boot_all -M boot_all -f /srv/boot.dump /boot
xfsdump: using file dump (drive_simple) strategy
xfsdump: version 3.1.7 (dump format 3.0) - type ^C for status and control
xfsdump: level 0 dump of xyz.icexmoon.centos:/boot
xfsdump: dump date: Wed Aug 11 21:50:50 2021
xfsdump: session id: e45a965d-f4e5-4dd3-a4c1-f227a76b352a
xfsdump: session label: "boot_all"
xfsdump: ino map phase 1: constructing initial dump list
xfsdump: ino map phase 2: skipping (no pruning necessary)
xfsdump: ino map phase 3: skipping (only one dump stream)
xfsdump: ino map construction complete
xfsdump: estimated dump size: 146011776 bytes
xfsdump: /var/lib/xfsdump/inventory created
xfsdump: creating dump session media file 0 (media 0, file 0)
xfsdump: dumping ino map
xfsdump: dumping directories
xfsdump: dumping non-directory files
xfsdump: ending media file
xfsdump: media file size 145687648 bytes
xfsdump: dump size (non-dir files) : 145446072 bytes
xfsdump: dump complete: 8 seconds elapsed
xfsdump: Dump Summary:
xfsdump:   stream 0 /srv/boot.dump OK (success)
xfsdump: Dump Status: SUCCESS
[root@xyz tmp]# ls -al /srv/boot.dump
-rw-r--r--. 1 root root 145687648 8月  11 21:50 /srv/boot.dump
[root@xyz tmp]# ls -al /var/lib/xfsdump/inventory/
总用量 16
drwxr-xr-x. 2 root root  122 8月  11 21:50 .
drwxr-xr-x. 3 root root   23 8月  11 21:50 ..
-rw-r--r--. 1 root root  312 8月  11 21:50 3a6bd73c-8f36-4955-b079-b1e2501efc31.InvIndex
-rw-r--r--. 1 root root 5080 8月  11 21:50 fe38446f-c7c6-40a2-a35a-7c22bebded14.StObj
-rw-r--r--. 1 root root  576 8月  11 21:50 fstab

最后那个/var/lib/xfsdump/inventory/目录是xfsdump用来存放已经制作的备份文件相关的信息(比如说有哪些备份,以及增量备份之间的关系等)。

查看备份信息

如果想查看目前系统有哪些可用备份:

[root@xyz tmp]# xfsdump -I
file system 0:
        fs id:          3a6bd73c-8f36-4955-b079-b1e2501efc31
        session 0:
                mount point:    xyz.icexmoon.centos:/boot
                device:         xyz.icexmoon.centos:/dev/sda2
                time:           Wed Aug 11 21:50:50 2021
                session label:  "boot_all"
                session id:     e45a965d-f4e5-4dd3-a4c1-f227a76b352a
                level:          0
                resumed:        NO
                subtree:        NO
                streams:        1
                stream 0:
                        pathname:       /srv/boot.dump
                        start:          ino 69 offset 0
                        end:            ino 1577745 offset 0
                        interrupted:    NO
                        media files:    1
                        media file 0:
                                mfile index:    0
                                mfile type:     data
                                mfile size:     145687648
                                mfile start:    ino 69 offset 0
                                mfile end:      ino 1577745 offset 0
                                media label:    "boot_all"
                                media id:       dbb6aec4-df26-4fa9-8ff7-16a8e6506965
xfsdump: Dump Status: SUCCESS

可以看到,无论是备份的设备名、挂载点、备份时间以及备份文件保存的路径,都有记录。

创建增量备份

下面我们创建一个增量备份:

[root@xyz tmp]# dd if=/dev/zero of=/boot/testing.img bs=1M count=10
记录了10+0 的读入
记录了10+0 的写出
10485760字节(10 MB)已复制,0.01443 秒,727 MB/秒
[root@xyz tmp]# xfsdump -l 2 -L boot_2 -M boot_2 -f /srv/boot_2.dump /boot
xfsdump: using file dump (drive_simple) strategy
xfsdump: version 3.1.7 (dump format 3.0) - type ^C for status and control
xfsdump: level 2 incremental dump of xyz.icexmoon.centos:/boot based on level 0 dump begun Wed Aug 11 21:50:50 2021
xfsdump: dump date: Wed Aug 11 22:06:27 2021
xfsdump: session id: e4d8ac92-fd04-45bb-bdb3-c6c831a63855
xfsdump: session label: "boot_2"
xfsdump: ino map phase 1: constructing initial dump list
xfsdump: ino map phase 2: pruning unneeded subtrees
xfsdump: ino map phase 3: skipping (only one dump stream)
xfsdump: ino map construction complete
xfsdump: estimated dump size: 10506880 bytes
xfsdump: creating dump session media file 0 (media 0, file 0)
xfsdump: dumping ino map
xfsdump: dumping directories
xfsdump: dumping non-directory files
xfsdump: ending media file
xfsdump: media file size 10510952 bytes
xfsdump: dump size (non-dir files) : 10488408 bytes
xfsdump: dump complete: 7 seconds elapsed
xfsdump: Dump Summary:
xfsdump:   stream 0 /srv/boot_2.dump OK (success)
xfsdump: Dump Status: SUCCESS

这里在/boot下创建了一个10M文件后进行了增量备份。

删除备份

如果你的备份设置错了,比如像我上边的增量备份,备份级别设置为了2,可以使用下边的方式删除备份。

首先确认要删除的备份信息:

[root@xyz ~]# xfsdump -I
...省略...
        session 1:
                mount point:    xyz.icexmoon.centos:/boot
                device:         xyz.icexmoon.centos:/dev/sda2
                time:           Wed Aug 11 22:06:27 2021
                session label:  "boot_2"
                session id:     e4d8ac92-fd04-45bb-bdb3-c6c831a63855
                level:          2
                resumed:        NO
                subtree:        NO
                streams:        1
                stream 0:
                        pathname:       /srv/boot_2.dump
                        start:          ino 113 offset 0
                        end:            ino 114 offset 0
                        interrupted:    NO
                        media files:    1
                        media file 0:
                                mfile index:    0
                                mfile type:     data
                                mfile size:     10510952
                                mfile start:    ino 113 offset 0
                                mfile end:      ino 114 offset 0
                                media label:    "boot_2"
                                media id:       da713227-70e3-40df-9870-8d01d7d464c8

这里要删除的增量备份对应的备份文件是/srv/boot_2.dump。

直接删除文件:

rm -r /srv/boot_2.dump

当然这不算完,因为xfsdump工具产生的数据库信息并没有被删除,使用xfsdump -I就能看到相关信息依然在。

这时候就需要使用xfsinvutil(xfs inventory util)工具:

[root@xyz ~]# xfsinvutil -s e4d8ac92-fd04-45bb-bdb3-c6c831a63855
Processing file /var/lib/xfsdump/inventory/fstab
   Found entry for xyz.icexmoon.centos:/boot
      processing index file
       /var/lib/xfsdump/inventory/3a6bd73c-8f36-4955-b079-b1e2501efc31.InvIndex
         Checking access for
          /var/lib/xfsdump/inventory/fe38446f-c7c6-40a2-a35a-7c22bebded14.StObj
            Session 0: xyz.icexmoon.centos:/boot Wed Aug 11 21:50:50 2021
            Session 1: xyz.icexmoon.centos:/boot Wed Aug 11 22:06:27 2021
                Match on session id
-------------------------------------------------
An entry matching the mount point/time is :
UUID            :       e4d8ac92-fd04-45bb-bdb3-c6c831a63855
MOUNT POINT     :       xyz.icexmoon.centos:/boot
DEV PATH        :       xyz.icexmoon.centos:/dev/sda2
TIME OF DUMP    :       Wed Aug 11 22:06:27 2021

Do you want to prune this entry: [y/n] y
-------------------------------------------------

xfsinvutil需要指定一个备份信息,这里使用-s通过session ID进行指定,然后会检测指定的备份信息是否有效,如果无效(比如备份文件已经不存在了),就会询问是否需要删除相应的数据库信息。

  • 更多关于xfsinvutil的使用方法可以查看xfsinvutil(8) — Linux manual page

  • xfsdump以及xfsrestore都没提供删除备份的功能,在网上找了半天才找到这个方法

还原备份

因为之前已经删除了有问题的增量备份,所以这里需要再创建一份:xfsdump -l 1 -L boot_1 -M boot_1 -f /srv/boot_1.xfsdump /boot

可以使用xfsrestore命令还原xfsdump创建的备份,需要特别注意的是,对于增量备份,我们需要从完整备份开始恢复,按备份级别依次恢复level0~n的备份,n指你想要恢复到的增量版本。

下面我们看实际操作:

我们先查看目标目录是否已经存在,如果已经存在就删除后重新创建一个空目录:

当然实际恢复的时候也不用这样,因为恢复操作会对原目录进行覆盖,这样做只是为了准确地观察恢复效果。

[root@xyz ~]# ls -ald /tmp/boot*
drwxr-xr-x. 2 root root 6 8月  12 10:47 /tmp/boot
[root@xyz ~]# rm -rf /tmp/boot
[root@xyz ~]# mkdir /tmp/boot

进行恢复操作:

[root@xyz ~]# xfsrestore -f /srv/boot.dump -L boot_all /tmp/boot
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.7 (dump format 3.0) - type ^C for status and control
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: examining media file 0
xfsrestore: reading directories
xfsrestore: 11 directories and 337 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: restore complete: 4 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore:   stream 0 /srv/boot.dump OK (success)
xfsrestore: Restore Status: SUCCESS
[root@xyz ~]# xfsrestore -f /srv/boot_1.xfsdump /tmp/boot
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.7 (dump format 3.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: examining media file 0
xfsrestore: dump description:
xfsrestore: hostname: xyz.icexmoon.centos
xfsrestore: mount point: /boot
xfsrestore: volume: /dev/sda2
xfsrestore: session time: Thu Aug 12 12:57:21 2021
xfsrestore: level: 1
xfsrestore: session label: "boot_1"
xfsrestore: media label: "boot_1"
xfsrestore: file system id: 3a6bd73c-8f36-4955-b079-b1e2501efc31
xfsrestore: session id: 8e194ca1-06dc-4ca0-9ca4-bfcd2818e355
xfsrestore: media id: 2a293295-f864-4636-9599-9ee8bde15576
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: 1 directories and 12 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore:   stream 0 /srv/boot_1.xfsdump OK (success)
xfsrestore: Restore Status: SUCCESS
[root@xyz ~]# ls -al /tmp/boot | head -n 10
总用量 136640
drwxr-xr-x.  5 root root     4096 8月  12 14:02 .
drwxrwxrwt. 26 root root     4096 8月  12 14:02 ..
-rw-r--r--.  1 root root   153591 10月 20 2020 config-3.10.0-1160.el7.x86_64
drwx------.  3 root root       17 7月  29 2020 efi
drwxr-xr-x.  2 root root       27 7月  24 14:34 grub
drwx------.  5 root root       97 7月  24 14:47 grub2
-rw-------.  1 root root 79688839 7月  24 14:42 initramfs-0-rescue-f5a85e92d51e4d40975fd956fd775f9c.img
-rw-------.  1 root root 32089078 7月  24 14:47 initramfs-3.10.0-1160.el7.x86_64.img
-rw-r--r--.  1 root root   320648 10月 20 2020 symvers-3.10.0-1160.el7.x86_64.gz

这里依次使用了完整备份和level1的增量备份进行了恢复。

交互模式

xfsrestore还存在一个交互模式,在交互模式下可以查看指定备份的内容,以及进行一些精确操作,比如仅选择部分内容进行还原。

进行实际演示:

[root@xyz ~]# cd /tmp
[root@xyz tmp]# rm -rf boot
[root@xyz tmp]# mkdir boot
[root@xyz tmp]# xfsrestore -i -f /srv/boot.dump ./boot
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.7 (dump format 3.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: examining media file 0
xfsrestore: dump description:
xfsrestore: hostname: xyz.icexmoon.centos
xfsrestore: mount point: /boot
xfsrestore: volume: /dev/sda2
xfsrestore: session time: Wed Aug 11 21:50:50 2021
xfsrestore: level: 0
xfsrestore: session label: "boot_all"
xfsrestore: media label: "boot_all"
xfsrestore: file system id: 3a6bd73c-8f36-4955-b079-b1e2501efc31
xfsrestore: session id: e45a965d-f4e5-4dd3-a4c1-f227a76b352a
xfsrestore: media id: dbb6aec4-df26-4fa9-8ff7-16a8e6506965
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: 11 directories and 337 entries processed
xfsrestore: directory post-processing

 ========================== subtree selection dialog ==========================

the following commands are available:
        pwd
        ls [ <path> ]
        cd [ <path> ]
        add [ <path> ]
        delete [ <path> ]
        extract
        quit
        help

 -> ls
              75 initramfs-3.10.0-1160.el7.x86_64.img
              77 vmlinuz-0-rescue-f5a85e92d51e4d40975fd956fd775f9c
              76 initramfs-0-rescue-f5a85e92d51e4d40975fd956fd775f9c.img
              74 vmlinuz-3.10.0-1160.el7.x86_64
              73 symvers-3.10.0-1160.el7.x86_64.gz
              72 config-3.10.0-1160.el7.x86_64
              71 System.map-3.10.0-1160.el7.x86_64
              70 .vmlinuz-3.10.0-1160.el7.x86_64.hmac
              68 grub/
         1572928 grub2/
              67 efi/

 -> add grub2

 -> cd grub2

 -> ls
    *    1577744 grub.cfg
    *    1577741 grubenv
    *     524357 fonts/
    *         78 locale/
    *    1572930 i386-pc/
    *    1572929 device.map

 -> delete fonts

 -> cd ..

 -> extract

 --------------------------------- end dialog ---------------------------------

xfsrestore: restoring non-directory files
xfsrestore: restore complete: 63 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore:   stream 0 /srv/boot.dump OK (success)
xfsrestore: Restore Status: SUCCESS
[root@xyz tmp]# ls -al boot/grub2/
总用量 32
drwx------. 4 root root   84 7月  24 14:47 .
drwxr-xr-x. 3 root root   19 8月  12 14:11 ..
-rw-r--r--. 1 root root   84 7月  24 14:45 device.map
-rw-r--r--. 1 root root 4309 7月  24 14:47 grub.cfg
-rw-r--r--. 1 root root 1024 7月  24 14:47 grubenv
drwxr-xr-x. 2 root root 8192 7月  24 14:45 i386-pc
drwxr-xr-x. 2 root root 4096 7月  24 14:45 locale
[root@xyz tmp]# ls -al boot
总用量 4
drwxr-xr-x.  3 root root   19 8月  12 14:11 .
drwxrwxrwt. 26 root root 4096 8月  12 14:12 ..
drwx------.  4 root root   84 7月  24 14:47 grub2

需要注意的是,在交互模式下的add和delete命令的作用都是将目标目录或文件添加或删除到要恢复的列表中,并不是对备份文件本身进行增加和删除。

示例中我的操作目的是仅恢复boot/grub2这个目录,且排除boot/grub2/fonts目录。

光盘写入工具

虽然现在这个时代用到实体光盘或者镜像文件的地方已经越来越少了,但依然需要了解一下Linux中如何处理光盘和镜像文件,以防的确需要用到的情况出现。

创建镜像文件

命令mkisofs用于将一个或多个目录制作为镜像文件,常用的有以下参数:

  • -o iso_file:输出的镜像文件名

  • -r:通过 Rock Ridge 产生支持 Unix/Linux 的文件数据,可记录较多的信息(如 UID/GID等)

  • -v:显式过程信息

  • -m file:排除文件或目录(不包含到镜像中)

制作一般数据镜像文件

我们看实际演示:

[root@xyz tmp]# mkisofs -v -r -o system.img /root /etc /home
...省略...
 96.88% done, estimate finish Thu Aug 12 14:29:49 2021
 97.90% done, estimate finish Thu Aug 12 14:29:49 2021
 98.92% done, estimate finish Thu Aug 12 14:29:49 2021
 99.94% done, estimate finish Thu Aug 12 14:29:49 2021
Total translation table size: 0
Total rockridge attributes bytes: 504456
Total directory bytes: 2111488
Path table size(bytes): 13524
Done with: The File(s)                             Block(s)    489071
Writing:   Ending Padblock                         Start Block 490168
Done with: Ending Padblock                         Block(s)    150
Max brk space used 492000
490318 extents written (957 MB)
[root@xyz tmp]# ls -alh system.img
-rw-r--r--. 1 root root 958M 8月  12 14:29 system.img

挂载镜像,并查看镜像内容:

[root@xyz tmp]# mount -o loop system.img /mnt
mount: /dev/loop0 写保护,将以只读方式挂载
[root@xyz tmp]# ls -al /mnt
总用量 1407
dr-xr-xr-x. 144 root root  38912 7月  29 16:51 .
dr-xr-xr-x.  18 root root    236 8月   8 21:41 ..
dr-xr-xr-x.   3 root root   2048 7月  24 14:35 abrt
-r--r--r--.   1 root root     16 7月  24 14:45 adjtime
-r--r--r--.   1 root root   1529 4月   1 2020 aliases
-r--r--r--.   1 root root  12288 7月  24 14:47 aliases.db
dr-xr-xr-x.   3 root root   2048 7月  24 14:37 alsa
dr-xr-xr-x.   2 root root  16384 7月  24 14:43 alternatives
-r--r--r--.   1 root root   1798 7月  24 14:47 anaconda-ks.cfg
-r--r--r--.   1 root root    541 8月   9 2019 anacrontab
-r--r--r--.   1 root root     55 8月   8 2019 asound.conf

可以看到我们备份的三个目录下的内容都杂乱堆在镜像文件中,并不是按照三个目录分别组织的,如果我们需要那样的结果,可以这样:

[root@xyz tmp]# mkisofs -r -v -o system2.img -m /root/etc -graf-point /root=/root /home=/home /etc=/etc
genisoimage: unrecognized option '-af-point'
Usage: genisoimage [options] -o file directory ...

Use genisoimage -help
to get a list of valid options.

Report problems to debburn-devel@lists.alioth.debian.org.
[root@xyz tmp]# mkisofs -r -v -o system2.img -m /root/etc -graft-point /root=/root /home=/home /etc=/etc
I: -input-charset not specified, using utf-8 (detected in locale settings)
genisoimage 1.1.11 (Linux)
Scanning /root
Scanning /root/.cache
Scanning /root/.cache/dconf
Scanning /root/.cache/abrt
Scanning /root/.dbus
Scanning /root/.dbus/session-bus
Scanning /root/.config
...省略...
Total directory bytes: 2152448
Path table size(bytes): 13560
Done with: The File(s)                             Block(s)    489071
Writing:   Ending Padblock                         Start Block 490170
Done with: Ending Padblock                         Block(s)    150
Max brk space used 496000
490320 extents written (957 MB)
[root@xyz tmp]# umount /mnt
[root@xyz tmp]# mount -o loop system2.img /mnt
mount: /dev/loop0 写保护,将以只读方式挂载
[root@xyz tmp]# ls -al /mnt
总用量 44
dr-xr-xr-x.   6 root root  2048 8月  12 14:38 .
dr-xr-xr-x.  18 root root   236 8月   8 21:41 ..
dr-xr-xr-x. 139 root root 36864 8月  12 13:58 etc
dr-xr-xr-x.   3 root root  2048 7月  24 14:45 home
dr-xr-xr-x.   5 root root  2048 7月  29 16:51 root
dr-xr-xr-x.  14 root root  2048 8月  12 14:38 rr_moved
[root@xyz tmp]# ls -al /mnt/rr_moved/
总用量 4
dr-xr-xr-x. 14 root root 2048 8月  12 14:38 .
dr-xr-xr-x.  6 root root 2048 8月  12 14:38 ..
[root@xyz tmp]# umount /mnt

加入参数-graf-point之后我们就可以通过/root=/root的方式指定镜像中的目录对应的被备份的目录的映射,从而让产生的镜像中的目录更有层次。

比较有意思的是产出的镜像中多了一个空目录rr_moved,也不知道是做什么用的。

此外这里使用-m参数排除了一个目录,该目录也就不会出现在产生的镜像文件中。

当然如果你不想怎么麻烦,而且需要备份的目录也不大,完全可以将需要备份的内容都复制到一个目录中,然后再直接使用mkisofs备份整个目录就可以了。

制作/修改可开机光盘镜像

制作可以自启动的光盘与一般性数据光盘有所不同,需要指定自启动程序,这里仅提供一个命令示例:

 mkisofs -o /custom.iso -b isolinux/isolinux.bin -c isolinux/boot.cat \
-no-emul-boot -V 'CentOS 7 x86_64' -boot-load-size 4 -boot-info-table -R -J -v -T .

光盘烧录工具

Linux上老式的光盘烧录工具是cdrecord,目前CentOS7使用的是wodim,但因为我使用的是虚拟机,并不能真正进行光盘烧录,自然可以就没法演示,而且目前的个人电脑也基本都不会带光驱,刻录光盘的需求也基本没有,所以这部分内容略去。

其它常见的压缩与备份工具

dd

之前也有使用过这个工具,可以创建一定大小的文件,而dd本身也可以用来备份数据,并且与之前介绍的tar或者xfsdump不同的是,dd可以无视文件系统类型,按照扇区进行一对一完全克隆。

dd的一般用法如下:

dd if="input_file" of="output_file" bs="block_size" count="number"

几个参数的意义很简单,这里不过多解释,需要特别说明的是如果bs没有指定,默认大小为512 Bytes。

在一众Linux命令中dd的参数使用方式最为特立独行,居然不是--if=="input_file"这种常见样式。

这里看实际使用:

备份一个文件

[root@xyz tmp]# dd if=/etc/passwd of=passwd.dd
记录了4+1 的读入
记录了4+1 的写出
2271字节(2.3 kB)已复制,0.000254694 秒,8.9 MB/秒
[root@xyz tmp]# ls -al /etc/passwd passwd.dd
-rw-r--r--. 1 root root 2271 7月  24 14:45 /etc/passwd
-rw-r--r--. 1 root root 2271 8月  12 14:59 passwd.dd
[root@xyz tmp]# cat passwd.dd | head -n 10
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

需要注意的是使用dd产生的备份文件大小并不相同。

备份光盘

这里使用以前制作的一个镜像,并用虚拟机加载后进行演示:

[root@xyz tmp]# dd if=/dev/sr0 of=my_music.dd.iso
记录了1703084+0 的读入
记录了1703084+0 的写出
871979008字节(872 MB)已复制,14.8442 秒,58.7 MB/秒
[root@xyz tmp]# ls -al my_music.dd.iso
-rw-r--r--. 1 root root 871979008 8月  12 15:07 my_music.dd.iso
[root@xyz tmp]# mount -o loop my_music.dd.iso /mnt
mount: /dev/loop0 写保护,将以只读方式挂载
[root@xyz tmp]# ls -al /mnt
总用量 16
dr-xr-xr-x.  1 root root  2048 8月   9 11:18 .
dr-xr-xr-x. 18 root root   236 8月   8 21:41 ..
dr-xr-xr-x.  1 root root 14336 8月   9 11:18 music
[root@xyz tmp]# ls -al /mnt/music/ | head -n 10
总用量 851373
dr-xr-xr-x. 1 root root    14336 8月   9 11:18 .
dr-xr-xr-x. 1 root root     2048 8月   9 11:18 ..
-r-xr-xr-x. 1 root root  9711036 12月  3 2020 Actium - Here With You.mp3
-r-xr-xr-x. 1 root root 10252755 12月  3 2020 again.mp3
-r-xr-xr-x. 1 root root     8896 3月  24 11:15 Alternative ending,ARM - チルノのパーフェクトさんすう教室.lrc
-r-xr-xr-x. 1 root root 12875222 12月  3 2020 Alternative ending,ARM - チルノのパーフェクトさんすう教室.mp3
-r-xr-xr-x. 1 root root     3324 3月  24 11:20 angela - 騎士行進曲.lrc
-r-xr-xr-x. 1 root root 11508174 12月  3 2020 angela - 騎士行進曲.mp3
-r-xr-xr-x. 1 root root     1966 3月  24 11:25 bassy_ 茶太 - 夕日.lrc
[root@xyz tmp]# umount /mnt

将镜像烧录进U盘

使用dd命令我们可以将镜像文件烧录进U盘,比如:

 dd if=/tmp/system.iso of=/dev/sda

这里的/dev/sda是一个外接U盘,需要注意的是U盘容量必须要大于镜像的大小,此外,因为dd命令是以扇区为单位完全克隆,所以上面的命令执行之后你的U盘就完全相当于那个镜像文件了,U盘剩余的空间会被浪费。

我们可以使用这种方式烧录一个Linux系统安装U盘。

因为手头没有空闲U盘,这里不做实际演示。

备份整个文件系统

上边说过了,dd命令可以无视文件系统格式,对扇区进行拷贝,所以当然也可以用来完整备份任意类型的文件系统:

[root@xyz tmp]# df -h /boot
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda2      1014M  182M  833M   18% /boot
Try 'dd --help' for more information.
[root@xyz tmp]# dd if=/dev/sda2 of=boot.sda2.dd.img
记录了2097152+0 的读入
记录了2097152+0 的写出
1073741824字节(1.1 GB)已复制,6.78263 秒,158 MB/秒
[root@xyz tmp]# ls -al boot.sda2.dd.img
-rw-r--r--. 1 root root 1073741824 8月  12 15:19 boot.sda2.dd.img
[root@xyz tmp]# ls -alh boot.sda2.dd.img
-rw-r--r--. 1 root root 1.0G 8月  12 15:19 boot.sda2.dd.img
[root@xyz tmp]# mount -o loop boot.sda2.dd.img /mnt

虽然/dev/sda2文件系统只使用了182M,但是因为我们的dd是按扇区进行拷贝,所以产生的备份也有1G。

在Linux 之旅 5:磁盘与文件系统管理中我们介绍了如何创建大型文件,并格式化后挂载当作普通的文件系统进行使用,当然这里也可以用同样的方式来挂载这个备份。

因为备份文件的UUID必然是和已有的dev/sda2重复的,所以这里需要先指定一个新的UUID:

[root@xyz tmp]# blkid boot.sda2.dd.img
boot.sda2.dd.img: UUID="3a6bd73c-8f36-4955-b079-b1e2501efc31" TYPE="xfs"
[root@xyz tmp]# uuidgen
ce217c34-027b-4704-b7a7-ae2c3b42ed0f
[root@xyz tmp]# xfs_admin -U ce217c34-027b-4704-b7a7-ae2c3b42ed0f boot.sda2.dd.img
Clearing log and setting UUID
writing all SBs
new UUID = ce217c34-027b-4704-b7a7-ae2c3b42ed0f

在确认一下是否真的和已有的UUID没冲突:

[root@xyz tmp]# blkid
/dev/sr0: UUID="2021-08-09-11-18-01-00" LABEL="20210809_111500" TYPE="iso9660"
/dev/sda2: UUID="3a6bd73c-8f36-4955-b079-b1e2501efc31" TYPE="xfs" PARTUUID="af480520-bc6b-458a-be30-954f7cd1fdbe"
/dev/sda3: UUID="z8yElP-WmqU-RW58-aQED-CexZ-238I-4n5JAu" TYPE="LVM2_member" PARTUUID="1aab14fb-e456-4559-8e25-e15539e763b9"
/dev/sda4: UUID="035911b7-d304-4217-97a4-84a57bad98eb" TYPE="xfs" PARTLABEL="Linux filesystem" PARTUUID="30bcb458-e75b-429e-9ef1-8ee779a8af04"
/dev/mapper/centos-root: UUID="9cfac9d8-a7d6-46e5-86ff-5843cc384ae6" TYPE="xfs"
/dev/mapper/centos-swap: UUID="1081ba0b-2e6b-47ab-be81-b136755a2744" TYPE="swap"
/dev/mapper/centos-home: UUID="9cc15746-fc30-4952-bf16-a248415fbebd" TYPE="xfs"
/tmp/boot.sda2.dd.img: UUID="ce217c34-027b-4704-b7a7-ae2c3b42ed0f" TYPE="xfs"
/dev/sda1: PARTUUID="beba03a1-011f-4237-9848-96c3b46bbad7"

挂载:

[root@xyz tmp]# mount -U ce217c34-027b-4704-b7a7-ae2c3b42ed0f /mnt
[root@xyz tmp]# df -h /mnt
文件系统        容量  已用  可用 已用% 挂载点
/dev/loop0     1014M  182M  833M   18% /mnt
[root@xyz tmp]# ls -al /mnt
总用量 136636
dr-xr-xr-x.  5 root root     4096 8月  11 22:04 .
dr-xr-xr-x. 18 root root      236 8月   8 21:41 ..
-rw-r--r--.  1 root root   153591 10月 20 2020 config-3.10.0-1160.el7.x86_64
drwx------.  3 root root       17 7月  29 2020 efi
drwxr-xr-x.  2 root root       27 7月  24 14:34 grub
drwx------.  5 root root       97 7月  24 14:47 grub2
-rw-------.  1 root root 79688839 7月  24 14:42 initramfs-0-rescue-f5a85e92d51e4d40975fd956fd775f9c.img
-rw-------.  1 root root 32089078 7月  24 14:47 initramfs-3.10.0-1160.el7.x86_64.img
-rw-r--r--.  1 root root   320648 10月 20 2020 symvers-3.10.0-1160.el7.x86_64.gz
-rw-------.  1 root root  3616707 10月 20 2020 System.map-3.10.0-1160.el7.x86_64
-rw-r--r--.  1 root root 10485760 8月  11 22:04 testing.img
-rwxr-xr-x.  1 root root  6769256 7月  24 14:42 vmlinuz-0-rescue-f5a85e92d51e4d40975fd956fd775f9c
-rwxr-xr-x.  1 root root  6769256 10月 20 2020 vmlinuz-3.10.0-1160.el7.x86_64
-rw-r--r--.  1 root root      167 10月 20 2020 .vmlinuz-3.10.0-1160.el7.x86_64.hmac
[root@xyz tmp]# umount /mnt

因为这个镜像很占地方,所以可以用完后删除:

[root@xyz tmp]# rm boot.sda2.dd.img
rm:是否删除普通文件 "boot.sda2.dd.img"?y

出了上面演示的可以将整个文件系统备份到一个文件以外,还可以将整个文件系统备份到另一个分区:

这里省略使用gdisk新建一个1.6G大小的分区dev/sda5的过程。

[root@xyz tmp]# lsblk
NAME            MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda               8:0    0    40G  0 disk
├─sda1            8:1    0     2M  0 part
├─sda2            8:2    0     1G  0 part /boot
├─sda3            8:3    0    30G  0 part
│ ├─centos-root 253:0    0    10G  0 lvm  /
│ ├─centos-swap 253:1    0     1G  0 lvm  [SWAP]
│ └─centos-home 253:2    0     5G  0 lvm  /home
├─sda4            8:4    0     1G  0 part /srv/myproject
└─sda5            8:5    0   1.6G  0 part
sr0              11:0    1 831.6M  0 rom
[root@xyz tmp]# df -h /boot
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda2      1014M  182M  833M   18% /boot
[root@xyz tmp]# dd if=/dev/sda2 of=/dev/sda5
记录了2097152+0 的读入
记录了2097152+0 的写出
1073741824字节(1.1 GB)已复制,40.6834 秒,26.4 MB/秒
[root@xyz tmp]# xfs_repair -L /dev/sda5
Phase 1 - find and verify superblock...
Phase 2 - using internal log
        - zero log...
        - scan filesystem freespace and inode maps...
        - found root inode chunk
Phase 3 - for each AG...
        - scan and clear agi unlinked lists...
        - process known inodes and perform inode discovery...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - process newly discovered inodes...
Phase 4 - check for duplicate blocks...
        - setting up duplicate extent list...
        - check for inodes claiming duplicate blocks...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
Phase 5 - rebuild AG headers and trees...
        - reset superblock...
Phase 6 - check inode connectivity...
        - resetting contents of realtime bitmap and summary inodes
        - traversing filesystem ...
        - traversal finished ...
        - moving disconnected inodes to lost+found ...
Phase 7 - verify and correct link counts...
Maximum metadata LSN (1:3546) is ahead of log (1:2).
Format log to cycle 4.
done
[root@xyz tmp]# uuidgen
31a4d543-5f19-45e9-b389-0611ee61dfbe
[root@xyz tmp]# xfs_admin -U 31a4d543-5f19-45e9-b389-0611ee61dfbe /dev/sda5
Clearing log and setting UUID
writing all SBs
new UUID = 31a4d543-5f19-45e9-b389-0611ee61dfbe
[root@xyz tmp]# mount /dev/sda5 /mnt
[root@xyz tmp]# df -h /mnt
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda5      1014M  182M  833M   18% /mnt
[root@xyz tmp]# xfs_growfs /mnt
meta-data=/dev/sda5              isize=512    agcount=4, agsize=65536 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 262144 to 409600
[root@xyz tmp]# df -h /mnt
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda5       1.6G  182M  1.4G   12% /mnt
[root@xyz tmp]# umount /mnt

整个过程与上边的挂载文件备份类似,有意思的是因为我们这里的备份分区大小远大于原分区,所以有600M左右空间被浪费了,此时可以使用xfs_growfs命令进行扩容。

最后不要忘记删除/dev/sda5分区,以便后续的教学内容。

此外还要注意的是对于dd备份的完整文件系统,无论是大文件还是另一个分区,我们都没有再格式化,这是因为dd按扇区复制,自然也将文件系统之类的超级区块等所有内容复制了过来,自然无需再次格式化。

cpio

cpio可以备份任何东西,包括设备文件,不过有个问题就是不会自行查找需要备份的内容,所以我们需要使用额外的命令,比如find为其指明需要备份的内容。

看实际演示:

[root@xyz ~]# cd /
[root@xyz /]# find boot | cpio -ocvB > /tmp/boot.cpio
boot
boot/efi
boot/efi/EFI
boot/efi/EFI/centos
boot/efi/EFI/centos/BOOT.CSV
boot/efi/EFI/centos/BOOTX64.CSV
boot/efi/EFI/centos/MokManager.efi
boot/efi/EFI/centos/mmx64.efi
boot/efi/EFI/centos/shim.efi
boot/efi/EFI/centos/shimx64-centos.efi
boot/efi/EFI/centos/shimx64.efi
boot/efi/EFI/centos/fw
boot/efi/EFI/centos/fwupia32.efi
boot/efi/EFI/centos/fwupx64.efi
boot/efi/EFI/BOOT
...省略...
boot/initramfs-0-rescue-f5a85e92d51e4d40975fd956fd775f9c.img
boot/vmlinuz-0-rescue-f5a85e92d51e4d40975fd956fd775f9c
boot/initramfs-3.10.0-1160.el7.x86_64.img
boot/testing.img
30419 块
[root@xyz /]# ls -alh /tmp/boot.cpio
-rw-r--r--. 1 root root 149M 8月  12 16:04 /tmp/boot.cpio
[root@xyz /]# file /tmp/boot.cpio
/tmp/boot.cpio: ASCII cpio archive (SVR4 with no CRC)

这里有一个细节,即我们是先切换目录到/再使用find boot查找/boot下的文件,而非是直接查找,这两者的区别是,如果直接查找:

[root@xyz /]# find /boot | head -n 10
/boot
/boot/efi
/boot/efi/EFI
/boot/efi/EFI/centos
/boot/efi/EFI/centos/BOOT.CSV
/boot/efi/EFI/centos/BOOTX64.CSV
/boot/efi/EFI/centos/MokManager.efi
/boot/efi/EFI/centos/mmx64.efi
/boot/efi/EFI/centos/shim.efi
/boot/efi/EFI/centos/shimx64-centos.efi

查找出的路径是完整路径,如果用这种数据让cpio进行备份,则其备份的结果也会是完整路径,类似于tar -P的结果,这样会在使用备份还原的时候直接覆盖相应的路径,而不能指定目录进行还原,比较危险。

如果是切换到/再使用find boot查找:

[root@xyz /]# find boot | head -n 10
boot
boot/efi
boot/efi/EFI
boot/efi/EFI/centos
boot/efi/EFI/centos/BOOT.CSV
boot/efi/EFI/centos/BOOTX64.CSV
boot/efi/EFI/centos/MokManager.efi
boot/efi/EFI/centos/mmx64.efi
boot/efi/EFI/centos/shim.efi
boot/efi/EFI/centos/shimx64-centos.efi

可以看到输出的是相对路径,交给cpio处理就不会有上面的问题了。

还原:

[root@xyz /]# cd tmp
[root@xyz tmp]# ls -al boot*
-rw-r--r--. 1 root root 155745280 8月  12 16:04 boot.cpio
[root@xyz tmp]# cpio -idvc < boot.cpio
boot
boot/efi
boot/efi/EFI
boot/efi/EFI/centos
boot/efi/EFI/centos/BOOT.CSV
boot/efi/EFI/centos/BOOTX64.CSV
boot/efi/EFI/centos/MokManager.efi
boot/efi/EFI/centos/mmx64.efi
boot/efi/EFI/centos/shim.efi
boot/efi/EFI/centos/shimx64-centos.efi
boot/efi/EFI/centos/shimx64.efi
...省略...
[root@xyz tmp]# ls -ald boot*
dr-xr-xr-x. 5 root root      4096 8月  12 16:13 boot
-rw-r--r--. 1 root root 155745280 8月  12 16:04 boot.cpio

cpio并不是特别好用,但因为其可以备份/dev下的任何设备文件,所以依然有一席之地。

关于所有压缩和备份相关的内容都介绍完毕了,谢谢阅读。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: Linux 压缩 备份 打包
最后更新:2021年8月12日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号