如何为Linux服务器上的SSD存储配置定期TRIM

来自菜鸟教程
跳转至:导航、​搜索

介绍

由于 SSD 或固态驱动器的架构,如果不加以考虑和缓解,连续使用会导致性能下降。 TRIM 命令是一种允许操作系统将有关哪些数据块不再使用的信息向下传播到 SSD 的操作。 这使 SSD 的内部系统能够更好地管理磨损均衡并为未来的写入做好准备。 随着时间的推移,TRIM 会对设备的性能及其整体寿命产生重大影响。

虽然可以在 Linux 中启用连续 TRIM,但这实际上会对性能产生负面影响,因为正常文件操作的额外开销。 更温和的替代方法是配置 periodic TRIM。 这会将操作系统配置为按计划修剪驱动器,而不是作为常规文件操作的必要组件。 在几乎所有情况下,它都提供了与连续 TRIM 相同的好处,而不会影响性能。

在本指南中,我们将简要讨论 SSD 和 TRIM 的工作原理,然后演示如何在各种 Linux 发行版上启用定期 TRIM。

SSD 如何存储数据?

为了更好地了解 TRIM 解决的问题,了解一些有关 SSD 如何存储和管理数据的信息会有所帮助。

数据单元

SSD 上的数据以称为 pages 的固定大小为单位写入和读取。 反过来,页面以更大的单元组合在一起,称为 块 。

读取、写入和擦除限制

SSD 可以单独读取和写入页面。 但是,它们只能擦除块级别的数据。 另一个限制是只能在完全 归零 (所有位设置为 0)的页面上执行写入。 这意味着直接覆盖数据是不可能的。

要修改数据,SSD 实际上必须从旧位置读取信息,在内存中对其进行修改,然后将修改后的数据写入新的归零页面。 然后,它更新一个内部表,以将操作系统分配到的逻辑位置映射到设备上数据的新物理位置。 旧位置在不同的内部表中标记为 stale:未使用,但尚未归零。

回收过时的页面

为了回收过时的页面,SSD 的内部垃圾收集进程必须从一个块中读取所有有效页面并将它们写入一个新块。 同样,内部表映射逻辑和物理位置被更新。 旧块现在不包含唯一的仍在使用的数据,然后可以将其归零并标记为准备好以备将来写入。

TRIM 做什么?

SSD 的内部垃圾收集进程负责擦除块和管理磨损均衡。 但是,文件系统通常通过在自己的记录中将数据标记为再次可用的空间来“删除”数据。 它们实际上不会从底层存储中擦除数据,但可能会在后续写入时覆盖该数据先前占用的区域。

这意味着 SSD 通常不会知道不再需要某个页面,直到它从文件系统接收到稍后写入相同逻辑位置的指令。 它无法执行其垃圾收集例程,因为它永远不会在数据被删除时通知它,只是在以前为它保留的空间现在应该用于其他数据时。

TRIM 命令将有关哪些数据不再使用的信息从文件系统传播到 SSD。 这允许设备在空闲时执行其常规垃圾收集职责,以确保有零页面准备好处理新的写入。 SSD 可以提前对数据进行洗牌,清理过时的页面,并通常使设备保持良好的工作状态。

然而,对每次删除执行 TRIM 的成本可能会很高,并且会对驱动器的性能产生负面影响。 配置定期 TRIM 会定期向设备提供有关不需要的页面的大量信息,而不是每次操作。

禁用连续 TRIM

安装设备时,您可能已经在设备上启用了连续 TRIM。 在我们启用定期 TRIM 之前,看看我们当前的挂载选项是有意义的。

通过使用 discard 选项安装驱动器或分区来启用连续 TRIM。

首先,找到当前使用 discard 选项挂载的文件系统:

findmnt -O discard
OutputTARGET     SOURCE    FSTYPE OPTIONS
/mnt/data  /dev/sda1 ext4   rw,relatime,discard,data=ordered
/mnt/data2 /dev/sdb1 ext4   rw,relatime,discard,data=ordered

您可以通过在 mount 中包含 -o remount,nodiscard 来重新安装这些文件系统,而无需 discard 选项:

