使用 SSD 上的 BtrFS 验证 TRIM 支持

Sha*_*ers 21 linux ubuntu ssd trim btrfs

我们正在研究在一组 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 一起使用):

  • 在开始之前手动修剪磁盘: for i in {0..10} ; do let A="$i * 65536" ; hdparm --trim-sector-ranges $A:65535 --please-destroy-my-drive /dev/sda ; done
  • 验证驱动器已被修剪: ./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
  • 看到测试文件是从磁盘中修剪出来的: ./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
Run Code Online (Sandbox Code Playgroud)

我的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";
Run Code Online (Sandbox Code Playgroud)

我的测试方法有缺陷吗?我在这里错过了什么吗?

谢谢您的帮助。

Sha*_*ers 4

经过很多天的研究,我能够证明 BtrFS 确实使用了 TRIM。我无法在我们将部署这些 SSD 的服务器上成功进行 TRIM 工作。但是,当使用插入笔记本电脑的同一驱动器进行测试时,测试会成功。

用于所有这些测试的硬件:

  • 英睿达 m4 固态硬盘 512GB
  • 惠普 DL160se G6
  • LSI LSISAS9200-8e HBA
  • 通用 SAS 机柜
  • 戴尔 XPS m1210 笔记本电脑

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

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

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

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

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

驱动器上的测试文件:

24600 .......................................+++++++++++
24650 ++++++++++++++++++++++++++++++++++++++++++++++++++
24700 ++++++++++++++++++++++++++++++++++++++++++++++++++
    -- cut --
34750 ++++++++++++++++++++++++++++++++++++++++++++++++++
34800 ++++++++++++++++++++++++++++++++++++++++++++++++++
34850 +++++++++++++++++++++++++++++.....................
Run Code Online (Sandbox Code Playgroud)

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

24600 .......................................+..........
24650 ..................................................
24700 ..................................................
    -- cut --
34750 ..................................................
34800 ..................................................
34850 ......................+++++++.....................
Run Code Online (Sandbox Code Playgroud)

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

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

现在要弄清楚为什么通过 RAID 卡发送到 SSD 的手动发出的 TRIM 命令可以工作,但自动 TRIM 命令却不能...