{{ cat }}'s docs

20.2.0: 同步工具-rsync


1. 工具:rsync

作用:一个快速、万能、可远程的文件复制工具
语法:

  • 本地复制

    rsync [OPTION...] SRC... [DEST]
  • 用ssh的方式复制

    Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST:DEST
  • 用rsync daemon的方式复制(需要创建配置文件/etc/rsyncd.conf)

    Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
        rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
        rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

参数:

  • -a archive mode
    存档模式,等同于-rlptgoD
    -a选项后面可以跟一个 --no-OPTION,表示关闭-rlptgoD中的某个例如-a --no-l等同于-rptgoD
  • -c 默认rsync是基于size和mtime来判断文件是否需要同步,而-c会弃用这种方式,用checksum校验来代替
  • -r reverse mode 递归模式,主要是针对存档目录时使用
  • -v verbose 冗余信息模式,显示复制详细信息
  • -l 保留软链接
  • -L 跳过软连接,把软连接指向的源文件拷贝到目标目录
  • -p permission,保持源文件权限
  • -o owner,保持文件属主信息,但使用的用户必须是root用户
  • -g gid,保持文件属组信息
  • -D 保持设备文件信息
  • -t 保持文件时间信息
  • --delete 删除那些DST中SRC没有的文件
  • --exclude=PATTERN 指定排除不需要传输的文件,等号后面跟文件名,可以是万用字符模式(如*.txt) 当有多个条件需要指定时,只需要增添多个--exclude=PATTERN即可
  • -P 等同于--partial(若传输中断,保留已传输的部分文件)和--progress(显示每个文件传输详细信息)
  • -u update,DST中比SRC时间还新的文件将被保留,不会覆盖,即使文件内容不一致
  • --port 指定端口(daemon模式下)
  • -z 复制的同时压缩文件

rsync是增量备份,默认-av参数时在目标目录已经存在且内容无更改的文件不会被重新拷贝

基本用法演示:
1. rsync本地同步文件
自动创建并不存在的/tmp/111目录,只能创建1层目录

# 如果是2层及以上就会报错该目录不存在了
rsync -av perm/ /tmp/111
sending incremental file list
created directory /tmp/111
./
001.txt
002.txt
......
377.log
777.log

sent 792 bytes  received 262 bytes  234.22 bytes/sec
total size is 0  speedup is 0.00

SRC是"perm"时与"perm/"的不同

# 这样会把perm文件夹整个复制到目标目录里去
rsync -av perm /tmp/111
sending incremental file list
perm/
perm/001.txt
perm/002.txt
......
perm/377.log
perm/777.log

sent 810 bytes  received 263 bytes  2146.00 bytes/sec
total size is 0  speedup is 0.00

2. rsync远程同步文件
以ssh的方式用rsync与web02远程同步文件

# 如果ssh端口不是22,那么需要写成:
# rsync -av --rsh="ssh -p <port>" perm/ 192.168.0.27:/tmp/rsyncdir/
# 或rsync -av -e "ssh -p <port>" perm/ 192.168.0.27:/tmp/rsyncdir/

# 本机上执行rsync,同步文件到192.168.0.27
rsync -av perm/ root@192.168.0.27:/tmp/rsyncdir/
root@192.168.0.27's password:
sending incremental file list
./
001.txt
002.txt
......
377.log
777.log

sent 792 bytes  received 262 bytes  234.22 bytes/sec
total size is 0  speedup is 0.00

# 192.168.0.27上同步文件到本地
rsync -avuL root@192.168.0.27:/tmp/rsyncdir perm/
root@192.168.0.27's password:
receiving incremental file list
rsyncdir/
rsyncdir/001.txt
rsyncdir/002.txt
......
rsyncdir/377.log
rsyncdir/777.log
rsyncdir/testu

sent 281 bytes  received 888 bytes  155.87 bytes/sec
total size is 5  speedup is 0.00

3. 软连接拷贝相关参数"-L"和"-l"

# -l会将软连接以软连接的形式拷贝过去
ll perm/ps.soft
lrwxrwxrwx 1 root root 11 Jan  6 17:18 perm/ps.soft -> /etc/passwd     
rsync -av perm/ /tmp/111
sending incremental file list
./
001.txt
002.txt
......
377.log
777.log
ps.soft -> /etc/passwd

