TRIMコマンド(ATAコマンドセット:TRIM、SCSIコマンドセット:UNMAP)は、オペレーティングシステムからソリッドステートドライブ(SSD)の未使用領域を内部的に消去するために用いられるコマンドである。

SSDの登場から間もなくTRIMコマンドが登場した。 SSDへのハードウェア的な操作は、従来のハードディスクドライブとは大きく異なるため、オペレーティングシステムから削除やフォーマットなどの操作を従来通り行った場合に、書き込み操作で予期せず段階的なパフォーマンス低下が発生した。TRIMの実行により、SSDはガベージコレクションをより効率的に処理できる。実行しない場合は、書き込み動作が遅延する可能性がある。

一部のドライブにおいては、工場出荷状態にリセットするツールは、TRIMの導入前から存在していたが、ドライブ上のすべてのデータも削除されるため、使用中に最適化のために使用することは現実的ではない 。また、2014年までには多くのSSDに対し、TRIMとは独立して機能する、バックグラウンドガベージコレクションメカニズムが搭載されるようになった。これにより、TRIMをサポートしていないOSでもパフォーマンスが維持できるようになったが、 ライトアンプリフィケーションが発生しやすくなる上、フラッシュセルの寿命を縮める欠点が存在した。

## 背景

多くのファイルシステムでは削除操作を処理する場合、データブロックに「未使用」のフラグを立てる 。これにより、いずれのストレージメディアでもどの領域が本当に使用中であるかに関わらず、空きスペースとして領域を使用できる。上書き操作とは異なり、削除操作時においては、データを含むセクターへの物理的な書き込みは行われない。一般的なSSDにおいては、未使用の領域のリストを含むファイルシステム構造を処理せず,そのまま書き込み動作を行うため、メディア側では領域が使用可能になったことは認識されない。 これにより、ハードディスクなどでは、削除されたファイルを復元するツールが利用できるようになっている 。つまり、いずれのメディアの場合でも、未使用領域を使用したという場合でも上書き操作が行われている可能性が存在する。 磁気ディスクの場合、空のセクターへの書き込みと上書き操作に相違はないが、一部のSSDは機能の実装が最低レベルであるため、上書きは完全未使用の領域にデータを書き込む場合に比べて大きなオーバーヘッドを生じ、書き込みパフォーマンスを損なう可能性がある 。

SSDは、通常4〜16 kiB単位でグループ化されたフラッシュメモリのセルにデータを格納し、通常それを128〜512ページのブロックにグループ化する 。NANDフラッシュメモリセルの場合、領域が完全に空の場合にのみ書き込み操作が実行できる。データが残存している可能性がある場合、書き込み操作の前に領域を消去する必要がある。SSDへの書き込み操作はページ単位で実行できるが、ハードウェアの制限により、消去は常にブロック全体に対して実行される。よって、SSDの空の領域への書き込み操作は非常に高速だが、以前に使用された領域を上書きする必要がある場合、遅延が発生する。 再度書き込む前にページ内のセルの消去が必要となるが、消去できるのはブロック全体であるので、上書きすると読み取り-消去-変更-書き込みサイクルが実行される 。削除対象のブロックに存在するデータ全体が一旦キャッシュに保存され、ブロック全体を消去し、上書きされた部分がキャッシュに書き込まれる。その後、更新されたブロック全体をフラッシュメディアに書き込む。この現象はライトアンプリフィケーションとして知られている 。

## 操作

TRIMコマンドを使用すると、オペレーティングシステムは、使用しなくなったページをSSDに通知できる。ファイル削除操作の場合、オペレーティングシステムはファイルのセクターを空き領域としてマークし、TRIMコマンドをSSDに送信する。その後新しいデータを書き込むときににSSDはブロックの内容を保持しないため、書き込み量を少なくすることとなり、書き込みスループットが高くなる。よって、寿命を延ばすことが期待できる。

ただし、SSDによってコマンドの実装方法が異なるため、得られるパフォーマンスが異なる場合がある 。

TRIMはSSDにLBA領域を無効としてマークするように指示し、その後に領域の読み取りを行ったとしても意味のあるデータを返さなくなる。非常に短い間、データが依然としてフラッシュメモリ内に存在する可能性があるが、TRIMコマンドが発行されてガベージコレクションが実行された後は、専門家でさえデータを回復できる可能性はほぼないとされている。

## 実装

### オペレーティングシステムでのサポート

TRIMコマンドの発行は、サポートされているオペレーティングシステムでのみ実行される。以下の表は、オペレーティングシステムと、コマンドをサポートする最初のバージョンを示している。さらに、ATA規格にTRIMコマンドが追加されるよりも前に設計された古いSSDでは、ファームウェアの更新が必要となる。更新されていない場合、新しいコマンドは無視される。ただし、すべての古いSSDでTRIMコマンドをサポートするアップデートが準備されているわけではない。

