Files
hoelee-blog/src/content/posts/zh/space-reclamation-wasnt-stuck-it-was-waiting.md
T
hoelee 08fa7a9412
Deploy / build (push) Successful in 32s
post: four posts — rclone/Drive quota, DSM space reclamation, mail domain/PTR, embedded fonts (EN+ZH) + og/banner
- my-backup-was-using-someone-elses-api-quota        (notes,       2026-10-15, pinned by its own evidence)
- space-reclamation-wasnt-stuck-it-was-waiting       (devops,      2026-10-14, pinned by its own samples)
- adding-a-domain-to-someone-elses-mail-server       (notes,       2025-05-06, backdated: no date/version pins)
- embedding-fonts-so-a-pdf-looks-the-same-everywhere (engineering, 2025-01-22, backdated: no date/version pins)
All four updatedDate 2026-10-16 so every lastmod stays honest; the two backdated posts carry no prose links
(a backdated post may only link backwards). og measured rows=1/overflow=0, banners 8 rows/delta=2/overflow=0.
2026-10-16 13:47:10 +08:00

5.6 KiB
Raw Blame History

title, description, pubDate, updatedDate, category, tags, ogImage, banner, draft
title description pubDate updatedDate category tags ogImage banner draft
空间回收没卡住,它只是在等明天早上 09:29 存储管理员那张卡整天写着 running,可用空间一动不动。其实 121 GiB 已经分两步回来了——然后下午又被写掉了 47 GiB。 2026-10-14 2026-10-16 devops
synology
btrfs
snapshots
storage
nas
/og/space-reclamation-wasnt-stuck-it-was-waiting.png /banners/space-reclamation-wasnt-stuck-it-was-waiting.png false

我问错了问题

我清掉几个文件夹,在 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 却什么都没发生」这个问题,在这台机器上的诚实答案是:「等明天早上再看」——而如果删掉的数据本来就在某个快照里面,答案是「等那个快照过期,之前不会释放」。

如果重来一次

  1. 采样那个数字,不要采样状态。 每五分钟量一次可用空间,比任何任务卡都更能回答「现在有没有事情在发生」,而且它同时让「回长」变得可见。
  2. 读调度字段,不读状态字段。 run_all_time 解释了那个永久 running,而且不需要任何 bug 存在。
  3. 搞清楚每个共享文件夹的保留策略。 它是决定「删除何时变成可用空间」的那口钟;不知道它,每一次删除都会看起来坏掉一整天。
  4. 把两本账分开。 回收站(5 GiB)和快照(115.8 GiB)行为完全不同,也是两套心理模型。
  5. 重新检查分母。 这个卷平时就在以约 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 的前提下,删除并不是我以为的那根杠杆;而该拿来做告警的是趋势,不是那张任务卡。这跟《你的磁盘快满告警在撒谎》是同一课,只是从另一个方向来的:对后果告警(随时间变化的可用字节),因为机制自己的状态不是证据。