sent 828 bytes  received 265 bytes  2186.00 bytes/sec
total size is 11  speedup is 0.01

# 查看结果
ll /tmp/111/ps.soft perm/ps.soft
lrwxrwxrwx 1 root root 11 Jan  6 17:18 perm/ps.soft -> /etc/passwd
lrwxrwxrwx 1 root root 11 Jan  6 17:18 /tmp/111/ps.soft -> /etc/passwd
# -a中包含-l,加上此参数,rsync会把软链接保持原有属性复制到目标目录,


# -L参数会把软连接指向的源文件同步过去

# 清空111目录后我们用-L再次复制
rsync -avL perm/ /tmp/111
sending incremental file list
./
001.txt
002.txt
......
377.log
777.log
ps.soft

sent 2495 bytes  received 281 bytes  5552.00 bytes/sec
total size is 1639  speedup is 0.59

# 查看结果
ll /tmp/111/ps.soft /etc/passwd
-rw-r--r-- 1 root root 1639 Dec 29 20:23 /etc/passwd
-rw-r--r-- 1 root root 1639 Dec 29 20:23 /tmp/111/ps.soft

4. --no-OPTION参数用来指定不使用的参数

# -a含-l,我们用--no-l把-l规避掉
# 因为规避了-l参数,所以并不处理软连接文件
rsync -av --no-l perm/ /tmp/111
sending incremental file list
./
001.txt
......
777.log
skipping non-regular file "ps.soft"

sent 813 bytes  received 262 bytes  2150.00 bytes/sec
total size is 11  speedup is 0.01

5. "-u"参数,当目标机器上文件时间比源文件时间新时不覆盖重传,即使文件内容不一致

# 创建测试环境
mkdir src
mkdir dest
touch src/test01
rsync -av src/ dest
sending incremental file list
./
test01

sent 83 bytes  received 34 bytes  234.00 bytes/sec
total size is 0  speedup is 0.00

# 修改源文件内容,但是去touch目标文件,保证目标文件时间新于源文件
echo "good" > src/test01
touch dest/test01

# 加上-u参数,不重传文件,即使文件内容不一致
rsync -auv src/ dest
sending incremental file list

sent 45 bytes  received 12 bytes  114.00 bytes/sec
total size is 5  speedup is 0.09

# 而不加-u参数时,即使目标文件新于源文件也拷贝
rsync -av src/ dest
sending incremental file list
test01

sent 93 bytes  received 31 bytes  248.00 bytes/sec
total size is 5  speedup is 0.04

6. '--delete'参数可删除SRC没有,DEST有的文件

# 先在SRC删除ps.soft,用--delete实现另一端自动删除
rm -f perm/ps.soft
rsync -av --delete perm/ /tmp/111/
sending incremental file list
./
deleting ps.soft
testu

sent 352 bytes  received 34 bytes  772.00 bytes/sec
total size is 5  speedup is 0.01

7. "--exclude"参数可指定排除复制的文件

#把以.log结尾的文件排除在复制目标之外
# rm -rf /tmp/111/*
# rsync -av --exclude='*.log' perm/ /tmp/111/
sending incremental file list        
./
001.txt
002.txt
003.txt
004.txt
005.txt
006.txt
007.txt
testu

sent 503 bytes  received 167 bytes  1340.00 bytes/sec
total size is 5  speedup is 0.01

8. "-c"强制使用checksum来代替size和mtime的检测机制