空き領域を正しく理解しているプログラムだけが安全にコマンドを発行できるため、TRIMのサポートは、ファイルシステムドライバーによっても異なる。

| オペレーティング・システム | サポート開始 | 備考 |
| --- | --- | --- |
| DragonFly BSD | 2011-05 2011年5月 |  |
| FreeBSD | 2010-07 8.1 – 2010年7月 | バージョン8.1でブロックデバイスレイヤーに追加。UFSに対しては8.3および9で追加 、ZFSに対しては9.2で追加。ソフトウェアRAID環境へは10で対応。 |
| NetBSD | 2012-10 2012年10月 |  |
| Linux | 2008-12-25 2.6.28–25 2008年12月 | 2.6.28でFTL NANDフラッシュデバイス初期サポートが追加。 ATA TRIMコマンドのサポートは、2.6.33で追加。 トリムを自動的に発行できるファイルシステムは、 Ext4 、Btrfs、FAT、GFS2、JFS、XFS、およびNTFS-3G。  一部のディストリビューションでは、パフォーマンスの問題により、自動実行をデフォルトで無効にし、スケジュール化で対応している。Ext3、NILFS2、およびOCFS2では、オフラインでのTRIMを実行するioctlが用いられる。仕様ではTRIM実行範囲のリストが必要だが、カーネル3.0では、単一の範囲でのみ呼び出されるため、実行が遅い。 |
| macOS | 2011-06-23 10.6.8(2011年6月23日) | AHCIブロックデバイスドライバーは、10.6.6(10J3210)でTRIMのサポート有無を表示する機能を搭載した が、IOStorageFamilyおよびHFS Plusファイルシステムを介してTRIMを実行できるようになった10.6.8までは使用できなかった。 10.10.4以前では、AppleブランドのSSDに対してのみネイティブでTRIMが有効となっていた。ただし、サードパーティのユーティリティを使用して、他社製のSSDに対しても機能を有効化できる。 Yosemiteへのアップデートにより、古いサードパーティのTRIMドライバーが使用できなくなったが、Yosemiteでも動作する更新されたドライバーは存在している 。アップデート10.10.4で、コマンドラインユーティリティのtrimforceから他社製SSDに対してもTRIMを有効化できるようになった。 |
| Microsoft Windows | 2009–10 Windows 7・Windows Server 2008 R2 – 2009年10月 | Windows 7は当初、 パラレルATAおよびシリアルATAを含むATアタッチメントファミリのドライブに対してのみTRIMをサポートし、デバイス自体がコマンドを受け入れる場合でも、Storport PCI-Express SSDなどのデバイスに対してはサポートしていなかった。ネイティブのMicrosoftドライバーでは、TRIMコマンドはWindows 7のAHCIおよびレガシーIDE / ATAモードで動作することが確認されている。Windows 8以降では、NVMeによるPCI Express SSDのトリムと、USB Attached SCSI Protocol(UASP)などのSCSIドライバースタックを使用するデバイスに対しての、TRIMコマンドと同様のunmapコマンドをサポートする。 Windows 7に対しては、KB2990941のアップデートをDISMを利用しセットアップ時に組み込むことにより、PCIe SSDへのTRIM を追加できる。 TRIMはReFSとNTFSでサポートされており、無効化するためのDisableDeleteNotifyスイッチも実装されている。他のファイルシステムに対しての実装は、複数ソース間で情報が一致していない。 |
| OpenSolaris | 2010-07 2010年7月 |  |
| Android | 2013から7 4.3 - 2013年7月24日 | デバイスが1時間以上アイドル状態で、80%以上充電されている場合(充電器に接続されている場合は30%以上)、24時間ごとに最大1回`fstrimを`自動的に実行する。 |

### RAIDへの問題

2017年1月 (2017-01)現在, TRIMコマンドへのサポートはほとんどすべてのハードウェアRAIDにおいては実装されていない。しかし、ソフトウェアRAID の場合はサポートされている場合がある。

#### Windows

Windows 10では、RAIDボリュームの構成時に「ドライブの最適化」のオプションを使用することで、SSDを含むRAIDボリュームでもTRIMをサポートする。

#### macOS

macOSの標準RAIDドライバーはTRIMをサポートしていない。この問題は、少なくとも10.7からmacOS 10.12.xまでのすべてのバージョンで該当する。

アップル以外製SSDでのTRIMサポートを含むサードパーティのSoftRAID®アプリケーションを使用する場合、TRIMはRAID(0、1、4、5、10)ボリュームでサポートされる。ただし、ターミナルコマンド「sudo trimforce enable」を使用して明示的に有効にする必要がある。

#### Linux

