xfs_fsrを使ってXFSファイルシステムをベストの状態で使用する

 XFSファイルシステムは大規模なファイルの保存/アクセスについての性能が高いことで知られている。XFSの設計はエクステントベースで、ファイルの内容は一つ以上のエクステントと呼ばれる連続的な領域内に保存されている。XFSファイルシステム内のファイルは、ユーザの使い方によってはフラグメント化することがあるが、xfs_fsrユーティリティを使ってそのようなファイルをデフラグすることでファイルアクセスについてのシステムの性能を向上させることができる。

 ファイルをXFSファイルシステム上にコピーすると、通常は一つのエクステント内にファイルの全内容が保存される。しかしその後ファイルを延長したり新たなデータで内容を書き換えたりしようとする際には、ファイルの直後に続く領域が利用できないこともある。その場合、ファイルはディスク上の別々の場所にある2つのエクステントに分かれて保存されることになる。当然ながらファイルにアクセスするアプリケーションはこのことを考慮する必要はなく、ファイルの最初から最後までについて、線形に連続した領域の場合と同様に内容を普通に読み取ったり、lseek(2)でファイル内を移動したりすることができる。しかしファイルの内容がディスク上の多数のエクステントに分散して保存されていると、性能的には劣る。

 xfs_bmapユーティリティを使えば、XFSファイルシステム上に保存されている特定のファイルのエクステントについて知ることができる。-vオプション(詳細モード)を付けて実行すれば、ファイルの各部分がファイルシステム内のどのブロックにマッピングされているかが分かる。以下に示したファイルの場合、運悪く300MBのtarファイルが2つのエクステントに分割されてしまっている。

# xfs_bmap -v sarubackup-june2008.tar.bz2
sarubackup-june2008.tar.bz2:
 EXT: FILE-OFFSET       BLOCK-RANGE          AG AG-OFFSET           TOTAL
   0: [0..350175]:      264463064..264813239 10 (2319064..2669239) 350176
   1: [350176..615327]: 265280272..265545423 10 (3136272..3401423) 265152

 一方xfs_dbユーティリティを使えば、ファイルシステム全体のフラグメント化の状態を見ることができる。その際-rオプションを使えば、読み取りのみが可能なモードで操作が行われるので、マウント済みの使用中のファイルシステム上でも使用することができる。とは言えファイルシステムを実際に変更するつもりがない場合にはいずれにしろ-rを付けておいた方がおそらく良いだろう。xfs_dbのfragコマンドを実行すると、ディスクが数秒間動いた後、ファイルシステムのフラグメント化の状態を以下のように表示する。

# xfs_db -r /dev/mapper/raid2008-largepartition2008
xfs_db> frag
actual 117578, ideal 116929, fragmentation factor 0.55%

 xfs_fsr(1) プログラムは、Fedora 9やDebianベースのディストリビューションではxfsdumpパッケージの中に含まれている。これは残念なことだ。というのもxfs_fsrは非常に便利なツールなのにも関わらず、xfsdumpの中に含まれていることで、mkfs.xfsと一緒にxfsprogsパッケージに入っている場合と比べてインストール/使用される機会が大きく減ってしまっているためだ。xfs_fsrはXFSファイルシステムのデフラグプログラムで、マウント中のXFSファイルシステムをデフラグするためにcronジョブとして定期的に実行するのに向いている。

 xfs_fsrの使い方は2通りある。制限時間を指定して実行すると、システム上のすべてのXFSファイルシステムを対象として、各ファイルシステム上でもっとも激しくフラグメント化されているファイルのいくつかを最適化する。あるいは、特定のXFSファイルシステムやXFSファイルシステム上の特定のファイルを明示的に指定して実行することもできる。xfs_fsrに制限時間を指定して実行した場合、その制限時間の終了時には実行した内容についての情報が/var/tmp内のファイルに保存されるため、次回再び制限時間を指定して実行した際には、作業は同じ場所から続行される。そのためcronジョブとして実行して、マシンをあまり使用していない時間に毎日少しずつ最適化を行うようにすることも可能だ。

 xfs_fsrはファイルを最適化する際、フラグメント化している既存のファイルのコピーを元のファイルよりも少ない数のエクステント(フラグメント)を使用して新たに作成する。そしてファイル内容が新しいファイルにコピーされた後、新しいファイルが古いファイルと置き換わるようにファイルシステムのメタデータが更新される。これは言い換えれば、デフラグしたいファイルをまるまるもう一つ保存するために十分な空き領域がファイルシステム上に存在していなければならないということだ。なお空き領域が必要であるということはディスクのクォータにも当てはまり、ファイルのコピーをまるまる保存しようとするとそのファイルの所有者であるユーザのディスククォータを越えてしまう場合にはデフラグすることはできない。

 制限時間を指定して実行するとxfs_fsrはデフォルトではシステム上のすべてのXFSファイルシステムを対象にするのだが、その際、(実際に問題になる可能性は非常に低いものの)いくつかの問題が起こる可能性がある。例えばLILOのようにディスク上の固定位置に設定ファイルがあることを前提としているブートローダを使用している場合、xfs_fsrでデフラグしたためにそのファイルが移動してしまって、その仕組みが機能しなくなる恐れがある。そのような場合には、xfs_ioコマンドを使って特定のファイルやディレクトリに対してno-defragという特別なフラグを付けることで、xfs_fsrがそのようなファイルをデフラグしてしまうのを回避することができる。なおno-defragをディレクトリに指定した場合には、no-defragが指定されたディレクトリ内のファイルやディレクトリについてはno-defragフラグが継承される。xfs_fsrのマニュアルページに、no-defragフラグについてのより詳しい情報や設定方法がある。

 使用中のXFSファイルシステム上で、ファイルを明示的に指定して実行した例を示すために、上記のxfs_bmapの実行例で2つのエクステントに分割されていたsarubackup-june2008.tar.bz2ファイルに対してxfs_fsrを実行した結果を以下に示す。xfs_fsrの実行後には、ファイルを保存するために1つのエクステントしか使用していないことが分かる。

