群晖更换硬盘迁移数据并保留硬链接

在保留文件硬链接的情况下迁移数据,换 NAS 硬盘。

前言

新买了一块 16T 的 HC550 插到群晖上做 pt 下载盘,由于之前的硬盘中存在大量硬链接,不能直接拷贝数据,需要用其他的方法。

首先了解到 cpio 可以在保留硬链接的情况下拷贝数据,使用命令:

1
find . -depth -print0 | cpio --null --sparse -pvd /destination/

但是 ssh 进入群晖发现并没有这个命令,由于群晖是魔改 Linux 系统,也没有找到如何直接安装,所以得换个方法。

rsync

这时候想到了万能的 rsync,查了下手册,还真的可以处理硬链接,使用 -H, --hard-links 就可以保留硬链接,那事情就好办了。

1
sudo rsync -aAHSXvh --progress --delete /volume1/media/ /volume3/media/

使用到的参数作用分别是:

  • -a 归档模式,相当于 -rlptgoD,不包含 -A -H -X
    • -r, --recursive,递归处理文件夹
    • -l, --links,遇到符号链接时,在目标重新创建符号链接
    • -p, --perms,保持文件权限
    • -t, --times,保持文件时间信息
    • -g, --group,保持文件属组信息
    • -o, --owner,保持文件属主信息
    • -D, --devices,保持设备文件信息
  • -A, --acls,保留 ACL,暗含 -p 参数
  • -H, --hard-links,保留硬链接,避免重复拷贝
  • -S, --sparse,对稀疏文件进行处理,节省空间
  • -X, --xattrs,保留扩展属性
  • -v, --verbose,输出详细日志
  • -h, --human-readable,输出易读的文件大小数字
  • --progress,显示传输进度,给无聊的人打发时间(gives a bored user something to watch)
  • --delete,删除目标文件夹中不存在于源文件夹的文件

rsync 对硬链接的处理

关于 rsync 在处理硬链接的时候,有一些补充。

-H 选项的作用是告诉 rsync 在传输过程中查找硬链接文件,并且在接收端将他们与相应的文件再次链接。如果不加该选项,便会当成普通文件进行拷贝,浪费空间。

如果目的地是非空文件夹,该选项只能保证在源端链接在一起的文件在接收端也链接在一起,不会将接收端存在而源端不存在的硬链接破坏掉。如果链接的文件内容有更改,那么在更新时会取消链接。

rsync 只能检测内部文件之间的硬链接,也就是硬链接链接的文件都要在传输范围内,否则链接会被破坏。

rsync 对符号链接的处理

  1. 发送端文件范围不包含符号链接的源文件

    如果使用 -a(包含 -l, --links),那么只会传输符号连接本身(一个无效的快捷方式)。 需要使用 -L, --copy-links 参数以将符号连接转化为文件本身进行传输(传输过程会保留符号链接的文件名,内容为指向的文件的内容)。

  2. 发送端文件范围包含符号链接的源文件

    如果使用 -a(包含 -l, --links),那么会传输符号连接本身和它指向的源文件(一切正常)。 如果添加 -L 参数,那么符号连接会转化为普通文件再传输一次(接收端存在两份相同的普通文件)。

  3. 发送端文件范围内存在以上 1 2 两种情况

    使用 --copy-unsafe-links 进行处理,它会让 rsync 将符号链接指向的发送端文件范围外的文件当作普通文件进行拷贝,包含在发送范围内的文件保持符号链接。使用该选项时不能加 -L, --copy-links,否则无效。

  4. -k, --copy-dirlinks-K, --keep-dirlinks

    • 使用 -k, --copy-dirlinks,将发送端的符号链接视为一个普通目录。 如果希望只处理目录,不希望指向非目录的符号链接也受到影响,需要使用这个选项,因为 --copy-links 也会影响到文件。
    • 接收端的目录是一个符号链接,并且要保留这个符号链接,需要使用 -K, --keep-dirlinks 选项。 -K 令接收端将符号链接视为目录文件,但只有发送端有真实目录与其匹配时生效。 例如,接收段 /destination/ 是一个符号链接,指向 /real-destination/。如果没有 -K 选项,那么 rsync 会删除 /destination/ 这个符号链接并且创建一个普通文件夹 /destination/;有 -K 时,则会遵循符号链接,将文件存放到 /real-destination/ 中。

后记

rsync 真的很强,离熟练用它还有挺远的距离的。

参考资料

rsync(1) - Linux man page files - How to copy directories with preserving hardlinks? - Unix & Linux Stack Exchange rsync - -k and -l options in rysnc - Ask Ubuntu rsync - How to copy directory structure without removing symlinks? - Unix & Linux Stack Exchange 当rsync遇到文件链接… - 知乎

0%