Linux Server に SSD を Software RAID (mdraid) で入れるときの確認ポイント

今更そんなの気にする必要ある?と言われそうだけど、調べていくうちにどんどん沼にはまったのでメモ。
※ATA は Trim で SCSI では UNMAP だとかその辺は今回は抜き。今回は SATA な一般のご家庭向けの SSD だけを対象とする。

■Linux Kernel のバージョン確認
Linux Kernel 2.6.33 以降ならば、基本的に ATA でも Trim コマンドの送出が可能になっている。
Red Hat Enterprise Linux 6 以降ならば、基本的に Trim 対応しているっぽい。
次のコマンドで 0 や Not Found が返ってくる場合は、対応していないとみていいらしい。

# cat /sys/block/[disk]/queue/discard_max_bytes

詳しくは、以下のサイトがわかりやすい。
Is there TRIM support for solid state drives (SSD) in RHEL6?
RHEL6 でソリッドステートドライブ (SSD) の TRIM はサポートされていますか?
もし、それ以外の Kernel の場合、ソースコードを確認し、次のコミットが適用されていれば、たぶん対応していそう。
libata: add translation for SCSI WRITE SAME (aka TRIM support)

しかし、今回調べたいのは Software RAID で Trim が使えるかどうかである。
RAID1 Trim support は Kernel 3.6 で Release candidate らしい。
RAID4/5/6 の Trim Support は Kernel 3.7 で対応らしい。
コミット内容はこれ。
md: raid 1 supports TRIM
MD: raid5 trim support

■ディスクそのものの Trim 対応確認
次のコマンドで、Data Set Management TRIM supported が返ってくれば Trim 対応のようだ。

# hdparm -I /dev/sdd | grep TRIM

ただし、今回は RAID 1 以上で使用するので、Trim した後のデータに注意する必要がある。
過去の SSD は、Trim コマンドを送出した後に該当 LBA を Read すると、何が返ってくるかわからなかったらしい。
Trim フラグがついたブロックが Garbage Collection 処理されたり、LBA と PBA のマッピングが Wear Leveling 処理などにより変動した際に、Write していない LBA においてはその処理前後での内容が保証されてなかったとか。
普通にシングルドライブとして使う場合は問題はでないが、RAID 1 などによってデータ保護を有効にしている場合はデータが化けた結果、RAID の不整合という致命的な障害になってしまう。
特に RAID4/5/6/DP などパリティによって複数ディスクのデータを保護している場合、パリティデータが保存されたディスクのブロック内で Trim が走った後に次回 Write されるまで返ってくる内容が不確定となると、データが化けかねない。というか化けるだろう。
これは、Microsoft が提唱した OS からストレージに未使用のブロック情報を通達する方法(Trim)を標準化を行う団体(ATAの標準化を行なうINCITS(米国規格協会ANSIの諮問機関)のT13技術委員会 らしい)に提案した「Data Set Management Commands Proposal for ATA8-ACS2」の仕様らしい。
Data Set Management Commands Proposal for ATA8-ACS2
Data Set Management Commands Proposal for ATA8-ACS2
【Mirror】Data Set Management Commands Proposal for ATA8-ACS2

Page 7
Trim
When trim is set to one the data in the logical blocks specified by the DATA SET MANAGEMENT command’s output data becomes indeterminate.

この問題に対して、NetApp と EMC というエンタープライズストレージベンダーが異議を唱えたらしい。
TRIM: Behavior of Subsequent READs
TRIM: Behavior of Subsequent READs
【Mirror】TRIM: Behavior of Subsequent READs
それにより、Trim 後の Read データを確定させるために、機能が追加されたとのこと。それが次の2つ。

  • Deterministic Read After Trim (DRAT)
  • Deterministic Read Zero After Trim (RZAT)

●Deterministic Read After Trim (DRAT)
規格については、次のドキュメント。
Deterministic TRIM Proposal for ATA8-ACS2
Deterministic TRIM Proposal for ATA8-ACS2
【Mirror】Deterministic TRIM Proposal for ATA8-ACS2
Trim した後の動きについては、次のようなことが書いてあった。

When trim is set to one the data in the logical blocks specified by the DATA SET MANAGEMENT command’s output data then:

  1. a) If word 69 bit 14 of the IDENTIFY DEVICE data is set to one, then once a trimmed LBA has been read (e.g., a read command), the data in that logical block becomes determinate (i.e., all read commands to a logical block shall return the same data until a subsequent write command to that logical block successfully completes); or
  2. b) If word 69 bit 14 of the IDENTIFY DEVICE data is cleared to zero, then the data read is indeterminate.


日本語的にはたぶん、Trim を送出した後に該当 LBA を Write する前に Read した場合、何らかの確定したデータを返すようにする。というように読める。気がする。

●Deterministic Read Zero After Trim (RZAT)
規格については、次のドキュメント。
Read zero after TRIM Proposal for ATA8-ACS2
Read zero after TRIM Proposal for ATA8-ACS2
【Mirror】Read zero after TRIM Proposal for ATA8-ACS2
Trim した後の動きについては、次のようなことが書いてあった。

