Trim命令

特里姆
Trim命令（ATA命令集中稱為TRIM，SCSI命令集中稱為UNMAP），它使操作系統能通知固態硬盤（SSD）哪些數據塊已不再考慮使用，可以被內部擦除。
Trim命令幾乎是與SSD同時推出的。這是因為SSD的底層操作方式與傳統機械硬盤有著顯著不同，若操作系統沿用傳統方法處理諸如刪除和格式化等操作，會導致SSD的寫入性能發生下降。Trim（意為修整、修剪、裁剪）使SSD能更有效地完成垃圾收集的工作，而不用犧牲對存儲塊的寫入速度。
儘管在引入Trim命令前，有些工具（比如“Reset”命令）已經可以將驅動器“重置”為空狀態，但這些操作會刪除驅動器上的所有數據，因而無法用於持續性優化。許多SSD擁有廠商自己的後臺垃圾收集機制，這些工具和Trim命令互相獨立，使不支持Trim命令的操作系統能完成與之類似的工作，卻依然存在寫入放大的現象，往往也會導致存儲塊壽命過早地衰減。

**快閃記憶體磁碟機特有的問題**
因為許多文件系統以標記數據塊為“未使用”來處理刪除操作，而非真正“清空”數據，因此存儲介質（傳統硬盤、SSD）通常不知道哪個扇區/頁是正在使用，哪些可被認作空閒空間，這與重寫（rewrite）操作不同，刪除操作不涉及對數據所在扇區/頁的物理寫入。SSD等存儲介質通常不負責管理文件系統（例如未使用的數據塊/扇區表），也無法獲知哪些數據塊/扇區已經可用。這使反刪除工具能通過更底層的方法，從傳統的機械硬盤上恢復文件，因為儘管操作系統報告用戶文件已被“刪除”，並騰出了存儲空間。但在存儲介質上，文件所在的扇區只有在下一次寫入時，舊數據才會被覆蓋，從存儲介質的角度看，“刪除”操作更接近於“重寫”。對於機械磁盤來說，這與寫入空扇區沒有區別，但因為SSD最底層的一些特性，與將數據寫入空頁相比，重寫會有顯著的開銷，從而潛在地削弱寫入性能。
SSD在閃存單元中通常以4-16kB為一組來存儲數據（稱之為頁），每128-512kB的頁組合成更大的一組（稱之為塊或數據塊）。舉例來說，某一品牌的SSD將4kB的數據組合成一頁，其數據塊大小是512kB，每一數據塊包含128個頁。NAND閃存單元只能在處於空狀態時寫入。如果它們包含數據，則執行寫操作前必須擦除其內容。SSD一次寫入最少一頁，但由於硬件限制，擦除數據時將會抹除整個數據塊；因此將數據寫入到SSD上的空頁時非常快，而寫入已有數據的頁就會明顯變慢。這是因為頁被再次寫入前需要擦除數據，但SSD只能擦除一整個數據塊，隨後把數據塊中的其他數據以改寫的方式（按“讀取、擦除、修改、寫入”的方式）完成；整個塊的內容會先存儲在緩存中，然後在SSD中擦除整個塊，再將改寫的頁寫入到緩存的塊，最後再將更新的塊寫入閃存介質。這種現象也稱寫入放大。

**操作**
TRIM命令使SSD可以從操作系統處得知哪一部分數據將永遠不會被訪問。對於刪除操作，操作系統會將整個數據塊標記為可用於新數據，然後向SSD發送TRIM命令。SSD完成這一操作後，在新的數據寫入這一頁時，SSD將刷新整個塊的數據，而不保留塊中其他頁原本的內容，從而緩解寫入放大現象（寫入次數更少），並提供更高的寫入吞吐量（不需要執行讀取、擦除、修改），還能顯著延長驅動器壽命。
不同的SSD實現的方式有所不同，因此性能可能也有所差異。
TRIM命令通知SSD從LBA(Logical Block Addressing)區域上標記為無效，從邏輯層上對該區域進行讀取將不會返回有效數據。從物理層面看，數據仍可能短時間駐留在閃存內部，SSD徹底完成垃圾回收的工作之後，恢復數據幾乎是不可能的；這不同於機械硬盤中被刪除的數據可能被數據恢復。

