针对 containerd 的特别建议

如果你确认要重新彻底迁移 /var/lib/containerd,请按照以下严格顺序操作:

  1. 彻底停止相关服务:
    containerd 通常被 docker 或 k8s 使用。必须先停掉它们:

    systemctl stop docker
    systemctl stop containerd
  2. 修改配置文件(可选但更稳妥):
    除了做软链接,你也可以直接修改 /etc/containerd/config.toml:

    root = "/data/containerd_data"

    然后重启服务。这种方式比软链接更受官方支持,性能也略好。

  3. 使用 tar 管道流传输 (对于本地文件系统之间迁移海量小文件和硬链接,老牌工具 tar 的效率往往“吊打” rsync[rsync -avzPH]注意硬链接。)

tar 的逻辑是:一边打包读取,一边直接写入目标路径,不产生中间文件,且处理硬链接的效率比 rsync 高得多。

# 确保目标目录已存在
mkdir -p /data/containerd_data

# 使用 tar 管道进行流式拷贝
tar -cpf - -C /var/lib/containerd . | tar -xpf - -C /data/containerd_data

命令原理解释:

  • tar -cpf - -C /var/lib/containerd . :进入原目录并打包所有内容(-p 保留权限,-f - 输出到标准输出流)。
  • | :管道符,将左边的数据流直接喂给右边。
  • tar -xpf - -C /data/containerd_data :在目标目录接收数据流并解包。
⚠️ 最终警告:
无论使用哪种方法提速,由于你迁移的是 containerd,在执行复制命令前,必须、必须、必须确保服务已经完全停止(systemctl stop containerd 以及 systemctl stop docker),否则复制过去的文件锁或数据库状态会损坏!

为什么 rsync -avzPH 这么慢?

  1. -z (压缩) 帮了倒忙:
    -z 参数会在传输时压缩数据,接收时解压。这在跨网络传输(受限于带宽)时极其有用。但在同机本地磁盘间拷贝时,磁盘读写速度远大于 CPU 的压缩/解压速度。你的 CPU 算力成为了瓶颈,反而拖慢了磁盘 IO。
  2. -H (保留硬链接) 的代价极高:
    containerd 和 docker 底层(如 overlay2 存储驱动)大量使用硬链接来共享镜像层以节省空间。rsync 使用 -H 时,必须在内存中建立一个巨大的索引表,对比每一个文件的 inode 来寻找并重建硬链接。文件越多,这个计算过程呈指数级变慢。
  3. 小文件与 IOPS 瓶颈:
    复制 1 个 5GB 的大文件和复制 10 万个 50KB 的小文件,对硬盘的压力完全不同。大量小文件会导致极高的元数据读写(创建 inode、修改目录结构),这消耗的是硬盘的 IOPS(每秒读写次数),而不是连续吞吐量。rsync 默认是单线程的,只能一个一个处理,面对几十万个小文件自然力不从心。