发布脚本先把包解到 /tmp,再 os.rename 到 /data/www,报 OSError: [Errno 18] Invalid cross-device link。旧版本目录已经被删掉,站点直接 404。日志里能对上时间点,这种反而好排。

rename 只保证同一文件系统内的原子性,跨挂载点内核直接返回 EXDEV,不会帮你拷贝。脚本没处理这个错误,前面的清理步骤又已经执行完,目录就空了。这一点先确认清楚,后面就不用反复试。

df -h /tmp /data
mv /data/tmp/release-20261112 /data/www/releases/
ln -sfn /data/www/releases/release-20261112 /data/www/current

这次卡住的地方就在「rename EXDEV 跨分区」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。

处理上按这个顺序:临时目录放到目标分区的同一个挂载点下 /data/tmp;跨分区场景改成 shutil.move 并补一次 fsync;发布用新目录加软链接切换 不要先删旧目录;脚本里对 EXDEV 单独捕获 失败就回滚软链接。

结果对不对很好判断,发布脚本退出码为 0 current 指向新目录 刷新页面内容是新版本。

作者 9823189