**實現**

**操作系統支持**
Trim僅在支持它的操作系統上有效。下表列出了各個重要的操作系統支持該命令的首個版本。此外，在TRIM命令添加到ATA標準之前設計的舊款固態驅動器需要更新固件（如果有）才能支持Trim，否則將忽略這個新命令。

**RAID問題**
，大多數基於硬件的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版本的驅動程序。

**為不支持的操作系統使用**
在使用不支持自動TRIM的文件系統時，某些實用工具可以手動發送Trim命令。通常它們將確定哪些塊為空閒，然後將該列表以一系列的Trim命令傳遞給驅動器。這些實用程序可從各製造商（例如Intel、G.Skill）或作為一般實用程序（例如Linux的hdparm自v9.17起，或者如上所述的mdtrim）。

**硬件支持**

**ATA**
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。- 非確定性TRIM：TRIM後每個對邏輯區塊位址（LBA）的讀取命令可能返回不同的數據。- 確定性TRIM（DRAT）：TRIM後對LBA的所有讀取命令都返回相同的數據，或者變為確定的。- TRIM（RZAT）後確定性讀零：TRIM後對LBA的所有讀取命令都將返回零。
在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。

**SCSI**
SCSI提供了UNMAP命令（TRIM的完全模擬），以及帶有UNMAP標誌集的WRITE SAME命令（10和16個變量）。

**SD/MMC**
多媒體記憶卡和SD ERASE（CMD38）命令提供了與ATA TRIM命令類似的功能，但它要求擦除的塊用0或1重寫。eMMC 4.5進一步定義了一個“discard”（丟棄）子操作，從而更緊密的配合ATA TRIM，因為丟棄的塊的內容可以被認為是不確定的（即“不在乎”的）。

**缺點**
 在使用加密時，TRIM命令的相關信息將揭露哪些塊正在使用，哪些沒有。- TRIM命令的原始版本已被T13小組委員會定義為非排隊命令，因此執行不當可能造成大量的錯誤執行。例如，如果它在操作系統的每個刪除命令後發出，該命令的非排隊性質將要求驅動程序先等待所有未完成的命令完成，然後發出TRIM命令，最後再繼續正常命令。TRIM可能需要很長時間才能完成，這取決於SSD中的固件，並還可能觸發垃圾收集週期。date=May 2012這種缺陷可以用定期執行批量TRIM的解決方案來最小化，而不是在每次文件刪除時執行修剪，批量處理任務可以在系統利用率最小時調度。這項TRIM缺點已在Serial ATA修訂3.1中解決，其中引入了排隊的TRIM命令。- 排隊的TRIM命令已在多款設備中涉及嚴重的數據損壞，最顯著的是Micron的M500、Crucial的M500、以及Samsung 8**系列。在2015年7月1日，Linux操作系統在這些設備上的數據損壞已得到確認。
這些設備已被列入Linux內核中libata-core.c的黑名單，從而強制發送非排隊的TRIM命令到這些設備，而不是排隊的TRIM命令：- Micron M500，所有固件版本（僅MU07之前有此問題，但Linux尚未跟進）- Crucial M500，所有固件版本，包括工廠重新認證的SSD（僅MU07之前有此問題，但Linux尚未跟進）- Micron M510，固件版本MU01- Micron M550，固件版本MU01- Crucial M550，固件版本MU01- Crucial MX100，固件版本MU01- 三星SSD 8**系列，所有固件版本
此文件也已將SuperSSpeed S238列入常規TRIM的黑名單，因為發出TRIM會導致錯誤的塊丟失數據。
libata-core.c還有一個列出子系統維護者已確認正確實現DRAT和RZAT標誌（flags）的SSD，這不同於許多忽略它們的驅動器。白名單中的設備如下：- Crucial多款SSD- Intel多款SSD（不包括Intel SSD 510）- Micron多款SSD- 三星多款SSD- 希捷多款SSD

**參見**
 數據殘留

**參考資料**

**外部鏈接**
  From write() down to flash chips – An explanation on how the TRIM command lets SSDs erase data not used by the filesystem-  TRIM Command White Paperdate=20120514101926  – A white paper explaining the command's purpose and actions- Fusion-io Patent  "Apparatus, system, and method for redundant write caching"date=20161222230439