SDB:SSD discard (trim) 支持
术语
有三个术语经常被互换使用来描述相同的基本功能:丢弃、UNMAP 和 TRIM。
丢弃是 Linux 中用于告知存储设备某些扇区不再存储有效数据的术语,适用于 ATA 和 SCSI 设备。 例如,对于 ext4 文件系统,有一个丢弃挂载选项,而不是 trim 或 unmap 选项。 历史上,此功能不存在,但最近 SSD 制造商要求提供此功能以提高其设计的性能能力,SCSI 阵列制造商也要求类似的功能以更好地支持稀疏配置。
因此,通常会丢弃 SSD 的小扇区范围,但仅丢弃 SCSI 阵列的大范围。 例如,某些 SCSI 阵列可能会将范围限制为 4 MB 的边界。 阵列特定的实现方式决定了范围如何被限制。
TRIM 是发送到 SSD 的实际 ATA-8 命令,用于导致扇区范围或一组扇区范围被丢弃。 因此,它仅应适用于 ATA 设备,但通常被通用地使用。 鉴于 ATA 设备的普及程度,trim 通常是这些术语中最常用的。
UNMAP 是一个 SCSI 特定的命令,性质相似,但主要用于支持稀疏配置。 UNMAP 也可以用作通用术语,而不是仅用于 SCSI 设备。
SCSI 还支持 WRITE SAME,它也可以用于实现丢弃功能。 目前,WRITE SAME 似乎仅在它专门适用时才使用。
情况
使用新一代 SSD 的工作是一个不断发展的解决方案。 基本操作应在所有 openSUSE 版本中得到支持,但丢弃/trim 功能仍在完全实现中。 SSD 很快将变得在笔记本电脑中很常见。 为了优化其性能并延长其寿命,草案 ATA-8 规范要求支持 trim。 如果丢弃了一系列扇区,则这些扇区不再包含有意义的数据,并且 SSD 可以自由删除内容并擦除它们。 擦除对于 SSD 来说是一个缓慢的操作,因此在需要扇区时擦除扇区而不是在扇区释放时擦除扇区是一项重大优势。
不幸的是,只有当用户空间、内核和硬件实现都经过优化时,才能获得此优势。 截至 2010 年初,唯一优化的实现是纯用户空间实现,其工作方式类似于碎片整理。 例如,它应该定期调用,例如通过 cron 脚本。
当前状态
在 11.2 之前,不支持 trim。
截至 11.4,fstrim 是 linux-util 包的一部分,并且是大多数用户调用 trim 的推荐选择。
内核支持
内核实时丢弃支持
openSUSE 11.2 及更高版本的内核支持实时丢弃。 例如,当删除文件时,底层数据块将被丢弃。 这些内核支持 ext4 和 xfs 的实时丢弃。
要使用内核实时丢弃功能,必须使用“mount -o discard”选项挂载。 openSUSE 不会自动设置此选项,因此必须手动挂载分区或更新 /etc/fstab 文件以执行此操作。
11.2、11.3 和 11.4 内核中的内核实时 trim 实现并未优化。 规范要求 trim 支持向量化的 trim 范围列表,但截至内核 3.0,trim 仅由内核使用单个丢弃/trim 范围调用,并且在 2011 年年中期的当前 SSD 中,这已被证明会导致性能下降而不是性能提升。 很少有理由使用 3.1 之前的内核的内核实时丢弃支持。 内核的丢弃功能何时优化以与当前一代 SSD 有益地配合使用尚不清楚。
内核交换设备丢弃支持
Linux 内核自 2.6.29 以来一直支持交换中不再使用的页面的丢弃。 性能影响是可变的,并且可以帮助或损害特定的 SSD。
在 openSUSE 11.2 和 11.3 中,无法控制此功能。 内核假定它对所有支持丢弃的设备都有益。
在 2.6.36 内核中,引入了一个由用户空间控制的选项。 对于 11.4,用户空间控制支持默认禁用。 需要大于 v2.18 的 util-linux-ng 版本才能启用丢弃功能。(请注意,util-linux-ng 在 2011 年初已重命名为 util-linux。)
详情请参阅:http://marc.info/?l=util-linux-ng&m=128796678428160
内核 mkfs 丢弃支持
openSUSE 11.4 及更高版本创建的新 ext4 分区的一个最近的内核优化是,ext4 格式化工具 mke4fs 现在将在格式化时丢弃整个分区,并且该过程已在内核中优化为使用每个 TRIM 命令的 64 个连续范围。 因此,它得到了很好的优化。 出于性能原因,重要的是新创建的分区在格式化过程结束时具有所有未使用的块处于 TRIM 状态。 因此,强烈建议使用 11.4 或更高版本的 mkfs 格式化先前包含有效数据的 SSD。
内核批量丢弃支持
2.6.37 内核获得了一个新的 ext4 专用 ioctl:FITRIM。 openSUSE 11.4 使用此内核。 openSUSE 11.4 用户空间工具调用此新功能是 fstrim。 对于较早的版本,fstrim 可通过 git 从以下位置获得:
http://www.spinics.net/lists/util-linux-ng/msg03646.html
fstrim / FITRIM 的一项功能,wiper.sh 下面未完全支持,是对设备映射器线性卷和条带卷的丢弃支持
更重要的是,FITRIM 已被接受为主流内核功能,因此获得了比 wiper.sh 下面更广泛的审查。 因此,FITRIM(由 fstrim 调用)不太可能因在不受支持的环境中尝试而导致数据丢失。
用户空间支持
来自 util-linux(或 util-linu-ng)包的 fstrim 是 11.4 中修剪 SSD 的推荐工具。 必须定期调用它,就像碎片整理工具一样。 如果可行,将其设置为从 cron 调用会是最好的。
在 11.4 之前,11.2 和 11.3 都有更新版本的 hdparm,可以绕过正常的块 I/O 层并直接提交优化的 trim 命令到 SSD。 hdparm 需要一个控制脚本来确定哪些扇区适合修剪。 这由 hdparm 包中的脚本 wiper.sh 提供,该脚本在 11.2 和 11.3 的 hdparm 包中可用。
目前,11.2 或 11.3 不会自动调用 wiper.sh。 用户必须创建一个 cron 脚本来执行此操作。 通常,wiper.sh 只需要几秒钟才能运行,并且必须以 root 用户身份运行。
我应该多久运行一次 fstrim / wiper.sh
对于大多数用户,每周一次就足够了。 这可能看起来间隔太长,但只要您没有运行创建和删除大量文件(带有内容)的高速率工作负载,就应该可以正常工作。
理论上,SSD 像 LIFO 一样处理已知空闲区域,并且在将块放入 LIFO 后,只需几毫秒就可以擦除并可用。 因此,只要有足够的可用擦除块,就可以以全速运行,将新释放的块推到底部并从顶部拉出新鲜擦除的块。
如果工作负载是数据库,从概念上讲,每个写入都会进入一个新分配的块,但旧块会立即释放并放入擦除队列。 随着新一代 SSD 的出现,似乎垃圾收集器在 SSD 内部固件中运行,以清理这些 SSD 存储的覆盖区域并有效地使空间可供将来使用。
例如,SSD 不允许物理数据块被更新。 每个写入都需要从空闲块堆栈中拉出一个新的数据块,并且先前的物理块被释放以进行擦除。 因此,像数据库这样的持续更新先前分配的数据块只是导致大量搅动,但实际上并没有减少空闲块的堆栈。
(注意:较新的 SSD 不再按上述方式工作。相反,它们似乎以比 EB 级别更精细的级别跟踪使用/未使用。因此,数据库风格的更新会导致 EB 的一部分标记为免费,并分配一个新的 EB 来保存新数据。因此,繁重的数据库风格更新可能会导致由于所有部分使用的 EB 造成的可用 EB 减少。现代 SSD 使用在后台运行的 EB 合并器来解决此问题。正确修剪 SSD 允许 EB 合并器以最佳性能工作。请参阅 SDB:SSD_Idle_Time_Garbage_Collection_support 以获取更多详细信息。)
文件删除让 SSD 认为这些块很有价值,因此无法用于擦除,而文件系统本身知道这些块将永远不会被使用。
因此,运行 wiper.sh 或 fstrim 的全部目的是告诉 SSD 将不再分配的块放入擦除/空闲队列中。
只要 SSD 不会尝试从该队列的顶部拉取块时卡住,其深度无关紧要。 因此,如果您的分区上有 10GB 的可用空间,您只需要每 10GB 的文件删除量调用一次 wiper.sh / fstrim。
Hdparm 错误
hdparm 的在线更新可以修复以下问题。
- 对于 openSUSE 11.2 和 openSUSE 11.3,您可以通过以下方式安装在线更新:
zypper in -t patch hdparm-3298
通过补丁 hdparm-3298 修复的 bug 635920 历史
对于 OCZ Vertex 2E SSD,请参阅 https://bugzilla.novell.com/show_bug.cgi?id=635920
此外,根据 hdparm 的维护者 Mark Lord 的说法,Intel SSD 不完全支持规范中的 trim,并遭受相同的错误。 因此,脚本 wiper.sh 或 hdparm 二进制文件本身已更新,以尝试支持 Intel SSD。
这些更新已在 hdparm v9.32 中进行,并回溯到 openSUSE 11.2 和 11.3 以进行上述在线更新。
虽然 wiper.sh 仍然被认为是实验性的,但人们认为调用 wiper.sh 到任何 SSD 不会导致任何数据丢失。 Trim payload 不兼容性只会导致 trim 操作失败。 在上述在线更新之后,目前没有已知问题。
用户反馈
EXT4 内核邮件列表的评论
来自:Mark Best
我有一个新的 Vertex2 固态硬盘。 当我尝试使用 EXT4(或带有 EXT4 的 LUKS)安装任何发行版时,我的硬盘在“文件复制”过程中超时。(例如,openSUSE 11.2 在复制 X11 的第二个文件后会崩溃。其他发行版在安装过程中会遇到“只读”错误。)
尝试过的发行版
- Ubuntu 10 - x64
- Debian 5 - x64
- PCLinuxOS 9 - x32
- CentOS 5.4 - x64
- OpenSUSE 11.2 (Linux 2.6.31) - x64
- OpenSUSE 11.3 - Build 0625 (Linux 2.6.34) - x64
尝试
- 如果我使用我的 Seagate 1TB 驱动器,我可以很好地安装到任何 EXT4 分区。(相同的 SATA 电缆和 SATA 控制器端口)
- 如果我在 Verex2 SSD 上使用 EXT2 文件系统,我可以安装任何发行版。
- Windows 2003/NTFS 也能顺利安装到 Vertex2 SSD 上。
- 向整个 SSD 写入随机的 'dd' 数据不会返回任何错误。
- 升级 EVGA 主板 BIOS 到最新版本 (P33) 也没有帮助。
- 将 OpenSUSE 11.2 操作系统安装到我的 HDD 上,然后将文件从 HDD 复制到 Vertex2 会导致相同的 I/O 超时/以只读方式重新挂载错误。