sudo mount -o remount,nodiscard /mnt/data
sudo mount -o remount,nodiscard /mnt/data2

如果再次运行 findmnt 命令,您应该不会收到任何结果:

findmnt -O discard

接下来,打开 /etc/fstab 文件以查看当前为您的文件系统定义的挂载选项。 这些决定了每次启动时文件系统的挂载方式:

sudo nano /etc/fstab

查找 discard 选项并将其从您找到的行中删除:

/etc/fstab

. . .
# /dev/sda1 /mnt/data ext4 defaults,nofail,discard 0 0
/dev/sda1 /mnt/data ext4 defaults,nofail 0 0
# /dev/sdb1 /mnt/data2 ext4 defaults,nofail,discard 0 0
/dev/sdb1 /mnt/data2 ext4 defaults,nofail 0 0

完成后保存并关闭文件。 文件系统现在将在没有 discard 选项的情况下挂载,并将在后续引导时以相同的方式挂载。 我们现在可以为所有支持它的文件系统设置定期 TRIM。

为 systemd 分发设置定期 TRIM

为使用 systemd 的现代发行版设置定期 TRIM 往往相当简单。

Ubuntu 16.04

Ubuntu 16.04 附带一个由 cron 每周运行的脚本。 这意味着 Ubuntu 16.04 不需要启用下一节中描述的 systemd 方法。

如果您想检查脚本,可以通过键入以下内容来查看它:

cat /etc/cron.weekly/fstrim
Output#!/bin/sh
# trim all mounted file systems which support it
/sbin/fstrim --all || true

如您所见,此脚本需要带有 --all 标志的 fstrim 版本。 Ubuntu 早期版本附带的许多版本 fstrim 不包含此选项。

其他 systemd 发行版

对于其他 systemd 发行版,可以使用 fstrim.timer 文件启用定期 TRIM,该文件将每周在所有有能力的已安装驱动器上运行一次 TRIM 操作。 这也利用了 fstrim --all 选项。

在撰写本文时,这是以下发行版的最佳方法:

  • Debian 8
  • CentOS 7
  • 软呢帽 24
  • 软呢帽 23
  • 核心操作系统

对于 CentOS 7、Fedora 23、Fedora 24 和 CoreOS,fstrim.service 和 fstrim.timer 单位默认可用。 要安排每周对所有连接的支持驱动器进行 TRIM,请启用 .timer 单元:

sudo systemctl enable fstrim.timer

Debian 8 在文件系统中有 fstrim.service 和 fstrim.timer 可用,但默认情况下不加载到 systemd 中。 您只需要先复制文件:

sudo cp /usr/share/doc/util-linux/examples/fstrim.service /etc/systemd/system
sudo cp /usr/share/doc/util-linux/examples/fstrim.timer /etc/systemd/system

现在,您可以像使用其他发行版一样启用计时器:

sudo systemctl enable fstrim.timer

您的服务器现在应该每周修剪一次所有支持该操作的已安装文件系统。

为非系统分布设置定期 TRIM

巧合的是,大多数附带非 systemd init 系统的发行版还附带了没有 --all 标志的 fstrim 实用程序版本。 这使得安全、自动的 TRIM 操作变得更加困难。

在不支持它的驱动器上或在错误实现它的设备上使用 TRIM 可能很危险并导致数据丢失。 --all 标志可以安全地处理这些情况,但是手动尝试确定连接的驱动器是否正确支持该操作可能很危险。

在 Ubuntu 14.04 中,包含一个名为 fstrim-all 的简短脚本,它试图执行此操作。 由 cron 运行的每周脚本执行此操作。 但是,脚本并不总是正确解释连接驱动器的 TRIM 功能。

对于这个和其他带有 fstrim 命令但没有 --all 标志的发行版,最好的解决方法可能是编译包含该标志的 fstrim 的静态链接版本。 这可以与分发管理版本一起安装,并且只能从 cron 作业中显式调用。

这可能是以下发行版的最佳选择:

  • Ubuntu 14.04
  • Ubuntu 12.04
  • Debian 7
  • 中央操作系统 6

