meta 目录里删掉的旧快照,被硬链接悄悄占着空间
meta 的目录从 1.2T 涨到 1.9T,我按 mtime 删了一批旧快照,du 一看只掉了 80G。df 却没怎么动。
环境是 Ubuntu 20.04,meta 版本 v2.7.3,快照目录每份 4-6G,总共 37 份,删了 14 份。删除命令是很普通的:
find /data/meta/snapshots -maxdepth 1 -type d -name '20*' -mtime +30 -exec rm -rf {} +
df 不掉的原因不是 rm 没删,是 inode 还被别的路径引用着。meta 在做增量快照时会对上一份里的块文件建硬链接,同一个 inode 挂在两个快照目录下。只删一个目录,inode 的链接数从 2 变 1,空间不会释放。
我先确认了一下:
# 看哪些 inode 还有多个链接
find /data/meta/snapshots -type f -links +1 -printf '%i %n %s %p\n' | head -50
输出里能看到同一 inode 出现在多个快照目录。然后按 inode 统计占了多少:
find /data/meta/snapshots -type f -links +1 -printf '%i %s\n' \
| awk '{sum[$1]=$2} END {for (i in sum) t+=sum[i]; print t/1024/1024/1024" GB"}'
结果是 610G 左右,跟 df 和 du 的差额对得上。
处理办法我没有直接删。先停掉 meta 的快照任务,确认没有写操作,再按快照从旧到新整份删。因为硬链接是成对存在的,只要两份里都删掉,inode 链接数归零,空间才真正释放。单份删一半反而会让后面的快照失去引用,回滚时直接坏掉。
代价是:停任务窗口期大概 40 分钟,这期间不能产生新快照;另外整份删不可逆,我提前用 find -printf '%p %s\n' 把剩下 23 份的清单存了一份到别的盘。
这里会失效的情况我也撞过:如果 meta 配置里开了 dedup 或者块级共享,-links +1 不一定是快照之间的硬链接,也可能是块存储自己的引用,这时候按 inode 删会误伤。另外 -mtime +30 按目录 mtime 判断不靠谱,快照目录的 mtime 在元数据更新时会变,我后来改成读快照清单里的时间字段。
还有一个坑:rm -rf 删大目录时如果中途被打断,会留下部分删掉的快照,inode 链接数不上不下,du 和 df 都看不出问题,但下次快照可能报校验失败。我现在改成先重命名成 .deleting-* 再删,出问题能一眼看出来。
你们那边 meta 的快照保留策略是按份数还是按时间?按份数的话,最老那份被硬链接引用的情况是怎么处理的?
0 条评论
还没有评论,写下第一条。