Trim命令

title: 闪存磁盘机特有的问题.
content: 因为许多文件系统以标记数据块为“未使用”来处理删除操作,存储介质(传统硬盘、SSD)通常不知道哪个扇区/页是真在使用,哪些可被认作空闲空间。因此与重写操作不同,删除将不涉及对数据所在扇区的物理写入。由于通用SSD不了解文件系统结构(例如未使用的块/扇区的列表),存储介质无法获知哪些块已经变为可用。这使反删除工具能从传统的机械硬盘上恢复文件,因为尽管操作系统报告文件已被“删除”,文件所在的扇区只是在操作系统之后进行写入时作为空闲空间的扇区,从而有效使操作变得像重写操作。对于机械磁盘来说,这与写入空扇区没有区别,但因为SSD最底层的一些特性,与将数据写入空页面相比,重写会有显着的开销,从而潜在地削弱写入性能。  SSD在闪存单元中通常以4至16kB的分组来存储数据,并将分组组合成128至512页的块。例如,512kB以4kB为一页存储在128页的块中。NAND闪存单元只能在处于空状态时写入。如果它们可能包含数据,则执行写操作前必须擦除其内容。一次SSD写入操作可以只完成单个页,但由于硬件限制,擦除命令始终会影响整个块;因此将数据写入到SSD上的空页非常快,而写入存在数据的页就会显著变慢。由于页被再次写入前需要擦除单元,但擦除只能对整个块,改写将按“读取、擦除、修改、写入”的方式完成;整个块的内容会先存储在缓存中,然后在SSD中擦除整个块,再将改写的页写入到缓存的块,最后再将更新的块写入闪存介质。这种现象也称写入放大。
title: 操作.
content: TRIM命令使操作系统得以通知SSD哪个页不再包含有效的数据。对于文件删除操作,操作系统会将文件删除标记为可用于新数据,然后向SSD发送TRIM命令。在Trim后,在新的数据写入闪存页面时,SSD不保留块的任何内容,从而实现更少的写入放大(更少的写入)、更高的写入吞吐量(不需要读取、擦除、修改),从而增加驱动器寿命。  不同的SSD实现的命令有所不同,因此性能可能也有所差异。  Trim为不可逆地擦除数据,无法恢复;这不同于机械硬盘中被删除的数据可能被数据恢复。
title: 实现.
title: 操作系统支持.
content: Trim仅在支持它的操作系统上有效。下表列出了各个重要的操作系统支持该命令的首个版本。此外,在TRIM命令添加到ATA标准之前设计的旧款固态驱动器需要更新固件(如果有)才能支持Trim,否则将忽略这个新命令。
title: RAID问题.
content: ,大多数基于硬件的RAID技术未实现TRIM命令的支持。但是,软件实现的RAID通常提供了TRIM支持。  Windows:  Windows 10为SSD RAID卷在配置一个RAID卷时通过“优化驱动器”选项提供了TRIM支持。  Mac OS:  macOS RAID驱动程序不支持TRIM。自Mac OS X 10.7至macOS 10.12.x的所有版本均是如此。  对于使用第三方SoftRAID®应用程序的RAID(0,1,4,5和10)卷支持TRIM,包括使用非苹果品牌SSD设备的TRIM支持。 (注:非苹果品牌的SSD设备必须使用终端命令“sudo trimforce enable”来启动TRIM)  Linux:  2011年1月以后的Linux内核中dmraid的发布版本已实现BIOS辅助的“假硬件RAID”支持,并且现在通行来自RAID阵列上的文件系统的任何TRIM请求。 不同于dmraid,Linux的常规目的软件RAID系统mdraid有实验性的基于批处理(而不是在文件删除时实时)的TRIM,当系统配置为定期在RAID 1阵列上的文件系统上运行mdtrim实用工具(包括ext3等没有原生TRIM支持的文件系统)。在Linux的稍晚版本(例如Red Hat Enterprise Linux 6.5和beyond)中 mdraid支持实时、实际传递TRIM命令,而不是作为一个批处理作业。  但请注意,红帽公司建议不要在大多数RAID技术的SSD上使用软件RAID 1、4、5和6,因为大多数RAID管理实用工具(例如Linux的mdadm)在初始化期间会在设备上写入所有块以确保校验和(或RAID 1/10情况下的驱动器到驱动器验证)运作正常,而这导致SSD认为除备用区域以外的所有块都在使用中,从而显著降低性能。  另一方面,Red Hat推荐在SSD上为LVM RAID使用RAID 1或RAID 10,因为这些级别支持TRIM(在Linux术语中称为"discard"),并且LVM实用工具在创建时不会写入所有块到RAID 1或RAID 10卷。  在2010年3月的一小段时间内,用户被误导相信英特尔快速存储技术(RST)9.6驱动程序支持RAID卷上的TRIM,但后来英特尔澄清说,TRIM支持AHCI模式和RAID模式的BIOS设置,但不支持RAID卷的驱动器。  截至2012年8月,英特尔确认,使用快速存储技术(RST)11.2驱动程序的7系列芯片组支持微软Windows 7中的RAID 0的TRIM。虽然英特尔没有确认支持6系列芯片组,RAID 0卷上的TRIM已展示为在Z68、P67和X79芯片组上可用,通过由硬件发烧友修改的RAID选项ROM。据推测,缺乏对6系列芯片组的官方支持是由于验证成本或企图鼓励消费者升级,而不是出于技术原因。  在使用X79芯片组的主板上需要修改选项ROM的例外是制造商添加了ROM开关;这需要RST和RST-E ROM存在于BIOS/UEFI内。这允许使用RST ROM而不是RST-E ROM,从而允许TRIM工作。英特尔指出,使用与ROM版本相同的驱动程序可以实现最佳性能。例如,如果BIOS/UEFI具有11.0.0.0m选项ROM,则应使用11.x版本的驱动程序。
title: 为不支持的操作系统使用.
content: 在使用不支持自动TRIM的文件系统时,某些实用工具可以手动发送Trim命令。通常它们将确定哪些块为空闲,然后将该列表以一系列的Trim命令传递给驱动器。这些实用程序可从各制造商(例如Intel、G.Skill)或作为一般实用程序(例如Linux的hdparm自v9.17起,或者如上所述的mdtrim)。
title: 硬件支持.
title: ATA.
content: TRIM命令规范已被标准化为AT Attachment接口标准的一部分,由国际信息技术标准委员会(INCITS)的技术委员会T13所领导。 TRIM根据DATA SET MANAGEMENT(数据集管理)命令(操作码06h)实现,ACS-2规范草案。ATA标准被并行(IDE、PATA)和串口(SATA)ATA硬件所支持。  原版ATA TRIM命令的缺点是它被定义为不可排队命令,因此不能轻松地与正常的、排队的读和写操作混合。SATA 3.1引入了一个排队的TRIM命令来纠正这一点。  ATA IDENTIFY DEVICE命令返回的SATA Words 69和169定义了不同类型的TRIM。 在SATA字105中有额外信息,描述驱动器可以在每个数据集管理命令(DATA SET MANAGEMENT)支持最多多少个512字节的数据块。通常此值默认为8(或4kB),但许多驱动器将其减少到1,以满足微软Windows硬件要求对TRIM的部分——该命令完成时间不应超过20 ms或者8 ms × (LBA范围项的数量),且两者中的较大者应始终小于600 ms。  各LBA范围被称为一个LBA范围条目,并由八个字节表示。 LBA由LBA范围条目的前6个字节表示,范围长度是由剩下两个字节表示的一个从零开始的计数器。如果两个字节组成的范围长度为零,那么LBA范围条目应视作填充而丢弃。这意味着以512字节为TRIM块范围支持的设备,该最大值为64个32 MB,也就是2 GB。如果设备在SATA字105处设为8,则它应该能在单个TRIM(数据集管理)命令中修整16GB。
title: SCSI.
content: SCSI提供了UNMAP命令(TRIM的完全模拟),以及带有UNMAP标志集的WRITE SAME命令(10和16个变量)。
title: SD/MMC.
content: 多媒体记忆卡和SD ERASE(CMD38)命令提供了与ATA TRIM命令类似的功能,但它要求擦除的块用0或1重写。eMMC 4.5进一步定义了一个“discard”(丢弃)子操作,从而更紧密的配合ATA TRIM,因为丢弃的块的内容可以被认为是不确定的(即“不在乎”的)。  这些设备已被列入Linux内核中libata-core.c的黑名单,从而强制发送非排队的TRIM命令到这些设备,而不是排队的TRIM命令: 此文件也已将SuperSSpeed S238列入常规TRIM的黑名单,因为发出TRIM会导致错误的块丢失数据。
title: 缺点.
content: libata-core.c还有一个列出子系统维护者已确认正确实现DRAT和RZAT标志(flags)的SSD,这不同于许多忽略它们的驱动器。白名单中的设备如下:

Summary: trim命令(ATA命令集中称为TRIM,SCSI命令集中称为UNMAP),它使操作系统能通知固态硬盘(SSD)哪些数据块已不再考虑使用,可以被内部擦除。

TRIM: TRIM ist ein Befehl, um den Controller eines Speichermediums über derzeit nicht (mehr) benötigte Datenblöcke zu informieren. Der Controller markiert die betreffenden Blöcke intern, um sie im Folgenden überschreiben zu können. Der Befehl wird vom Computer (normalerweise dem Dateisystem-Treiber innerhalb des Betriebssystems) an den Controller gesendet.