一篇文章教你学会数据备份利器rsync

发布时间 2023-04-25 13:30:10作者: Linux运维阿铭

 

作为一个系统管理员,数据备份是非常重要的。阿铭有一次没有做好备份策略,结果磁盘坏了,数据全部丢失。所以在以后的系统维护工作中,你一定要时刻牢记给数据做备份。

在Linux系统下数据备份的工具很多,但阿铭只用一种,那就是rsync,从字面意思上可以理解为remote sync(远程同步)。rsync不仅可以远程同步数据(类似于scp),而且可以本地同步数据(类似于cp),但不同于cp或scp的一点是,它不会覆盖以前的数据(如果数据已经存在),而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。如果你的Linux没有rsync命令,请使用命令yum install -y rsync安装。下面阿铭先举一个例子,然后再详细讲解rsync的用法。
# rsync -av /etc/passwd /tmp/1.txtsending incremental file listpasswd 
sent 1,205 bytes received 35 bytes  2,480.00 bytes/sectotal size is 1,113 speedup is 0.90
上例将会把/etc/passwd同步到/tmp/目录下,并改名为1.txt。如果是远程复制,数据备份就是这样的形式——IP:path,比如192.168.72.128:/root/。具体用法如下:
# rsync -av /etc/passwd 192.168.72.128:/tmp/1.txtThe authenticity of host '192.168.72.128 (192.168.72.128)' can't be established.ECDSA key fingerprint is SHA256:gFHUJnoZAjOcnG95pt7Zg9iaPZGDiOrbZyssZtRoQhA.Are you sure you want to continue connecting (yes/no/[fingerprint])? yesWarning: Permanently added '192.168.72.128' (ECDSA) to the list of known hosts.root@192.168.72.128's password:sending incremental file list
sent 45 bytes received 12 bytes  8.77 bytes/sectotal size is 1,113 speedup is 19.53
首次连接时会提示是否要继续连接,我们输入yes继续。当建立连接后,需要输入密码。如果手动执行这些操作比较简单,但若是写在脚本中该怎么办呢?这就涉及添加信任关系了,该部分内容稍后会详细介绍。14.7.1 rsync的命令格式
rsync [OPTION]... SRC DESTrsync [OPTION]... SRC [USER@]HOST:DESTrsync [OPTION]...  [USER@]HOST:SRC DESTrsync [OPTION]... [USER@]HOST::SRC DESTrsync [OPTION]... SRC [USER@]HOST::DEST
在阿铭前面举的两个例子中,第一个例子为第一种格式,第二个例子为第二种格式。但不同的是,阿铭并没有加user@host,如果不加默认指的是root。第三种格式是从远程目录同步数据到本地。第四种和第五种格式使用了两个冒号,这种格式和其他格式的验证方式不同。14.7.2 rsync常用选项rsync命令各选项的含义如下。
  • -a:这是归档模式,表示以递归方式传输文件,并保持所有属性,它等同于-rlptgoD。-a选项后面可以跟一个--no-OPTION,表示关闭-rlptgoD中的某一个,比如-a--no-l等同于-rptgoD。
  • -r:表示以递归模式处理子目录。它主要是针对目录来说的,如果单独传一个文件不需要加-r选项,但是传输目录时必须加。
  • -v:表示打印一些信息,比如文件列表、文件数量等。
  • -l:表示保留软连接。
  • -L:表示像对待常规文件一样处理软连接。如果是SRC中有软连接文件,则加上该选项后,将会把软连接指向的目标文件复制到DST。
  • -p:表示保持文件权限。
  • -o:表示保持文件属主信息。
  • -g:表示保持文件属组信息。
  • -D:表示保持设备文件信息。
  • -t:表示保持文件时间信息。
  • --delete:表示删除DST中SRC没有的文件。
  • --exclude=PATTERN:表示指定排除不需要传输的文件,等号后面跟文件名,可以是万用字符模式(如*.txt)。
  • --progress:表示在同步的过程中可以看到同步的过程状态,比如统计要同步的文件数量、同步的文件传输速度等。
  • -u:表示把DST中比SRC还新的文件排除掉,不会覆盖。
  • -z:加上该选项,将会在传输过程中压缩