TRIMは、Linuxカーネル内のdmraidにおいて、2011年1月以降のリリースで使用可能となった。これは、BIOSによる「偽のハードウェアRAID」へのサポートであり、RAID上にあるファイルシステムからのTRIMリクエストを透過的に処理する。

Linuxの汎用ソフトウェアRAIDシステムであるmdraidでは、システムがファイルシステムでmdtrimユーティリティを定期的に実行するように構成されている場合、RAID 1上でバッチベース(ファイル削除時実行)のTRIMを試験的にサポートしている。Red Hat Enterprise Linux 6.5以降などのLinuxの新しいバージョンでは、mdraidは、単なるバッチジョブとしてではなく、実際にTRIMコマンドをリアルタイムで渡すことをサポートしている。

しかし、Red HatはソフトウェアRAIDのうち1、4、5、6を使用しないことを推奨しており、理由として、ほとんどのRAID管理ユーティリティ(Linuxにおけるmdadmなど )での初期化時にデバイスのすべてのブロックに書き込み処理を行い、チェックサム(またはRAID 1/10の場合はドライブ間の検証)が適切に動作することを確認するためである。これにより、SSDにおいてはスペア領域以外のすべてのブロックが使用中の場合、パフォーマンスが大幅に低下する。

一方、Red Hatは、TRIM(Linux用語では「破棄」)をサポートしており、LVMユーティリティは作成時にすべてのブロックに対する書き込み処理を行わないため、SSD上のLVM RAIDに対してはRAID 1またはRAID 10を使用することを推奨している。

2010年3月、ユーザー間でIntel Rapid Storage Technology(RST)9.6ドライバーがRAIDボリュームでTRIMをサポートしていると信じられるようになったが、Intelは後にTRIMがAHCIモードとRAIDモードのBIOS設定でサポートされるが,RAIDボリュームの一部として使用される場合はサポートしないことを明らかにした。

2012年8月の時点で、IntelはRapid Storage Technology(RST)11.2ドライバーを搭載した7シリーズのチップセットがMicrosoft Windows 7におけるRAID 0のTRIMをサポートしていることを確認している。Intelは6シリーズチップセットのサポートを確認していないが、RAID 0ボリュームでのTRIMは、変更されたRAIDオプションROMを使用することで、Z68、P67、X79のチップセットで動作することが示されている。6シリーズチップセットで公式にサポートされていない理由として、技術的なものではなく、検証コストないし消費者にアップグレードを促す目的であると推測されている。

X79チップセットを備えたマザーボードにおいてオプションROMを変更しなくても問題ない場合は、製造元がROMスイッチを追加した場合である。BIOSとUEFIの内部にRST ROMとRST-E ROMの両方があれば、RST-E ROMの代わりにRST ROMを使用して、TRIMを機能させることが可能となる。Intelは、ROMと同じバージョンのドライバーを使用することで最高のパフォーマンスが得られると述べている。たとえば、BIOS・UEFIに11.0.0.0mオプションROMがある場合、11.xバージョンのドライバーを使用する必要がある。

### サポートされていないファイルシステムでの有効化

ファイルシステムが自動的にTRIMをサポートしない場合でも、一部のユーティリティではTRIMコマンドを手動で送信できる。通常、ユーティリティが使用されていないブロックを判別し、リストをコマンドとしてドライブに渡す。このようなユーティリティは、複数のメーカーが提供している(例: Intel、G.Skill )。また、一般的なユーティリティ(例:Linuxのhdparmv9.17以降の"wiper" 、mdtrim)としても提供されている。hdparmとmdtrimはいずれも、ファイルシステムに大きなファイルを割り当て、割り当てられている物理的な場所を解決することにより、空きブロックを検索する。

## ハードウェアサポート

### ATA

TRIMコマンドの仕様は、 国際情報技術標準委員会 (INCITS)の技術委員会T13が主導するATアタッチメント (ATA)インターフェイス標準の一部として標準化されている。TRIMは、ドラフトACS-2仕様のDATA SET MANAGEMENTコマンド(opcode 06h)で実装されている。また、ATA規格は、パラレル(IDE、PATA)・シリアル(SATA)の両方でサポートされている。

オリジナルのATA TRIMコマンドの欠点は、キューに入れられないコマンドとして定義されていたため、キューに入れられた読み取りおよび書き込み操作の通常のワークロードと簡単に混在させることができない点であった。 SATA 3.1では、これを修正するためにキューに入れられたTRIMコマンドが導入された。

ATA IDENTIFY DEVICEコマンドから返されるSATAワード69および169により定義される、複数種のTRIMコマンドが存在する。

