通过SSD上的BtrFSvalidationTRIM支持

我们正在研究在SSD磁盘arrays上使用BtrFS,并且我被要求validationBtrFS实际上在删除文件时执行TRIM操作。 到目前为止,我一直无法validationTRIM命令是否发送到磁盘。

我知道BtrFS不被视为生产准备,但我们喜欢stream血的边缘,因此我正在testing它。 服务器是Ubuntu 11.04服务器64位版本(mkfs.btrfs 0.19版本)。 我已经安装了Linux 3.0.0内核,因为BtrFS更新日志声明,在Ubuntu 11.04(2.6.38)附带的内核中,批量TRIM不可用。

这是我的testing方法(最初通过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 for i in {0..10} ; do let A="$i * 65536" ; hdparm --trim-sector-ranges $A:65535 --please-destroy-my-drive /dev/sda ; done
  • 确认驱动器是TRIM'd: ./sectors.pl |grep + | tee sectors-$(date +%s) ./sectors.pl |grep + | tee sectors-$(date +%s)
  • 分区驱动器: fdisk /dev/sda
  • build立文件系统: mkfs.btrfs /dev/sda1
  • 挂载: sudo mount -t btrfs -o ssd /dev/sda1 /mnt
  • 创build一个文件: dd if=/dev/urandom of=/mnt/testfile bs=1k count=50000 oflag=direct
  • validation文件在磁盘上: ./sectors.pl | tee sectors-$(date +%s) ./sectors.pl | tee sectors-$(date +%s)
  • 删除testing文件: rm /mnt/testfile
  • 看到testing文件是从磁盘./sectors.pl | tee sectors-$(date +%s)./sectors.pl | tee sectors-$(date +%s) ./sectors.pl | tee sectors-$(date +%s)
  • validationTRIM'd块:区分两个最近的sectors-*文件

此时,预删除和后删除validation仍显示相同的磁盘块在使用中。 我应该看到在使用块的数量减less。 在testing文件被删除之后等待一个小时(如果需要发出TRIM命令需要一段时间)仍然显示相同的使用块。

我也试着用-o ssd,discard选项挂载,但这似乎没有任何帮助。

从上面的fdisk创build的分区(我保持分区小,以便validation可以更快):

 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"; 

我的testing方法是否有缺陷? 我在这里错过了什么?

谢谢您的帮助。

    所以经过多天的工作,我能够certificateBtrFS确实使用了TRIM。 我无法成功地在将要部署这些SSD的服务器上运行TRIM。 但是,使用插入笔记本电脑的相同驱动器进行testing时,testing会成功。

    用于所有这些testing的硬件:

    • Crucial M4 SSD 512GB
    • HP DL160se G6
    • LSI LSISAS9200-8e HBA
    • 通用SAS机箱
    • 戴尔XPS m1210笔记本电脑

    在validation服务器上的BtrFS失败之后,我决定使用旧笔记本电脑进行相同的testing(删除RAID卡层)。 在笔记本电脑上使用Ext4和BtrFS的这个testing的初始尝试失败(数据不是TRIM'd)。

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

    为了确保TRIM命令有时间运行,我在执行validation之前执行了rm /mnt/testfile && sync && sleep 120

    有一件事要注意,如果你正在尝试这个相同的testing:固态硬盘有擦除块,他们经营(我不知道的Crucial m4擦除块的大小)。 当文件系统发送TRIM命令到驱动器时​​,驱动器将只擦除一个完整的块; 如果为块的一部分指定了TRIM命令,则由于擦除块内剩余的有效数据,该块将不会被TRIM。

    所以说明我在说什么(上面的sectors.pl脚本的输出)。 这是在SSD上的testing文件。 期间是只包含零的部分。 加号有一个或多个非零字节。

    testing文件在驱动器上:

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

    testing文件从驱动器中删除(在sync && sleep 120 ):

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

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

    一个外带的forms:一些Ext4 TRIMtesting指令要求用户只validation第一个扇区是从文件TRIM'd。 testing人员应该查看testing文件的大部分,以确定TRIM是否成功。

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

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

    您假定TRIM将导致您的SSD清零已被删除的块。 但是,情况往往不是这样。

    这只有在SSD实施TRIM以便将丢弃的块归零时才是如此。 您可以检查设备是否至less知道报告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

    顺便说一句,我正在寻找一种可靠的方式来validationTRIM,但还没有find。 我很想知道,如果有人find一个方法。

    这里是10.10和EXT4的testing方法。 也许会有帮助。

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

    哦,我认为你需要fstab安装上的丢弃参数。 不知道是否需要SSD参数,因为我认为它应该自动检测SSD。

    对于btrfs,您需要discard选项以启用TRIM支持。

    functionTRIM的一个非常简单但是工作的testing在这里: http : //techgage.com/article/enabling_and_testing_ssd_trim_support_under_linux/2

    有些事情需要考虑(帮助回答“我错过了什么?”问题):

    • / dev / sda究竟是什么? 一个单一的SSD? 或者(硬件?)RAIDarrays的SSD?

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

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

    最后,

    • 如果您将/ dev / sda1格式化为btrfs以外的其他格式,您的testing方法是否会为您提供预期的结果?

    几乎所有带有SATA接口的SSD都会运行某种完全隐藏的日志结构文件系统。 SATA'trim'命令告诉设备该块不再被使用,并且如果/相应的擦除块(可能更大)/ only /包含标记有trim的块,底层日志结构文件系统可以使其闪烁。

    我还没有阅读标准文档,这是在这里: http : //t13.org/Documents/MinutesDefault.aspx?keyword=trim ,但我不知道是否有任何标准级别的保证,你可以查看修剪命令的结果。 如果你可以看到一些变化,就像在擦除块开始时的第一个字节被清零一样,我不认为这是适用于不同设备甚至是固件版本的保证。

    如果考虑抽象的实现方式,应该可以使修剪命令的结果完全不可见,只有读取/写入块才是可见的。 此外,可能很难判断哪些块位于同一擦除块中,因为只有闪存转换层必须知道这些块,并且可能已经对其进行了逻辑重新sorting。

    也许有一个SATA命令(OEM命令或许?)用于获取与SSD闪存转换层相关的元数据?