空间回收没卡住,它只是在等明天早上 09:29
我问错了问题
我清掉几个文件夹,在 NAS 上点了空间回收,然后等。几个小时后,存储管理员那张卡还写着 running,可用空间看起来跟早上一样。我的问题是「它为什么什么都没回收」。
它回收过了——两次,而且其中一次比我删掉的东西大得多。测量回答的是另一个问题,而这才是这件事里最有意思的地方。
在相信任何东西之前,先给可用空间上定时采样
我没有去看那张进度卡,而是给 volume1 的可用空间做了当天每五分钟一次的采样:
| 时间 | 可用 | 事件 |
|---|---|---|
| 08:59 → 09:24 | 1134.1 GiB | 平——什么都没在回收 |
| 09:29 | +69.0 GiB | Class 快照 …10.14-09.29.02 轮转 |
| 09:34 | +46.8 GiB | Video 快照 …10.14-09.30.35 轮转 |
| 15:28:45 | — | DSM 日志:Start to empty all recycle bins. |
| 15:34 | +5.0 GiB | 清回收站结束——里面只有 5 GiB |
| 16:35 → 17:39 | −39 GiB | 新数据写入(一阵爆发) |
| 15:00 → 20:44 | −47.2 GiB | 净值:这个卷那天下午丢了空间 |
两次回收,合计约 121 GiB;然后 47 GiB 的新写入把下午吃掉了。「什么都没回来」是我这边的读法错误:我拿早上和晚上比,而晚上里面多了一整天的写入。
我特意手动清空的回收站是 5 GiB;我压根没想到的快照是 115.8 GiB。这个比例就是全部故事。
为什么那张卡写着 running,却什么都不代表
$ synostgreclaim --get-all-status --verbose
{"state":"running","num_subvolume_remain":1,"now_runnable":true}
schedule_table: 168 × 1
run_time_option: run_all_time
state: running 加上 168 个 1 的调度表和 run_all_time,意思是这个任务被配置成按设计 24×7 都处于 running。它是调度状态,不是进度指示器——所以在某天完全无事可排的日子,这张卡照样这么写。而当时那台机器上没有 synostgreclaim 进程、没有 btrfs balance、md2/dm-3 的 I/O 基本为零。那一刻没有任何东西在被回收,也没有任何东西卡住。
然后是日志,而 DSM 上它们大多是红鲱鱼:
- 回收任务本身什么都不记;
/var/log/space_operation.log是 LUKS 和卷列表的噪音;/var/log/synorecycle.log是synounlinkd的路径噪音;- 当天的 Log Center 里只有我自己那条清回收站的记录,外加几条 UPS 断电/来电的提示。
一个永远为真的 UI 状态字段,加上三个永远不会给出答案的日志文件:唯一剩下的仪器,就是随时间变化的可用空间。
没人告诉你的那个机制
空间回收释放的是已删除的 btrfs 子卷。它释放不了仍然被快照钉住的数据。那两个共享文件夹的保留策略是 retention 1(各留一代),所以我删掉的任何东西,都要等到第二天的轮转、大约 09:29 / 09:30 才会变成可用空间,一次跳几十 GB,然后安静 24 小时。
那两次跳变正是这个。它也就意味着,对于「我删了 50 GB 却什么都没发生」这个问题,在这台机器上的诚实答案是:「等明天早上再看」——而如果删掉的数据本来就在某个快照里面,答案是「等那个快照过期,之前不会释放」。
如果重来一次
- 采样那个数字,不要采样状态。 每五分钟量一次可用空间,比任何任务卡都更能回答「现在有没有事情在发生」,而且它同时让「回长」变得可见。
- 读调度字段,不读状态字段。
run_all_time解释了那个永久 running,而且不需要任何 bug 存在。 - 搞清楚每个共享文件夹的保留策略。 它是决定「删除何时变成可用空间」的那口钟;不知道它,每一次删除都会看起来坏掉一整天。
- 把两本账分开。 回收站(5 GiB)和快照(115.8 GiB)行为完全不同,也是两套心理模型。
- 重新检查分母。 这个卷平时就在以约 1.5 GiB/时 的速度被正常写入吃掉;回收回来 121 GiB、当天又花掉 47 GiB,只要你只比同一个数字的两个快照,这两件事看起来完全一样。
测量真正告诉我的,是这台机器的趋势
我本来是去修一个卡住的任务,结果带回来的是一条存储趋势:
volume1 42 TB 已用 98% 剩 1.2 TB 近来约 -1.5 GiB/时(8 天 -344 GiB)
volume2 16 TB 已用 100% 剩 70 GB 约 -19 GiB / 2 天
健康 两个卷 btrfs corruption_errs 均为 0
所有 md 阵列 [UUUU] / [UU],没有在跑 balance
read/write_io_errs 与九月基线一致
所以有用的结论不是「回收是好的」。而是:相对于写入速率,回收只是一个舍入误差;在保留策略为 1 的前提下,删除并不是我以为的那根杠杆;而该拿来做告警的是趋势,不是那张任务卡。这跟《你的磁盘快满告警在撒谎》是同一课,只是从另一个方向来的:对后果告警(随时间变化的可用字节),因为机制自己的状态不是证据。