# xfs_bmap -v sarubackup-june2008.tar.bz2
sarubackup-june2008.tar.bz2:
 EXT: FILE-OFFSET       BLOCK-RANGE          AG AG-OFFSET           TOTAL
   0: [0..350175]:      264463064..264813239 10 (2319064..2669239) 350176
   1: [350176..615327]: 265280272..265545423 10 (3136272..3401423) 265152

# md5sum  sarubackup-june2008.tar.bz2
123b9db92b31bea5f60835920dee88d5

# xfs_fsr  sarubackup-june2008.tar.bz2

(RAID上にある300MBのファイルのため、ここで数秒かかった。)

# xfs_bmap -v sarubackup-june2008.tar.bz2
sarubackup-june2008.tar.bz2:
 EXT: FILE-OFFSET      BLOCK-RANGE          AG AG-OFFSET           TOTAL
   0: [0..615327]:     267173832..267789159 10 (5029832..5645159) 615328

# md5sum  sarubackup-june2008.tar.bz2
123b9db92b31bea5f60835920dee88d5
ext3_fsrツールがない理由
 XFSとは異なりext3ファイルシステムでは、ファイル内容の保存場所の管理にエクステントではなく間接ブロックが使用されている。なお次期ext4ファイルシステムはファイル内容の保存にエクステントを使用していて、xfs_fsrと似た形でのオンラインデフラグもサポートする予定だ。

 ext3ファイルシステムについては、filefrag(1) ユーティリティを使えばファイルのフラグメント化の状態を把握することができるが、その状態を修正することはできない。またtune2fsの-mオプションを使えば特権を持ったプロセスのみが使用することのできるブロックの割合を設定することができるので、例えば通常のユーザが使用できない領域としてディスクの10%の領域を確保しておけば、ファイルシステムが満杯になったときに起こる激しいフラグメント化を避けることができる。

 xfs_fsrをcronジョブとして定期的に実行するには、単に引数なしで実行すれば良いだけだ。なお定期的にメールを受け取りたくなければ出力結果をnullデバイスにリダイレクトしておくと良いだろう。唯一利用すると良いかもしれないオプションとしては-tがあって、xfs_fsrを実行する時間を秒単位で指定することができる。デフォルトは7200(2時間)になっているが、デスクトップマシンの場合には以下のように6時間に設定しておいて毎晩寝る時間に起動するようにしておくと良いかもしれない。

# cd /root
# mkdir -p mycron
# cd mycron
# vi xfs-fsr.cron
30 0  * * *  /root/mycron/xfs-fsr.sh
# vi xfs-fsr.sh
/usr/sbin/xfs_fsr -t 21600 >/dev/null 2>&1
# cat *.cron >|newtab
# crontab newtab

 Linuxディストリビューションでは、xfs_fsrユーティリティはmkfs.xfsと同じくらいに気付きやすいように(例えば、同じxfsprogsパッケージに含めて)インストールされるのではなく、ファイルシステムのダンプ/リストアツール群の中にしまい込まれてしまっている。これはとても残念だ。XFSファイルシステムを数年間使用しているのにも関わらずxfs_fsrユーティリティの存在を知らなかったなら、xfs_fsrをシステム上で数回実行することでファイルシステムの性能を向上させることができるだろう。

Ben Martinは10年以上もファイルシステムに携わっている。博士号を取得し、libferris、ファイルシステム、検索ソリューションを中心としたコンサルティングサービスを提供している。

Linux.com 原文