If Trim is set to one, then the data in the logical block ranges addressed by the DATA SET MANAGEMENT command’s output data shall:

  1. a) if word 69 bit 14 of the IDENTIFY DEVICE data is set to one, then:
    1. A. after a trimmed LBA has been read (e.g., a read command has been processed), the data in that logical block becomes determinate (i.e., all read commands to a logical block shall return the same data until a subsequent write command to that logical block successfully completes);
    2. B. if word xx bit yy of the IDENTIFY DEVICE data is set to one, then the data returned by a read command shall have all words cleared to zero; and
    3. C. if word xx bit yy of the IDENTIFY DEVICE data is cleared to zero, then the data returned by a read command may have words set to any value;
  2. or
  3. b) if word 69 bit 14 of the IDENTIFY DEVICE data is cleared to zero, then the data read is indeterminate.


日本語的にはたぶん、Trim を送出した後に該当 LBA を Write する前に Read した場合、0x00 を必ず返す。というように読める。気がする。

これらを踏まえ、RAID に使う場合は RZAT に対応している SSD を選択するのが正しい気がする。気がする。

●Linux 上で RZAT 対応確認方法
hdparm にて確認すれば行けると思われる。

# hdparm -I /dev/sdd | grep Deterministic

この返り値が

  • 無い場合、DRAT / RZAT 未対応。
  • Deterministic read data after TRIM の場合、DRAT 対応
  • Deterministic read ZEROs after TRIM の場合、DRAT / RZAT 双方に対応

とみてよさそうである。
根拠は hdparm のソースコードにある identify.c の内容及び T13技術委員会のドキュメントによる裏付け。
・hdparm のソースコード identify.c より抜粋

static const char *feat_word69_str[16] = { 
	"CFast specification support",			/* word 69 bit 15 */
	"Deterministic read data after TRIM",		/* word 69 bit 14 */
	"Long physical sector diagnostics",		/* word 69 bit 13 */
	"DEVICE CONFIGURATION SET/IDENTIFY DMA commands", /* word 69 bit 12 */
	"READ BUFFER DMA command",			/* word 69 bit 11 */
	"WRITE BUFFER DMA command",			/* word 69 bit 10 */
	"SET MAX SETPASSWORD/UNLOCK DMA commands",	/* word 69 bit  9 */
	"DOWNLOAD MICROCODE DMA command",		/* word 69 bit  8 */
	"reserved 69[7]",				/* word 69 bit  7 */
	"reserved 69[6]",				/* word 69 bit  6 */
	"Deterministic read ZEROs after TRIM",		/* word 69 bit  5 */
	"reserved 69[4]",				/* word 69 bit  4 */
	"reserved 69[3]",				/* word 69 bit  3 */
	"reserved 69[2]",				/* word 69 bit  2 */
	"reserved 69[1]",				/* word 69 bit  1 */
	"reserved 69[0]",				/* word 69 bit  0 */
};
	if (like_std > 6) {
		const __u16 trimd = 1<<14;	/* deterministic read data after TRIM */
		const __u16 trimz = 1<<5;	/* deterministic read ZEROs after TRIM */
		__u16 word69 = val[69] & ~(trimz | trimd); /* TRIM bits require special interpretation */
		print_features(word69, word69, feat_word69_str);
		if (val[169] & 1 && val[169] != 0xffff) { /* supports TRIM ? */
			printf("\t   *\tData Set Management TRIM supported");
			if (val[105] && val[105] != 0xffff)
				printf(" (limit %u block%s)\n", val[105], val[105] > 1 ? "s" : "");
			else
				printf(" (limit unknown)\n");
			if (val[69] & trimd) { /* Deterministic TRIM support */
				if (val[69] & trimz)
					print_features(trimz, trimz, feat_word69_str);
				else
					print_features(trimd, trimd, feat_word69_str);
			}
		}
		
	}

TRIM – DRAT / RZAT clarifications for ATA8-ACS2 から抜粋
TRIM – DRAT / RZAT clarifications for ATA8-ACS2 から抜粋
【Mirror】TRIM – DRAT / RZAT clarifications for ATA8-ACS2

Table X – TRIM related interactions

Word 169
bit 0
Word 69
bit 14
Word 69
bit 5
Meaning
0 Reserved Reserved The Trim function of the DATA SET MANAGEMENT command (see 7.10.3.2) is not supported.
1 1 1 The Trim function of the DATA SET MANAGEMENT command (see 7.10.3.2) is supported with deterministic read after trim behavior with words set to zero.
1 1 0 The Trim function of the DATA SET MANAGEMENT command (see 7.10.3.2) is supported with deterministic read after trim behavior with words set to any value.
1 0 Reserved The Trim function of the DATA SET MANAGEMENT command (see 7.10.3.2) is supported with indeterminate read after trim behavior.

これらを見るに、やはり先ほどの確認方法でよさそう。
なお、Windows で確認する場合、TxBENCH のドライブ情報で確認すればわかりやすい。

■その他参考にした情報
The Linux Kernel Archives
Linux kernel source tree
■元麻布春男の週刊PCホットライン■:SSDの現状とチャンス
■元麻布春男の週刊PCホットライン■:SSDに関するWindows 7の3つの特徴
Wikipedia: Trim (computing)
忘却の彼方:Trimコマンドの送信を個人でチェックする方法
忘却の彼方:Deterministic Zeroing TRIMについて

カテゴリー: めも パーマリンク

3 Responses to Linux Server に SSD を Software RAID (mdraid) で入れるときの確認ポイント

  1. ピンバック: 20181010 くもり | まこぴかっと

  2. ピンバック: 20200831 くもり | まこぴかっと

  3. ピンバック: Hyper-V のホストサーバ上に All Flash でインライン重複排除ができるストレージサーバを作る | まこぴかっと

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です