## 传统av参数会在size改变和mtime修改条件改变时同步文件
echo "good" >> test1/file1
rsync -av test1/* test2/
sending incremental file list
file1

sent 130 bytes  received 35 bytes  330.00 bytes/sec
total size is 22  speedup is 0.13

touch test1/file1
rsync -av test1/* test2/
sending incremental file list
file1

sent 130 bytes  received 35 bytes  330.00 bytes/sec
total size is 22  speedup is 0.13

## 而-c参数仅会在checksum校验后发现不同才会同步文件
touch test1/file1
rsync -acv test1/* test2/
sending incremental file list

sent 99 bytes  received 19 bytes  236.00 bytes/sec
total size is 22  speedup is 0.19
# 在我们touch源文件之后,并未发送源文件

## 对比使用vim打开文件,不做任何修改,然后保存是否会同步文件
# 无-c,会同步文件
vim test1/file1
rsync -av test1/* test2/
sending incremental file list
file1

sent 232 bytes  received 35 bytes  534.00 bytes/sec
total size is 124  speedup is 0.46

# 加-c,不会同步文件
vim test1/file1
rsync -avc test1/* test2/
sending incremental file list

sent 99 bytes  received 19 bytes  236.00 bytes/sec
total size is 124  speedup is 1.05

rsync daemon模式:

服务器配置文件/etc/rsyncd.conf(需要手动创建)

vi /etc/rsyncd.conf
*************************************************
## 全局配置
port=8700
#监听端口,默认是873,若不是873,客户端需要增加--port 8700指定端口
#默认端口的配置和服务信息可在/etc/services和/etc/xinetd.d/rsync里查到
log file=/var/log/rsync.log
#默认就是这个文件,可通过此行设置其他文件,日志很重要,用于排错
pid file=/var/run/rsyncd.pid
#进程文件,默认就是这个文件
address=192.168.0.5
设置server端的ip,设置不正确的话rsync daemon无法启动

## 模块1
[test1]
#模块名称,用在客户端命令里
path=/root/perm
#指定此模块共享文件的目录
use chroot=yes
#指定是否限定用户的活动范围就是path指定的目录
max connections=4
#指定最大连接数
read only=true
#如果设为只读,那客户端用户不可push文件进来,只能读取走
list=no
#设定用户是否可以通过--list来查看server端的模块
uid=root
#若client写入文件,写入文件的属主归属
gid=root
#同上,写入文件的属组归属
auth users=testguy
#授权使用复制命令时的登录角色
secrets file=/etc/rsyncd.passwd
#登录角色的指定密码文件
hosts allow=192.168.0.1/24
#指定允许的ip网段及子网掩码(有子网掩码即为一个网段)
*************************************************

服务端密码文件/etc/rsyncd.passwd

# vi /etc/rsyncd.passwd
*************************************************
#可通过多行定义多个用户
用户名:密码
*************************************************

启动rsync守护进程(pid文件保存的内容是守护进程的pid)

# 用--daemon启动rsync服务
# 默认/etc/rsyncd.conf,也可手动指定--config=/.../rsyncd.conf
rsync --daemon

## 若pid文件已存在会报错
# failed to create pid file /var/run/rsyncd.pid: File exists

# port不是默认873,远程客户端需要用--port指定端口

rsync -av --port=8700 testguy@192.168.0.5::test1 /tmp/222
Password:
receiving incremental file list
./
001.txt
002.txt
......
377.log
777.log
testu

sent 327 bytes  received 927 bytes  167.20 bytes/sec
total size is 5  speedup is 0.00

"use chroot=yes"产生的效果

## 现在服务端创建一个软连接
# ll /root/perm/rc.soft
lrwxrwxrwx 1 root root 18 Jan  7 10:49 /root/perm/rc.soft -> /etc/rc.d/rc.local

## client端同步出现报错,这是因为chroot把用户限制在path指定的目录里
# rsync -avL --port=8700 testguy@192.168.0.5::test1 /tmp/222
Password:
receiving incremental file list
symlink has no referent: "/rc.soft" (in test1)
./

sent 61 bytes  received 431 bytes  75.69 bytes/sec
total size is 5  speedup is 0.01
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1505) [generator=3.0.6]


## 编辑服务端配置文件"use chroot=no",然后再在client端再次尝试
## 无报错,成功传输
# rsync -avL --port=8700 testguy@192.168.0.5::test1 /tmp/222
Password:
receiving incremental file list
rc.soft

sent 77 bytes  received 652 bytes  162.00 bytes/sec
total size is 225  speedup is 0.31

服务端和客户端的密码文件(用--password-file指定客户端密码文件)

# 客户端配置密码文件
vi /etc/rsyncd.d/rsyncd.pass
*************************************************
testguy:password
*************************************************

# 必须要修改权限为600,否则报错
chmod 600 /etc/rsyncd.d/rsyncd.pass

#指定客户端密码文件后不需要输入密码
rsync -avL --port=8700 --password-file=/etc/rsyncd.d/rsyncd.pass testguy@192.168.0.5::test1 /tmp/222
receiving incremental file list

sent 58 bytes  received 389 bytes  894.00 bytes/sec
total size is 225  speedup is 0.50

配置hosts allow

# "hosts allow=192.168.0.1/24"若没有/24则仅为192.168.0.1可以访问
# 修改服务端配置文件"hosts allow=192.168.0.1",客户端同步
rsync -avL --port=8700 --password-file=/etc/rsyncd.d/rsyncd.pass testguy@192.168.0.5::test1 /tmp/222
@ERROR: Unknown module 'test1'
rsync error: error starting client-server protocol (code 5) at main.c(1503) [receiver=3.0.6]

## 服务端查看log信息,用于排错
# cat /var/log/rsync.log
......
2015/01/07 11:16:17 [21454] building file list
2015/01/07 11:16:17 [21454] sent 404 bytes  received 59 bytes  total size 225
2015/01/07 11:26:14 [21468] connect from Unknown_00-0c-29-24-9e-dd.gateway.2wire.net (192.168.0.27)
2015/01/07 11:26:14 [21468] rsync denied on module test1 from unknown_00-0c-29-24-9e-dd.gateway.2wire.net (192.168.0.27)
## 将hosts段增加为"hosts allow=192.168.0.1/24"后即正常,
## 那/24代表什么含义呢,如下面所示
#/8=255.0.0.0
#/16=255.255.0.0
#/24=255.255.255.0
#/32=255.255.255.255
## /24代表了255.255.255.0的子网掩码,而子网掩码的作用是和传来的封包ip地址进行"与"计算,如果结果和本机网段一致,则可通信。

配置list=yes or no

# "list=no"用来设定服务端模块是否可被列出(推荐设为no)
# 客户端尝试list
rsync --port=8700 --list-only 192.168.0.5::

# 在服务器段设置配置文件为list=yes
rsync --port=8700 --list-only 192.168.0.5::
test1

# --list-only可省略不写
rsync --port=8700  192.168.0.5::
test1

rsync报错解决:

报错1
错误信息:

rsync -av /root/ root@192.168.0.5:/root/
rsync: Failed to exec ssh: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(84) [sender=3.0.6]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]

解决办法

# 检查ssh命令是否存在
which ssh
/usr/bin/which: no ssh in......
# 安装ssh命令
yum install openssh-clients

报错2
错误信息

rsync -av /data/tongchiang/ root@124.6.62.13:/data/www/
root@124.6.62.13\'s password:
sending incremental file list
eighth/
eighth/bk.png
eighth/eighth.css
eighth/eighth.html
rsync: connection unexpectedly closed (70 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]

解决过程:

## 查看目标主机的硬盘,发现硬盘满了,没空间了
# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vzfs        80G   80G     0 100% /
none            512M  4.0K  512M   1% /dev
none            512M     0  512M   0% /dev/shm
## 利用"du -sh ./*"来逐步排查,终于找到了罪魁祸首
# du -sh error_log
79G     error_log

解决方案:

#解决方案:创建日志分割与删除脚本,并制定计划定期执行
# vim /root/sh/error_log_del.sh
**********************************************************
#!/bin/bash
#
#created by zhaopeiwu @ 2015-04-20
#FOR control the size of error log of apache
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/apache2/bin:/usr/local/mysql/bin
export PATH

log_path="/usr/local/apache2/logs/"
log_size=`du -s $log_path/error_log|cut -f 1`
if [ $log_size -gt 100000 ];
        then
                mv $log_path/error_log $log_path/error_log_`date +%Y%m%d`;
                touch $log_path/error_log;
fi

num_del=`ls -t $log_path/error*|wc -l`
if [ $num_del -gt 4 ];
        then
                ls -t $log_path/error*|tail -$[$num_del-2]|xargs -i rm -f {} 2 > /dev/null
fi

exit 0
*********************************************************

# 制作计划任务
crontab -e
*********************************************************
*/20 * * * * sh /root/sh/error_log_del.sh
*********************************************************
#此脚本可让日志每20分钟把大于100M的日志分割,然后当日志大于4个的时候只保留最新的两个

Contents