现场是这样的。一台 CentOS 7 上把 40G 的备份从 /data 移到 /backup,中途手动 ctrl+c,之后 /data 里的原文件不见了,/backup 下同名文件大小是 0,两边的目录都还在。
中间走过弯路,把「源目录项只在拷贝成功后才删除,可分布式存储上删除和拷贝的顺序不可控」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。跨文件系统时 mv 实际是拷贝加删除,拷贝没完成前中断会留下不完整的目标文件;mv 先创建目标文件再写内容,中断后文件存在但长度为零;脚本里没有校验返回码,静默失败被当成成功继续往下跑。
第一件事是确认还有没有完整副本
ls -l /backup/*.tar.gz /data/*.tar.gz 2>/dev/null
从快照或者备份里找回原文件
ls -lt /snapshot | head -5
接着改用带校验的拷贝再删源
rsync -aHAX --info=progress2 /data/bak.tar.gz /backup/ && sha256sum /data/bak.tar.gz /backup/bak.tar.gz
校验一致后再删掉源文件
cmp /data/bak.tar.gz /backup/bak.tar.gz && rm -f /data/bak.tar.gz
别只看报错消失,验证要多做一步。两侧 sha256 完全一致,目标文件大小与源文件相同,删除源文件后 df 显示 /data 空间已释放且 /backup 占用相应增加。
大批量迁移一律用 rsync 加校验再删源,mv 只适合同一文件系统内的重命名;中断过的目标文件要当废文件删掉,不要接着用。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。