- 非決定的TRIM:TRIM後の論理ブロックアドレス (LBA)への読み取りコマンドで、異なるデータを返す場合がある。
- 確定的TRIM(DRAT):TRIM後のLBAへの読み取りコマンドは、同じデータを返すか、確定的となる。
- TRIM後の確定的読み取りゼロ(RZAT):TRIM後のLBAへのすべての読み取りコマンドはゼロを返す。

SATAワード105には、ドライブがサポートできるDATA SET MANAGEMENTコマンドごとの512バイトブロックの最大数を示す追加情報が存在する。 通常、これはデフォルトで8または4 kBとなっているが、多くのドライブでは1として、TRIMのMicrosoft Windowsハードウェア要件に存在する、コマンド完了時間が20ミリ秒または8ミリ秒×LBA範囲エントリ数のいずれか以上かつ600ミリ秒未満でなければならないという条件を満たすようにしている。

個々のLBA範囲はLBA範囲エントリと呼ばれ、8バイトで表現される。LBA自体は、LBA範囲エントリの最初の6バイトで表され、範囲長が残りの2バイトで表されている。範囲長のビットがすべてゼロの場合、LBA範囲エントリはパディングとして破棄される。つまり、1回のTRIM範囲で最大で32 MBの64倍すなわち2GBが指定される。デバイスがSATAワード105で8をサポートしている場合、1回のTRIM(DATA SET MANAGEMENT)コマンドで16 GBをトリムできることとなる。

### SCSI

SCSIでは、TRIMと同一内容であるUNMAPコマンド、およびUNMAPフラグが設定されたWRITE SAMEコマンド(10および16バリアント)が存在する。

### SD/MMC

MultiMediaCardおよびSD ERASE(CMD38)コマンドは、ATAでのTRIMコマンドと同様の機能を提供するが、消去されたブロックをその後0または1で上書きする必要がある。eMMC 4.5では、破棄されたブロックの内容が不確定と見なすことができる点でTRIMコマンドにより類似した「破棄」サブオペレーションを定義した。

### NVM Express

NVM Expressコマンドセットでは、ホストの意図を一連のブロック範囲のストレージデバイスに示めすための汎用のコマンドが存在する。その操作の1つであるdeallocateコマンドはTRIMを実行することと同義である。また、deallocateコマンド実行へのヒントを提供し、ディスクがゼロをトリミングして返すことを可能にするWrite Zeroesコマンドも存在する。

## 短所

- 暗号化が使用されている場合、TRIMコマンドを使用すると、使用されているブロックと使用されていないブロックに関する情報が明らかになってしまう。
- オリジナルのTRIMコマンドは、 T13小委員会によって非キューコマンドとして定義されていたため、たとえば各ファイルシステムの削除コマンドの後に送信された場合など、不注意に使用すると、大量の実行ペナルティが発生する可能性がある。非キューコマンドの性質上、デバイスドライバは、未解決のコマンドがすべて完了するのを待機し、TRIMコマンドを発行してから、通常のコマンドを再開する必要がある。SSDのファームウェアによっては、TRIMが完了するまでにかなりの時間がかかってしまい、ガベージコレクションサイクルがトリガーされる場合もある。このペナルティは、システムの使用率が最小になるようなバッチジョブをスケジュールすることにより、ファイルの削除ごとにトリミングするのではなく、定期的にバッチTRIMを実行することで最小限に抑えられる。このTRIMの欠点は、Queued TRIMコマンドの導入により、シリアルATAリビジョン3.1で改善した。
- Queued TRIMへのサポートを誤ってシステムに通知しているか、実装に重大なバグがあるドライブファームウェアにより、いくつかのデバイス、特にMicronとCrucialのM500およびSamsungの840および850シリーズなどで深刻なデータ破損を引き起こすとされている。

以下のデバイスは、Linuxカーネルのlibata-core.cでブラックリストに登録されており、非キューTRIMコマンド(ATA\_HORKAGE\_NO\_NCQ\_TRIM)の送信を強制される。

- Micron/Crucial M500 
- Micron M510 (ファームウェアバージョン MU01)
- Micron/Crucial M550 (ファームウェアバージョン MU01)
- Crucial MX100 (ファームウェアバージョン MU01)
- Samsung 840/850 シリーズ(すべてのファームウェア)

また、このファイルは、TRIMが発行されたときに誤ったブロックがデータを失う原因となるため、SuperSSpeed S238をTRIMコマンドへのブラックリストに載せている。

libata-core.cには、サブシステムのメンテナーがDRATフラグとRZATフラグ(`ATA_HORKAGE_ZERO_AFTER_TRIM`)を確実に認識しているSSDを列挙しているホワイトリストもある。 ホワイトリストに登録されているドライブは以下の通りである。

- Crucial SSD
- Intel SSD 510を除くIntel SSD
- Micron SSD
- Samsung SSD
- Seagate SSD