对于 Ubuntu 14.04,最好禁用 fstrim-all 脚本运行,因为它可能无法正确检测到状态:

sudo chmod a-x /etc/cron.weekly/fstrim
sudo mv /etc/cron.weekly/fstrim /etc/cron.weekly/fstrim.bak

对于其他发行版,您可以直接加入。

安装软件编译工具

首先,安装所需的软件构建工具。

对于 Ubuntu 和 Debian 系统,这可以通过键入:

sudo apt-get update
sudo apt-get install build-essential

对于 CentOS 系统,您可以通过键入以下命令安装一组类似的工具:

sudo yum groupinstall 'Development Tools'

您现在拥有编译最新版本的 fstrim 所需的构建依赖项。

下载并提取源文件

fstrim 实用程序与称为 util-linux 的组中的其他工具一起发布。 您可以在 这里 找到按发行版本组织的源代码。

单击软件包的最新版本。 目前,即 v2.28,但随着开发的继续,可能会有所不同。

在下一个目录中,找到该软件的最新压缩包。 这将从 util-linux- 开始并以 .tar.gz 结束。 目前,最新的稳定版本是 util-linux-2.28.1.tar.gz。 右键单击相应的链接并将其复制到剪贴板。

回到你的服务器,移动到 /tmp 目录。 使用 curl 或 wget 实用程序并粘贴您复制的 URL 以下载文件:

cd /tmp
curl -LO https://www.kernel.org/pub/linux/utils/util-linux/v2.28/util-linux-2.28.1.tar.gz

之后,解压缩 tarball 以创建源目录结构:

tar xzvf util-linux*

现在我们有了源代码和构建工具,我们可以构建软件了。

配置和编译静态链接的 fstrim

首先输入提取的目录结构:

cd /tmp/util-linux*

接下来我们需要配置软件。 由于我们只安装一个隔离的 fstrim 二进制文件,并且不想覆盖我们的包管理系统管理的实用程序和库,我们将编译一个静态二进制文件。

为此,我们需要启用静态链接并禁用共享库。 通过键入以下内容配置具有这些属性的软件:

./configure --enable-static --disable-shared

配置软件后,您可以通过键入以下命令来编译 fstrim 实用程序:

make fstrim

这将编译该实用程序,将其放置在提取存档的顶级目录中。

将二进制文件复制到 PATH 中 而非 的目录。 由于我们只对从 cron 脚本调用它感兴趣,因此我们应该确保它不会与系统安装的 fstrim 竞争其他用途。

我们将创建一个名为 /cron-bin 的目录并将二进制文件放入其中:

sudo mkdir /cron-bin
sudo cp /tmp/util-linux*/fstrim /cron-bin

我们现在可以访问功能更强大的 fstrim 实用程序。

创建每周 Cron 脚本以运行 fstrim

现在,我们可以创建一个由 cron 每周运行的新脚本。 这将与 Ubuntu 16.04 中包含的脚本完全相同,只是它将指向我们放置静态编译的二进制文件的位置。

通过键入以下内容创建文件:

sudo nano /etc/cron.weekly/fstrim

在里面,粘贴以下行。 这将使用 --all 选项运行我们新的 fstrim 二进制文件:

/etc/cron.weekly/fstrim

#!/bin/sh
# trim all mounted file systems which support it
/cron-bin/fstrim --all || true

完成后保存并关闭文件。

通过键入以下命令使脚本可执行:

sudo chmod a+x /etc/cron.weekly/fstrim

cron 和 anacron 守护程序将每周运行一次此脚本以修剪文件系统。

结论

您的 Linux 服务器现在应该配置为每周定期修剪所有支持的文件系统。 TRIM 有助于最大限度地提高 SSD 的长期性能和使用寿命。

连续的 TRIM 操作可能听起来很理想,但它们会给常规文件系统操作增加大量开销。 定期 TRIM 通过在计划的作业中传递执行驱动器日常维护所需的关键信息,而不是作为每个文件操作的组件,提供了一个很好的中间立场。