
别让SSD性能腐烂:Linux上实用的fstrim.timer
如果你的Linux系统运行在SSD、由SSD存储支持的虚拟磁盘或精简配置卷上,TRIM是那种容易被遗忘、日后调试又很麻烦的无聊维护任务。
好消息是,现代Linux已经有了一个明智的解决方案:fstrim.timer。
本文展示如何:
fstrim.timer是否已启用discard我这里聚焦于实用路径,而非存储领域的陈旧观念。
当文件被删除时,文件系统知道这些块是空闲的,但SSD可能不会立即知道。通过Linux上的fstrim暴露的TRIM会告诉底层存储哪些未使用的块可以被丢弃。
这很重要,因为:
fstrim(8)手册描述得很清楚:fstrim会丢弃已挂载文件系统上未使用的块,对SSD和精简配置存储很有用。
很多指南直接建议在挂载选项中添加discard。这不是我的默认建议。
上游fstrim(8)手册页明确警告:频繁运行TRIM,或使用mount -o discard,可能会对质量较差的SSD产生负面影响,并指出对于大多数桌面和服务器系统,每周一次就足够了。
这与当今许多发行版的默认配置一致。在本机上,打包的timer是:
# /usr/lib/systemd/system/fstrim.timer
[Timer]
OnCalendar=weekly
AccuracySec=1h
Persistent=true
RandomizedDelaySec=100min
这是一个非常合理的默认值:
weekly保持适度的执行频率Persistent=true意味着错过的运行会在启动后补上RandomizedDelaySec=在多台机器间分散负载从lsblk -D开始:
lsblk -D
示例输出:
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
vda 0 512B 2G 0
├─vda1 0 512B 2G 0
├─vda14 0 512B 2G 0
└─vda15 0 512B 2G 0
需要关注的内容:
DISC-GRAN和DISC-MAX不应同时为0B你也可以用以下命令检查已挂载的文件系统:
findmnt -D
这会给你一个已挂载文件系统和discard相关设备特性的快速视图。
很多系统已经默认启用了。在做任何更改之前先检查:
systemctl status fstrim.timer
systemctl list-timers --all fstrim.timer
示例:
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2026-05-11 00:46:45 UTC 3 days Mon 2026-05-04 01:29:37 UTC 3 days ago fstrim.timer fstrim.service
如果你看到下次运行已安排,你可能已经完成了。
你也可以检查打包的service和timer定义:
systemctl cat fstrim.timer fstrim.service
在这台机器上,service执行的是:
ExecStart=/sbin/fstrim --listed-in /etc/fstab:/proc/self/mountinfo --verbose --quiet-unsupported
这是个很好的细节。它会trim fstab或挂载信息中列出的文件系统,打印有用的字节数,并对不支持的文件系统抑制烦人的错误。
如果timer已安装但未激活,启用它:
sudo systemctl enable --now fstrim.timer
然后确认:
systemctl status fstrim.timer
systemctl list-timers --all fstrim.timer
如果你的发行版使用了厂商预设已启用它,这个命令是无害的。
有时候你不想等到每周运行,特别是刚完成大清理、VM镜像压缩或容器/镜像修剪之后。
运行:
sudo fstrim -av
参数含义:
-a trim所有支持该操作且已挂载的文件系统-v 显示有多少字节被向下传递以供可能丢弃示例输出通常如下:
/: 38.2 GiB (41016926208 bytes) trimmed
/boot/efi: 97.5 MiB (102236160 bytes) trimmed
fstrim(8)有一个微妙但重要的说明:报告的字节数是向下传递以供可能丢弃的数量,而不是保证设备当时确实物理丢弃了每个字节。这是正常的。
无论是手动运行还是timer驱动的运行之后,检查service日志:
systemctl status fstrim.service
journalctl -u fstrim.service --since "7 days ago"
这给你两样有用的东西:
有几个情况会让人踩坑:
在这台主机上,打包的unit包含:
ConditionVirtualization=!container
所以fstrim.timer和fstrim.service在容器内会被故意跳过。这是正确的,因为discard属于拥有块设备的主机或VM层。
fstrim(8)手册页指出,在trim所有文件系统时,不支持的文件系统和只读情况会被忽略。如果你的存储栈不传递discard,再多的systemd调整也解决不了。
这通常已不再是问题。每周批量TRIM是大多数系统的上游推荐默认值。
如果我要在一台普通工作站、家庭服务器或由SSD存储支持的VM上配置这个,我的基线会是:
lsblk -D
findmnt -D
systemctl status fstrim.timer || true
sudo systemctl enable --now fstrim.timer
sudo fstrim -av
journalctl -u fstrim.service --since today
这样你就能获得:
通常不要。
只有当你的存储栈确实受益于即时回收,并且你已经测试过性能权衡的情况下,我才会考虑持续discard。对于通用Linux系统,每周timer是更干净的默认值。
fstrim.timer是Linux中那些罕见的同时既无聊又正确的默认配置之一。
如果你的存储支持discard,启用timer,验证一次,然后继续你的生活。这比把discard胡乱添加到每个挂载选项并希望最好要好得多。
fstrim(8)手册页:https://man7.org/linux/man-pages/man8/fstrim.8.htmlfstrim.timer手册:https://www.freedesktop.org/software/systemd/man/latest/fstrim.timer.htmlfstrim.timer的变更说明:https://fedoraproject.org/wiki/Changes/EnableFSTrimTimerlsblk(8)手册页:https://man7.org/linux/man-pages/man8/lsblk.8.htmlfindmnt(8)手册页:https://man7.org/linux/man-pages/man8/findmnt.8.html