# 拷贝文件
- 在本机上拷贝文件时:
- 通常使用 cp 命令。
- 跨磁盘拷贝文件时,两个磁盘分别承受读、写负载。在同一磁盘拷贝文件时,读、写负载同时作用于该磁盘,拷贝速度慢很多,不如创建硬链接。
- 跨主机拷贝文件时:
- 通常使用 scp、rsync 命令。
- 跨主机拷贝文件时,磁盘 IO 速度可能比网络 IO 速度快多倍,比如 100MB/s 对 10MB/s 。建议先制作文件的压缩包,拷贝到目标主机之后再解压,使得总耗时更少,只是压缩、解压需要占用一些时间和 CPU 。
- 拷贝大量小文件时,也建议制作压缩包。因为每个文件都需要拷贝一次文件元数据,增加了耗时。
# cp
cp <src_path> <dst_path> # 将文件从源路径拷贝到目标路径
-a # 相当于-dpr
-d # 若源文件为 link file ,则复制 link file 的属性(而非文件本身)
-p # 将源文件的权限、属性也拷贝过去(否则会使用默认属性)
-r # 递归操作(用于复制目录)
-f # 若目标文件已存在,则删除它再尝试拷贝
-i # 若目标文件已存在,则提示用户是否进行覆盖
-n # 若目标文件已存在,则不覆盖
-u # --update ,当目标文件不存在,或源文件比目标文件更新时,才执行拷贝
-v # 显示执行过程的详细信息
- Linux 发行版一般设置了
alias cp='cp -i'
,所以 -f 选项无效。 - 例:
cp f1 f2 cp f1 f2 /tmp cp -r * /tmp # 源路径中包含通配符 * 时,不会拷贝隐藏文件 cp -r . /tmp cp -a * /tmp
- 执行
cp f1 f2
时:- 如果 f2 不存在,则会先创建一个空的 f2 文件,再将 f1 的内容拷贝过去。
- 如果 f2 已存在,则会先将 f2 的内容清空,再将 f1 的内容拷贝过去,因此目标文件依然使用 f2 的 inode 号。
- 如果该过程中有其它进程也在修改 f2 ,则会导致 cp 出错。
# ln
:用于创建文件的链接,并不会实际拷贝文件。
- 命令:
ln <src_path> <dst_path> # 创建文件的硬链接 -s # 创建文件的软链接 -f # 若目标文件已存在,则覆盖它
- 创建链接时,源路径、目标路径都必须是绝对路径。
- 不支持给目录创建硬链接,不支持跨磁盘分区创建硬链接。
- 可以给目录创建软链接,可以跨磁盘分区创建软链接。
- 例:
[root@CentOS ~]# ln -s /tmp tmp [root@CentOS ~]# ls -lh total 0 lrwxrwxrwx 1 root root 4 Jan 8 14:21 tmp -> /tmp [root@CentOS ~]# rm -f tmp/ # 如果软链接文件指向一个目录,删除时不能加上 / 后缀,否则会被视作删除目标目录 rm: cannot remove ‘tmp/’: Is a directory [root@CentOS ~]# rm -f tmp
# dd
:用于在本机上拷贝文件,还支持转换文件格式。不支持拷贝目录。
- 命令:
dd if=<file> # 源文件,默认为 stdin of=<file> # 目标文件,默认为 stdout count=<blocks> # 拷贝多少个块(默认为拷贝全部数据) bs=<bytes> # 读写数据时,内存缓冲区的大小。默认为 512 。取值过小会减慢速度,取值过大会占用大量内存 ibs=<bytes> # 每次读取多少字节的数据,默认为 512 obs=<bytes> # 每次写入多少字节的数据,默认为 512
- dd 拷贝文件时,会以 ibs 为单位读取数据,放入内存缓冲区 bs ,然后以 obs 为单位写入目标文件。
- 例:
dd if=/dev/sda1 of=/dev/sda2 # 从 if 设备拷贝数据到 of 设备 dd if=/dev/cdrom of=cd.iso # 拷贝文件并转换成 iso 文件
- 例:
[root@CentOS ~]# dd if=/dev/urandom of=f1 bs=1M count=1024 # 拷贝生成一个指定大小、随机内容的文件 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 74.6221 s, 14.4 MB/s [root@CentOS ~]# dd if=f1 of=f2 bs=1M # 拷贝文件,这也能测试磁盘的顺序读写速度 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 7.92427 s, 136 MB/s
# scp
:安全拷贝协议(Secure copy protocol),用于在主机之间拷贝文件,基于 SSH 协议加密通信。
- 命令:
scp <file>... [email protected]:/root # 将本机的文件拷贝到其它主机(需要通过 SSH 认证) [email protected]:/root/f1 /root # 将其它主机的文件拷贝到本机的指定目录 -C # 传输数据流时启用压缩 -P 22 # 指定 SSH 的端口 -r # 递归操作(用于拷贝目录)
# rsync
:用于在本机拷贝文件、目录,或跨主机拷贝。
- 与 scp 相比:
- rsync 将每个文件分成多个文件块传输,如果目标文件中已包含 md5 值相同的块,则不拷贝。因此支持断点续传、增量拷贝。
- rsync 跨主机拷贝时,需要源主机、目标主机都安装了 rsync 。
- 命令:
rsync SRC... DEST # 在本机拷贝文件(此时相当于 cp 命令) SRC... [USER@]HOST:DEST # 将本机的文件拷贝到其它主机 [USER@]HOST:SRC... DEST # 将其它主机的文件拷贝到本机 -e "ssh -p 1022" # 修改 SSH 协议的配置参数 -z # 传输数据流时启用压缩(不管是本机拷贝,还是跨主机拷贝) -a # 保留文件属性,且递归处理目录 -P # 保留未完全拷贝的文件,并显示传输进度 -q # --quite ,隐藏拷贝过程的信息,除非是报错 --exclude=log/* # 排除某些文件,不拷贝它们 --ignore-existing # 如果目标文件已存在,则不拷贝 -u # --update ,如果目标文件已存在,且修改时间比源文件更新,则不拷贝 --delete # 删除目标目录比源目录多出的文件 --inplace --append
- 当 SRC 是目录时,如果以 / 结尾,则相当于
cp SRC/* DEST
,否则相当于cp SRC DEST/SRC
。 - 如果 DEST 目录不存在,则会自动创建。
- 当 SRC 是目录时,如果以 / 结尾,则相当于
- 例:
rsync -aP /tmp /data rsync -aP --inplace -e ssh /root/f1 10.0.0.1:/root
- rsync 将 src_file 拷贝文件到 dst_file 时:
- 如果 dst_file 不存在(即目标文件路径未被占用),则从头拷贝 src_file 。
- 拷贝时,默认先暂存到 DEST 目录下一个临时文件。比如拷贝 f1 文件时会暂存为 .f1.GRds8g 文件,等拷贝完才将它重命名为 f1 。如果拷贝中断,则删除该文件。
- 启用 -P 选项时,即使未完全拷贝文件,rsync 就中断,也会将临时文件重命名为 dst_file 。此时该文件是不完整的, modify time 为 1970-01-01 。
- 如果 dst_file 已存在,则检查其 md5 值、文件属性是否与 src_file 一致。
- 如果相同,则不拷贝该文件。
- 如果不同,则默认会从头拷贝 src_file 。
- 例如事先用 cp 命令等其它方式拷贝该文件,即使已经拷贝完,也会因为文件的 modify time 与 src_file 不一致,导致 rsync 从头拷贝该文件。
- 以下情况不会创建临时文件,而是直接保存到 dst_file 。
- 启用 --inplace 选项时,会检查 dst_file 中各个文件块的 md5 值,如果与 src_file 不同,则拷贝该文件块。如果文件属性不同,则单独拷贝文件属性。
- 启用 --append 选项时,会检查 dst_file 的长度,如果比 src_file 短,则拷贝缺少的字节到 dst_file 的末尾。因此不保证 dst_file 与 src_file 的长度、内容、文件属性一致。
- 综上,如果想实现断点续传,避免从头拷贝文件,建议启用 -P 和 --inplace 选项。
- 如果 dst_file 不存在(即目标文件路径未被占用),则从头拷贝 src_file 。
# 数据备份
按备份层级的不同,可将备份方式分为:
- 物理备份
- :将一块磁盘的数据,备份到另一块磁盘中,以 block 为单位拷贝数据。
- 优点:
- 拷贝、恢复的速度很快,接近磁盘的读写速度上限。
- 缺点:
- 磁盘中有些数据可能不需要备份,也会被拷贝,导致备份包占用更多磁盘空间。
- 逻辑备份
- :将一个文件的数据,备份到另一个文件中,以 byte 为单位拷贝数据。
- 物理备份
备份数据存在一定耗时,在此期间,数据可能被业务进程修改,导致备份出错。因此,存在两种备份方式:
- 在线备份
- :又称为热备份,是在备份期间,继续运行业务进程,对用户无影响。
- 离线备份
- :又称为冷备份,是在备份期间,停止运行业务进程,不为用户提供服务。
- 在线备份
假设需要备份一个文件或目录,每天备份一次,生成一个压缩包,最多保留 30 个压缩包。存在几种备份方式:
- 全量备份
- :每天备份一次,每次将所有文件都备份。
- 优点:
- 备份速度最慢。每次备份,都需要读取所有文件。
- 缺点:
- 恢复速度最快,只需要解压一个压缩包。
- 占用的磁盘空间最多。即使待备份的数据从未变化,也需要保留 30 个体积一样大的压缩包。
- 增量备份
- :第一个压缩包,采用全量备份。之后每次备份,都是比较当前时刻的数据,与上一个压缩包的差异,然后只备份这些差异。
- 优点:
- 备份速度较快。
- 占用的磁盘空间最少。每次增量备份时,差异越少,生成的压缩包体积越小。
- 缺点:
- 恢复速度最慢。如果想恢复到第 N 个增量备份,则需要先解压第一个压缩包,然后按顺序应用各个增量备份,直到第 N 个增量备份。
- 差异备份
- :每次备份时,比较当前时刻的数据,与上一次全量备份的差异。因此恢复文件时,只需要使用一个全量备份和一个差异备份。
- 效果介于全量备份与增量备份之间。
- 全量备份
何时采用增量备份?
- 如果待备份的数据,不超过 100MB ,
- 可以用 zip 等压缩命令,进行全量备份。
- 如果这些数据是文本格式,则可以用 git 命令,进行增量备份。
- 如果待备份的数据,超过 100MB ,则全量备份太浪费磁盘空间,应该采用增量备份、差异备份。
- 可以用 tar 命令,进行增量备份。不过 tar 命令的功能较少。
- 可以用 rsnapshot 命令,进行增量备份。
- 如果待备份的数据,超过 1TB ,则逻辑备份太浪费时间,应该采用物理备份。
- 如果待备份的数据,不超过 100MB ,
# dump
dump 命令用于备份数据(属于物理备份、增量备份),只支持 etx2、etx3、etx4 文件系统。
命令:
dump [option] <path> # 读取一个路径中的数据,进行备份 -f <file> # 保存为指定文件 -[0-9] # 设置备份级别 -j # 压缩为 bzip2 格式
- path 可以是文件、目录、磁盘分区。只有为磁盘分区时,才支持增量备份。
- 备份级别有 0~9 十种,0 是全量备份,1~9 都是增量备份。
- 比如用 0 全量备份一次之后,可用 1 增量备份。下一次备份时,用 2 就是增量备份(级别加一),用 1 就是差异备份(覆盖之前的同级数据)。
- 即使用 -j 指定了压缩格式,但 dump 生成的备份文件,并不是通用的压缩文件,因为增加了一些备份信息。只能被 restore 命令解压。
- 例:
dump -j -0f tmp.bz2 /tmp/
命令:
restore -f <file> # 指定备份文件 -r # 还原数据(会根据备份文件中的备份信息,将数据还原到原路径) -t # 显示备份文件的内容 -C # 比较当前文件与备份文件的差异(比如旧文件被修改、删除,但是增加新文件时不算差异)
- restore 会生成一个 restoresymtable 文件,用于在增量备份时传递信息,可以删除。
- 例:
restore -tf tmp.bz2
# xfsdump
- xfs 文件系统,提供了 xfsdump 命令用于备份数据(属于物理备份、增量备份),提供了 xfsrestore 命令用于恢复数据。
# rsnapshot
rsnapshot 是一个数据备份工具(属于逻辑备份、增量备份)。
- 采用 perl 语言开发,适用于类 Unix 系统。
- 基于 rsync 命令进行工作,可以备份本机的数据,也可以通过 SSH 备份其它主机的数据。
- 每次备份,会将目标文件拷贝到一个新的 snapshot 目录下。
- 如果目标文件在之前的 snapshot 目录下也存在,没有变化,则不拷贝该文件,而是创建硬链接,从而减少占用的磁盘空间。
- 用户不能将 snapshot 目录做成压缩包,否则硬链接失效。建议将需要备份的源文件,做成压缩包,从而减少占用的磁盘空间。
安装:
yum install rsnapshot
用法示例:
编写一个配置文件
/data/rsnapshot/rsnapshot.conf
:# 配置文件的语法版本 config_version 1.2 loglevel 2 logfile /data/rsnapshot/rsnapshot.log lockfile /data/rsnapshot/rsnapshot.pid # 将快照保存到哪个目录 snapshot_root /data/rsnapshot/snapshots/ # 每种类型的快照,最多保留多少个 # 这些快照,会保存为多个目录,命名格式为 $snapshot_root/$type.$num/ ,例如 /data/rsnapshot/snapshots/hourly.0/ # 同种类型的快照中,最新一个快照的编号为 0 。每新增一个快照,所有历史快照的编号都会递增 1 retain hourly 24 retain daily 7 retain weekly 4 retain monthly 3 # 配置 rsync 命令的可执行文件、参数 cmd_rsync /usr/bin/rsync # rsync_short_args -a # rsync_long_args --delete --numeric-ids --relative --delete-excluded # ssh_args -p 22 # include ... # exclude ... # 基于 rsync 命令,拷贝文件,保存到 $snapshot_root/$retain/10.0.0.1/ 目录下 backup [email protected]:/tmp 10.0.0.1/ # 执行自定义的 shell 脚本,拷贝数据到 $snapshot_root/$retain/mysql/ 目录下 # backup_script /etc/rsnapshot/dump_mysql.sh mysql/
- 配置文件中的分隔符,必须使用 Tab ,不能使用空格。可执行命令
sed -i 's#\x20#\t#g' rsnapshot.conf
进行转换。
- 配置文件中的分隔符,必须使用 Tab ,不能使用空格。可执行命令
添加 crontab 定时任务,定期执行 rsnapshot 命令:
0 * * * * /usr/bin/rsnapshot -c /data/rsnapshot/rsnapshot.conf hourly # 生成一个 hourly 类型的快照 0 1 * * * /usr/bin/rsnapshot -c /data/rsnapshot/rsnapshot.conf daily 0 1 * * 7 /usr/bin/rsnapshot -c /data/rsnapshot/rsnapshot.conf weekly 0 1 1 * * /usr/bin/rsnapshot -c /data/rsnapshot/rsnapshot.conf monthly