SSDに対するBlock Discard/TRIMをSystemTapで可視化する
パソコンを買いました。
- CPU:Intel Core i5-2400S
- Motherboard:ASUS P8H67-M EVO
- Memory:Patriot PSD38G1333KH 4GB×2 2個
- SSD:Intel X25-M G2 120GB
- HDD:HGST Deskstar 5K3000 2TB
- Power Supply:Owltech Xseries SS-650KM
今回はOLIOSPECさんのMicro Monster H67 Super Silentをカスタマイズして注文しました。デスクトップ機をリプレイスするのは実に9年ぶりなのですが、最近のパソコンはすごく良いですね。速くて静かで低消費電力です。本日はこのパソコンを使って、近年のLinuxにおけるSSD事情を確認していきたいと思います。
TRIMとは
近頃では定番SSDの座をすっかりCrucial RealSSD C300に奪われてしまった感のあるIntel X25-M G2ですが、4KiBアライメントが不要という使い勝手の良さ、およびWindows XPでもTRIMを利用可能というところを評価してこちらを選びました。どちらの製品も間もなくモデルチェンジを控えており、今が買いどきかと言われると少し微妙な情勢です。でも欲しかったので仕方がないです。
- RealSSD C400/C400vは2011年Q1に登場予定 - 上田新聞 blog版
- 25nm NANDを搭載したINTELのX25-M G3とX25-E 25nmの仕様 - 上田新聞 blog版
TRIMとは、OSがSSDに対し不要になった領域を通知するATA規格のコマンドです。SSDはNANDフラッシュの特性上、空き領域が少なくなると性能が劣化するという弱点があります。OS上でファイルを削除すれば空き領域は増えたように見えますが、SSDにとってはそれが「書いた」のか「消した」のかの区別がつかないため、TRIMコマンドによって実際に「消した」ことを伝える必要があります。
ただし、古いOSではTRIMがサポートされていません。TRIMを利用するには最新のOSとファイルシステムを使用する必要があります。現在のところ、以下のOSとファイルシステムの組み合わせでTRIMを利用することが可能となっています。
- Windows 7でNTFSを使用
- Windows Server 2008 R2でNTFSを使用
- Linux Kernel 2.6.33以降でext4を使用 (Fedora 13/14、Ubuntu 10.10など)
- Red Hat Enterprise Linux 6.0でext4を使用
(Linux Kernel 2.6.32だがバックポートされている。Storage Administration Guide参照)
例外的にIntel X25-M G2については、Intel SSD Toolboxを用いることでWindows XP/VistaでもTRIMを利用することができます。
LinuxにおけるTRIMの利用とモニタリング
本当はCentOS 6.0がリリースされるのを首を長くして待っていたのですが、待ちきれなかったのでとりあえずFedora 14をインストールしました。LinuxでTRIMを利用するには、ext4ファイルシステムをマウントする際にdiscardオプションを指定します。
# mount -t ext4 -o discard /dev/sda5 /mnt
Linuxでは、ブロックデバイスに不要領域を通知する機能のことをBlock Discardと呼んでいます。Block DiscardによってATAデバイスにはTRIMコマンドが、SCSIデバイスにはUNMAPというコマンドが発行されます。
さて、設定はこれだけなのですが、これで実際にTRIMが機能しているのかどうか少し心配になります。というのも、TRIMについてはログなどが何も出力されないためです。
そこで、SystemTapを用いてBlock Discardの様子をモニタリングするスクリプトを作ってみました。SystemTapについては昨年のエントリでも取り扱っていますので、そちらも是非ご覧ください。
- SystemTapでMySQLのDisk I/Oを分析する - SH2の日記
以下のスクリプトをdiscard.stpという名前で保存します。
probe kernel.function("blkdev_issue_discard").return { printf("%s, sector=%d, nr_sects=%d, return=%d (%d - %d KiB)\n", execname(), $sector, $nr_sects, $return, $sector / 2, ($sector + $nr_sects) / 2 - 1); }
stapコマンドでSystemTapを起動します。
# stap discard.stp
別のターミナルで、大きなファイルを作ってから削除してみます。
# dd if=/dev/zero of=temp.dat bs=8388608 count=128 oflag=direct 128+0 records in 128+0 records out 1073741824 bytes (1.1 GB) copied, 9.1373 s, 118 MB/s # rm temp.dat rm: remove 通常ファイル `temp.dat'? y
すると、数秒経ってから以下のようなログが出力されました。
jbd2/sda5-8, sector=5767168, nr_sects=16392, return=0 (2883584 - 2891779 KiB) jbd2/sda5-8, sector=4718592, nr_sects=262144, return=0 (2359296 - 2490367 KiB) jbd2/sda5-8, sector=4980736, nr_sects=262144, return=0 (2490368 - 2621439 KiB) jbd2/sda5-8, sector=5242880, nr_sects=262144, return=0 (2621440 - 2752511 KiB) jbd2/sda5-8, sector=5505024, nr_sects=262144, return=0 (2752512 - 2883583 KiB) jbd2/sda5-8, sector=6029312, nr_sects=262144, return=0 (3014656 - 3145727 KiB) jbd2/sda5-8, sector=5799936, nr_sects=229376, return=0 (2899968 - 3014655 KiB) jbd2/sda5-8, sector=6291456, nr_sects=262144, return=0 (3145728 - 3276799 KiB) jbd2/sda5-8, sector=6815744, nr_sects=32768, return=0 (3407872 - 3424255 KiB) jbd2/sda5-8, sector=6569984, nr_sects=245760, return=0 (3284992 - 3407871 KiB)
左から、プロセス名、TRIM開始セクタ、セクタ数、戻り値、括弧内はTRIM対象範囲をKiB単位に換算した値です。jbd2というのはファイルシステムにジャーナリング機能を付加するJournaling Block Deviceモジュールのext4対応版です。見ると、確かに合計1GiBの領域がTRIMされていることや、一度にTRIMされる領域が最大128MiBであることなどが分かります。
また、Fedora 14ではファイルシステム構築時にもTRIMが発行されます。
# mkfs -t ext4 /dev/sda5 mke2fs 1.41.12 (17-May-2010) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 524288 inodes, 2097152 blocks 104857 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=2147483648 64 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632 Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 25 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
このときSystemTapの出力は以下のようになり、一度にデバイスの全領域をTRIMしていることが見てとれます。
mkfs.ext4, sector=0, nr_sects=16777216, return=0 (0 - 8388607 KiB)
一方、HDDなどTRIMに対応していないデバイスでは、戻り値として-95が返されます。これはEOPNOTSUPP、「Operation not supported on transport endpoint」というエラーを表しています。
jbd2/sdb5-8, sector=1312776, nr_sects=8, return=-95 (656388 - 656391 KiB) jbd2/sdb5-8, sector=270336, nr_sects=245760, return=-95 (135168 - 258047 KiB) jbd2/sdb5-8, sector=524288, nr_sects=262144, return=-95 (262144 - 393215 KiB) jbd2/sdb5-8, sector=1048576, nr_sects=262144, return=-95 (524288 - 655359 KiB) jbd2/sdb5-8, sector=802816, nr_sects=245760, return=-95 (401408 - 524287 KiB) jbd2/sdb5-8, sector=1572864, nr_sects=262144, return=-95 (786432 - 917503 KiB) jbd2/sdb5-8, sector=1327104, nr_sects=245760, return=-95 (663552 - 786431 KiB) jbd2/sdb5-8, sector=2097152, nr_sects=262144, return=-95 (1048576 - 1179647 KiB) jbd2/sdb5-8, sector=1851392, nr_sects=245760, return=-95 (925696 - 1048575 KiB) jbd2/sdb5-8, sector=2375680, nr_sects=65536, return=-95 (1187840 - 1220607 KiB)