验证 SSD 上 BtrFS 的 TRIM 支持情况

验证 SSD 上 BtrFS 的 TRIM 支持情况

我们正在研究在 SSD 磁盘阵列上使用 BtrFS,有人要求我验证 BtrFS 在删除文件时是否确实执行了 TRIM 操作。到目前为止,我无法验证 TRIM 命令是否已发送到磁盘。

我知道 BtrFS 尚未准备好投入生产,但我们喜欢前沿技术,因此我正在测试它。服务器是 Ubuntu 11.04 服务器 64 位版本(mkfs.btrfs 版本 0.19)。我安装了 Linux 3.0.0 内核作为BtrFS 更新日志指出 Ubuntu 11.04 (2.6.38) 附带的内核中不提供批量 TRIM。

以下是我的测试方法(最初采用自http://andyduffell.com/techblog/?p=852,经过修改以适用于 BtrFS):

  • 开始之前手动 TRIM 磁盘:for i in {0..10} ; do let A="$i * 65536" ; hdparm --trim-sector-ranges $A:65535 --please-destroy-my-drive /dev/sda ; done
  • 验证驱动器是否已进行 TRIM:./sectors.pl |grep + | tee sectors-$(date +%s)
  • 对驱动器进行分区:fdisk /dev/sda
  • 制作文件系统:mkfs.btrfs /dev/sda1
  • 山:sudo mount -t btrfs -o ssd /dev/sda1 /mnt
  • 创建文件:dd if=/dev/urandom of=/mnt/testfile bs=1k count=50000 oflag=direct
  • 验证文件是否在磁盘上:./sectors.pl | tee sectors-$(date +%s)
  • 删除测试文件:rm /mnt/testfile
  • 查看测试文件是否已从磁盘中 TRIM:./sectors.pl | tee sectors-$(date +%s)
  • 验证 TRIM 块:diff两个最新的sectors-*文件

此时,删除前和删除后的验证仍显示相同的磁盘块正在使用中。相反,我应该看到正在使用的块数量减少。在删除测试文件后等待一个小时(以防 TRIM 命令需要一段时间才能发出)仍然显示相同的块正在使用中。

我也尝试过使用这些-o ssd,discard选项进行安装,但似乎根本没有帮助。

从上面创建的分区fdisk(我保持分区很小,以便验证可以进行得更快):

root@ubuntu:~# fdisk -l -u /dev/sda

Disk /dev/sda: 512.1 GB, 512110190592 bytes
255 heads, 63 sectors/track, 62260 cylinders, total 1000215216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x6bb7542b

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1              63      546209      273073+  83  Linux

我的sectors.pl脚本(我知道这效率低下,但它可以完成工作):

#!/usr/bin/perl -w

use strict;

my $device = '/dev/sda';
my $start = 0;
my $limit = 655360;

foreach ($start..$limit) {
    printf "\n%6d ", $_ if !($_ % 50);
    my @sector = `/sbin/hdparm --read-sector $_ $device`;
    my $status = '.';
    foreach my $line (@sector) {
            chomp $line;
            next if $line eq '';
            next if $line =~ /$device/;
            next if $line =~ /^reading sector/;
            if ($line !~ /0000 0000 0000 0000 0000 0000 0000 0000/) {
                    $status = '+';
            }
    }
    print $status;
}
print "\n";

我的测试方法有缺陷吗?我是否遗漏了什么?

谢谢您的帮助。

答案1

因此,经过多日的努力,我终于能够证明 BtrFS 确实使用了 TRIM。我无法在我们将部署这些 SSD 的服务器上成功运行 TRIM。但是,当使用插入笔记本电脑的同一驱动器进行测试时,测试成功。

所有测试所用的硬件:

  • Crucial m4 SSD 512GB
  • HP DL160se G6
  • LSI LSISAS9200-8e 主机总线适配器
  • 通用 SAS 外壳
  • 戴尔 XPS m1210 笔记本电脑

在服务器上多次验证 BtrFS 失败后,我决定使用旧笔记本电脑(删除 RAID 卡层)尝试同样的测试。在笔记本电脑上使用 Ext4 和 BtrFS 进行的首次测试失败(数据未 TRIM)。

然后,我将 SSD 驱动器固件从版本 0001(开箱即用)升级到版本 0009。使用 Ext4 和 BtrFS 重复测试,两个文件系统都成功 TRIM 了数据。

为了确保 TRIM 命令有时间运行,我rm /mnt/testfile && sync && sleep 120在执行验证之前做了一些操作。

如果您尝试进行同样的测试,请注意一件事:SSD 具有它们操作的擦除块(我不知道 Crucial m4 擦除块的大小)。当文件系统向驱动器发送 TRIM 命令时,驱动器将仅擦除整个块;如果为块的一部分指定 TRIM 命令,则由于擦除块内剩余的有效数据,该块将不会被 TRIM。

为了演示我所说的内容(sectors.pl上述脚本的输出)。这是 SSD 上的测试文件。句点是仅包含零的扇区。加号有一个或多个非零字节。

驱动器上的测试文件:

24600 .......................................+++++++++++
24650 ++++++++++++++++++++++++++++++++++++++++++++++++++
24700 ++++++++++++++++++++++++++++++++++++++++++++++++++
    -- cut --
34750 ++++++++++++++++++++++++++++++++++++++++++++++++++
34800 ++++++++++++++++++++++++++++++++++++++++++++++++++
34850 +++++++++++++++++++++++++++++.....................

测试文件已从驱动器中删除(之后sync && sleep 120):

24600 .......................................+..........
24650 ..................................................
24700 ..................................................
    -- cut --
34750 ..................................................
34800 ..................................................
34850 ......................+++++++.....................

看起来文件的第一个和最后一个扇区与文件其余部分位于不同的擦除块中。因此,一些扇区未受影响。

由此得出的结论是:一些 Ext4 TRIM 测试说明要求用户仅验证文件的第一个扇区是否已进行 TRIM。测试人员应查看测试文件的更大部分,以真正了解 TRIM 是否成功。

现在要弄清楚为什么手动发出的通过 RAID 卡发送到 SSD 的 TRIM 命令有效,但自动 TRIM 命令无效......

答案2

根据我所读的内容,您的方法论可能存在缺陷。

您假设 TRIM 将导致您的 SSD 将已删除的块清零。然而事实往往并非如此。

只有当 SSD 实现 TRIM 以便将丢弃的块清零时,情况才会如此。您可以检查设备是否至少知道足够多的信息来报告 discard_zeroes_data:

cat /sys/block/sda/queue/discard_zeroes_data

此外,即使 SSD 确实将块清零,也可能需要一些时间(在丢弃完成后),SSD 才能真正将块清零(一些质量较差的 SSD 确实如此)。

http://www.redhat.com/archives/linux-lvm/2011-April/msg00048.html

顺便说一句,我一直在寻找一种可靠的方法来验证 TRIM,但还没有找到。如果有人找到方法,我很想知道。

答案3

这是针对 10.10 和 EXT4 的测试方法。也许会有所帮助。

https://askubuntu.com/questions/18903/how-to-enable-trim

哦,我认为你确实需要在 fstab 挂载上使用 discard 参数。不确定是否需要 SSD 参数,因为我认为它应该自动检测 SSD。

答案4

一些需要考虑的事情(帮助回答您的“我遗漏了什么吗?”的问题):

  • /dev/sda 到底是什么?单个 SSD?还是 (硬件?) SSD RAID 阵列?

  • 如果是后者,那么是什么样的 RAID 控制器?

  • 你的 raid 控制器是否支持 TRIM?

最后,

  • 如果您使用 btrfs 以外的其他方式格式化 /dev/sda1,您的测试方法是否会给出预期的结果?

相关内容