选项虽然多,但阿铭常用的选项也就-a、-v、-z、--delete和--exclude这几个,请牢记它们!下面阿铭将会针对这些选项做一系列小试验。1. 建立目录和文件过程如下所示:
# mkdir rsync# cd rsync# mkdir test1# cd test1# touch 1 2 3/root/123.txt# ln -s/root/123.txt ./123.txt# ls -l总用量 0-rw-r--r-- 1 rootroot 0 6月  26 17:30 1lrwxrwxrwx 1 rootroot 13 6月  26 17:30 123.txt ->/root/123.txt-rw-r--r-- 1 rootroot 0 6月  26 17:30 2-rw-r--r-- 1 rootroot 0 6月  26 17:30 3# cd ..
阿铭建立这些文件的目的就是为后续试验做一些准备工作。2. 使用-a选项首先来看看-a选项的用法,如下所示:
# rsync -a test1 test2# ls test2 test1# ls test2/test1/1 123.txt 2  3
这里有一个问题,就是本来想把test1目录直接复制成test2目录,可结果rsync却新建了test2目录,然后把test1放到test2当中。为了避免这样的情况发生,可以这样做:
# rm -rf test2# rsync -a test1/ test2/# ls -l test2/总用量 0-rw-r--r-- 1 rootroot 0 6月  26 17:30 1lrwxrwxrwx 1 rootroot 13 6月  26 17:30 123.txt -> /root/123.txt-rw-r--r-- 1 root root 0 6月  26 17:30 2-rw-r--r-- 1 root root 0 6月  26 17:30 3
这里加一个斜杠就好了,所以阿铭建议你在使用rsync备份目录时,要养成加斜杠的习惯。前面已经讲了-a选项等同于-rlptgoD,且-a还可以和--no-OPTIN一并使用。下面再来看看-l选项的作用,如下所示:
# rm -rf test2# rsync -av --no-l test1/ test2/sending incremental file listcreated directory test2skipping non-regular file "123.txt"./123sent 234 bytes received 144 bytes  756.00 bytes/sectotal size is 13 speedup is 0.03
上例中使用了-v选项,跳过了非普通文件123.txt。其实123.txt是一个软连接文件,如果不使用-l选项,系统则不理会软连接文件。虽然加-l选项能复制软连接文件,但软连接的目标文件却没有复制。有时我们需要复制软连接文件所指向的目标文件,这又该怎么办呢?3. 使用-L选项具体用法如下:
# rm -rf test2# rsync -avL test1/ test2/sending incremental file listcreated directory test2./1123.txt23sent 265 bytes received 123 bytes  776.00 bytes/sectotal size is 0 speedup is 0.00# ls -l test2/总用量 0-rw-r--r-- 1 root root 0 6月  26 17:30 1-rw-r--r-- 1 root root 0 6月  26 17:30 123.txt-rw-r--r-- 1 root root 0 6月  26 17:30 2-rw-r--r-- 1 root root 0 6月  26 17:30 3
上例加上-L选项就可以把SRC中软连接的目标文件复制到DST。4. 使用-u选项首先查看一下test1/1和test2/1的创建时间(肯定是一样的),然后使用touch修改一下test2/1的创建时间(此时test2/1要比test1/1的创建时间晚一些)。如果不加-u选项,会把test2/1的创建时间变成和test1/1一样,如下所示:
# ll test1/1 test2/1-rw-r--r-- 1 root root 0 6月  26 17:30 test1/1-rw-r--r-- 1 root root 0 6月  26 17:30 test2/1
从上例可以看出二者的创建时间是一样的。下面修改test2/1的创建时间,然后不加-u同步,如下所示:
# echo "1111" > test2/1# ll test2/1- rw-r--r-- 1 root root 5 6月  26 17:33 test2/1# rsync -a test1/1 test2/# ll test2/1-rw-r--r-- 1 root root 0 6月  26 17:30 test2/1
这里test2/1的创建时间还是和test1/1一样。下面加上-u选项,如下所示:
# echo "1111" > test2/1# ll test2/1-rw-r--r-- 1 root root 5 6月  26 17:34 test2/1# rsync -avu test1/ test2/sending incremental file list./123.txt -> /root/123.txtsent 134 bytes received 22 bytes  312.00 bytes/sectotal size is 13 speedup is 0.08# ll test1/1 test2/1-rw-r--r-- 1 root root 0 6月  26 17:30 test1/1-rw-r--r-- 1 root root 5 6月  26 17:34 test2/1
加上-u选项后,不会再把test1/1同步为test2/1了。5. 使用--delete选项首先删除test1/123.txt,如下所示:
# rm -f test1/123.txt# ls test1/1 2  3
然后把test1/目录同步到test2/目录下,如下所示:
# rsync -av test1/ test2/sending incremental file list./1sent 130 bytes received 38 bytes  336.00 bytes/sectotal size is 0 speedup is 0.00# ls test2/1 123.txt 2  3
上例中,test2/目录并没有删除123.txt。下面加上--delete选项,示例如下:
# rsync -av --delete test1/ test2/sending incremental file listdeleting 123.txtsent 84 bytes received 23 bytes  214.00 bytes/sectotal size is 0 speedup is 0.00# ls test2/1 2  3
这里test2/目录下的123.txt也被删除了。另外还有一种情况,就是如果在DST中增加文件了,而SRC当中没有这些文件,同步时加上--delete选项后同样会删除新增的文件。如下所示:
# touch test2/4# ls test1/1 2  3# ls test2/1 2 3  4# rsync -a --delete test1/ test2/# ls test1/1 2  3# ls test2/1 2  3
6. 使用--exclude选项具体用法如下:
# touch test1/4# rsync -a --exclude="4" test1/ test2/# ls test1/1 2 3  4# ls test2/1 2  3
该选项还可以与匹配字符*一起使用,如下所示:
# touch test1/1.txt test1/2.txt# ls test1/1 1.txt 2  2.txt  3  4# rsync -a --progress --exclude="*.txt" test1/ test2/sending incremental file list./4 0 100%    0.00kB/s   0:00:00 (xfr#1, to-chk=0/5)# ls test2/1 2 3  4
上例中,阿铭也使用了--progress选项,它主要是用来观察rsync同步过程状态的。总而言之,平时你使用rsync同步数据时,使用-a选项基本上就可以达到想要的效果了。当有个别需求时,也会用到--no-OPTION、-u、 -L、--delete、--exclude以及--progress等选项。其他选项阿铭都没有介绍,如果在以后的工作中遇到特殊需求,可以查一下rsync的man文档。14.7.3 rsync应用实例上面列举了许多小案例,都是为了让大家熟悉rsync各个选项的基本用法。本节正式介绍rsync的实际应用,请大家认真学习。在正式试验前,你需要准备两台Linux机器,因为下面的小案例都是从一台机器复制文件到另一台机器。前面阿铭也带着大家克隆过一台虚拟机,所以把那台克隆的虚拟机打开即可,阿铭的两台机器IP地址分别为192.168.72.128和192.168.72.129。1. 通过ssh的方式在之前介绍的rsync的5种命令格式中,第二种和第三种(一个冒号)就属于通过ssh的方式备份数据。这种方式其实就是让用户登录到远程机器,然后执行rsync的任务:
# rsync -avL test1/ 192.168.72.129:/tmp/test2/The authenticity of host '192.168.72.129 (192.168.72.129)' can't be established.ECDSA key fingerprint is SHA256:gFHUJnoZAjOcnG95pt7Zg9iaPZGDiOrbZyssZtRoQhA.Are you sure you want to continue connecting (yes/no/[fingerprint])? yesWarning:Permanently added '192.168.72.129' (ECDSA) to the list of known hosts.root@192.168.72.129's password:sending incremental file listcreated directory /tmp/test2./11.txt22.txt34sent 377 bytes received 166 bytes  98.73 bytes/sectotal size is 0speedup is 0.00
这种方式就是前面介绍的第二种方式了,是通过ssh复制的数据,需要输入192.168.72.129那台机器root账户的密码。当然也可以使用第三种方式复制,如下所示:
# rsync -avL 192.168.72.129:/tmp/test2/ ./test3/root@192.168.72.129's password:receiving incremental file listcreated directory./test3./11.txt22.txt34sent 141 bytes received 389 bytes  117.78 bytes/sectotal size is 0speedup is 0.00
以上两种方式如果写入脚本,做备份麻烦,要输入密码,但我们可以通过密钥(不设立密码)验证。下面阿铭具体介绍一下通过密钥登录远程主机的方法。你可以根据3.33节,把128机器上的公钥内容放到129机器下的authorized_keys里面,这样128机器登录129机器时不再输入密码,如下所示:
# ssh 192.168.72.129Last login: Fri Jun 26 15:46:33 2020 from 192.168.72.1
现在不用输入密码也可以登录主机129了。下面先从129主机退出来,再从主机128上执行一下rsync命令试试吧:
# rsync -avL test1/ 192.168.72.129:/tmp/test4/sending incremental file listcreated directory /tmp/test4./11.txt22.txt34sent 377 bytes received 166 bytes  362.00 bytes/sectotal size is 0 speedup is 0.00
2. 通过后台服务的方式这种方式可以理解为:在远程主机上建立一个rsync的服务器,在服务器上配置好rsync的各种应用,然后将本机作为rsync的一个客户端连接远程的rsync服务器。下面阿铭就介绍一下如何配置一台rsync服务器。在128主机上建立并配置rsync的配置文件/etc/rsyncd.conf,如下所示(请把你的rsyncd.conf编辑成如下内容):
# vim /etc/rsyncd.confport=873log file=/var/log/rsync.logpid file=/var/run/rsyncd.pidaddress=192.168.72.128[test]path=/root/rsyncuse chroot=truemax connections=4read only=nolist=trueuid=rootgid=rootauth users=testsecrets file=/etc/rsyncd.passwdhosts allow=192.168.72.0/24
其中配置文件分为两部分:全局配置部分和模块配置部分。全局部分就是几个参数,比如阿铭的rsyncd.conf中的port、log file、pid file和address都属于全局配置;而[test]以下部分就是模块配置部分了。一个配置文件中可以有多个模块,模块名可自定义,格式就像阿铭的rsyncd.conf中的这样。其实模块中的一些参数(如use chroot、max connections、udi、gid、auth users、secrets file以及hosts allow都可以配置成全局参数。当然阿铭并未给出所有的参数,你可以通过命令man rsyncd.conf获得更多信息。下面就简单解释一下这些参数的作用。
  • port:指定在哪个端口启动rsyncd服务,默认是873端口。

  • log file:指定日志文件。

  • pid file:指定pid文件,这个文件的作用涉及服务的启动、停止等进程管理操作。

  • address:指定启动rsyncd服务的IP。假如你的机器有多个IP,就可以指定由其中一个启动rsyncd服务,如果不指定该参数,默认是在全部IP上启动。

  • []:指定模块名,里面内容自定义。

  • path:指定数据存放的路径。

  • use chroot true|false:表示在传输文件前,首先chroot到path参数所指定的目录下。这样做的原因是实现额外的安全防护,但缺点是需要roots权限,并且不能备份指向外部的符号连接所指向的目录文件。默认情况下chroot值为true,如果你的数据当中有软连接文件,阿铭建议你设置成false。

  • max connections:指定最大的连接数,默认是0,即没有限制。

  • read only ture|false:如果为true,则不能上传到该模块指定的路径下。

  • list:表示当用户查询该服务器上的可用模块时,该模块是否被列出,设定为true则列出,设定为false则隐藏。

  • uid/gid:指定传输文件时以哪个用户/组的身份传输。

  • auth users:指定传输时要使用的用户名。

  • secrets file:指定密码文件,该参数连同上面的参数如果不指定,则不使用密码验证。注意,该密码文件的权限一定要是600。

  • hosts allow:表示被允许连接该模块的主机,可以是IP或者网段,如果是多个,中间用空格隔开。

     

编辑secrets file并保存后要赋予600权限,如果权限不对,则不能完成同步,如下所示:

# vi /etc/rsyncd.passwd //写入如下内容test:test123# chmod 600 /etc/rsyncd.passwd
启动rsyncd服务,如下所示:
# rsync --daemon --config=/etc/rsyncd.conf
启动后可以查看一下日志,并查看端口是否启动,如下所示:
# cat /var/log/rsync.log2020/06/26 17:43:11 [4680] rsyncd version 3.1.3 starting, listening on port 873# netstat -lnp |grep rsynctcp 0     0 192.168.72.128:873     0.0.0.0:*               LISTEN      4680/rsync
如果想开机启动rsyncd服务,请把/usr/bin/rsync --daemon --confg=/etc/rsyncd.conf写入/etc/rc.d/rc.local文件。为了不影响实验过程,还需要把两台机器的firewalld服务关闭,并设置为不开机启动,操作过程如下所示:
# systemctl stop firewalld ; systemctl disable firewalld //两台机器都执行Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.# rsync -avL test@192.168.72.128::test/test1/ /tmp/test5/Password:receiving incremental file listcreated directory /tmp/test5./11.txt22.txt34sent 141 bytes received 377 bytes  8.56 bytes/sectotal size is 0 speedup is 0.00
阿铭刚刚提到了选项use chroot,默认为true。首先在主机128的/root/rsync/test1/目录下创建一个软连接文件,如下所示:
# ln -s /etc/passwd /root/rsync/test1/test.txt# ls -l /root/rsync/test1/test.txtlrwxrwxrwx 1 root root 11 6月  26 17:47 /root/rsync/test1/test.txt -> /etc/passwd
然后再到主机129上执行同步,如下所示:
# rsync -avLtest@192.168.72.128::test/test1/ /tmp/test6/Password:receiving incremental file listsymlink has no referent: "/test1/test.txt" (in test)created directory /tmp/test6./11.txt22.txt34sent 141 bytes received 436 bytes  42.74 bytes/sectotal size is 0 speedup is 0.00rsync error: some files/attrs were not transferred (see previous errors) (code 23) atmain.c(1659) [generator=3.1.3]
从上例可以看出,如果设置use chroot为true,则同步软连接文件会有问题。下面阿铭把主机128的rsync配置文件修改一下,把true改为false,如下所示:
# sed -i 's/use chroot=true/use chroot=false/'/etc/rsyncd.conf# grep 'use chroot' /etc/rsyncd.confuse chroot=false
然后再到主机129上再次执行同步,如下所示:
# rsync -avL test@192.168.72.128::test/test1/ /tmp/test7/Password:receiving incremental file listcreated directory/tmp/test7./11.txt22.txt34test.txtsent 160 bytes received 1,556 bytes  137.28 bytes/sectotal size is 1,113 speedup is 0.65
这样问题就解决了。另外,修改完rsyncd.conf配置文件后不需要重启rsyncd服务,这是rsync的一个特定机制,配置文件是即时生效的。上面的例子中,阿铭都有输入密码,这意味着我们还是不能写入脚本中自动执行。其实这种方式可以不用手动输入密码,它有两种实现方式。(1) 指定密码文件在客户端(即主机129)上编辑一个密码文件:/etc/pass,加入test用户的密码:
# vim /etc/pass //写入如下内容test123
修改密码文件的权限:
# chmod 600 /etc/pass
在同步时指定密码文件,就可以省去输入密码的步骤,如下所示:
# rsync -avL test@192.168.72.128::test/test1/ /tmp/test8/ --password-file=/etc/passreceiving incremental file listcreated directory /tmp/test8./11.txt22.txt34test.txtsent 160 bytes received 1,556 bytes  149.22 bytes/sectotal size is 1,113 speedup is 0.65

(2) 在rsync服务端不指定用户在服务端(即主机128)上修改配置文件rsyncd.conf,删除关于认证账户的配置项(auth user和secrets file这两行),如下所示:
# sed -i 's/auth users/#auth users/;s/secrets file/#secrets file/' /etc/rsyncd.conf
上例是在auth users和secrets file这两行的最前面加一个#,这表示将这两行作为注释,使其失去意义。在前面阿铭未曾讲过sed的这种用法,它是用分号把两个替换的子命令块替换了。然后我们再到客户端主机129上进行测试,如下所示:
# rsync -avL test@192.168.72.128::test/test1/ /tmp/test9/receiving incremental file listcreated directory /tmp/test9./11.txt22.txt34test.txtsent 160 bytes received 1,556 bytes  163.43 bytes/sectotal size is 1,113 speedup is 0.65
注意,这里不用再加test这个用户了,默认是以root的身份复制的。现在登录时已经不需要输入密码了。