ファイルの最適化

ファイルがディスクに書き込まれると、ファイルを連続するクラスターに書き込むことができない場合があります。 連続しないクラスターでは、ファイルの読み取りと書き込みのプロセスが遅くなります。 ディスク上で連続しないクラスターが離れるほど、ハード ディスク ドライブの読み取り/書き込みヘッドの移動にかかる時間が長いため、問題は悪化します。 連続しないクラスターを含むファイルが 断片化されています。 高速アクセスのためにファイルを最適化するために、ボリュームを最適化できます。

最適化 とは、ディスク上のファイルの一部を移動してファイルを最適化するプロセス、つまりディスク上のファイル クラスターを移動して連続させるプロセスです。 詳細については、以下のセクションを参照してください。

ファイルの最適化

単純な単一タスク オペレーティング システムでは、最適化ソフトウェアだけがタスクであり、ディスクの読み取りまたはディスクへの書き込みを行う他のプロセスはありません。 ただし、マルチタスク オペレーティング システムでは、ハード ディスク ドライブの読み取りと書き込みを行うプロセスもあれば、そのハード ディスク ドライブを最適化するプロセスもあります。 トリックは、非常に長い間書き込みプロセスを停止せずに最適化されているファイルへの書き込みを避けるためです。 この問題を解決することは簡単ではありませんが、可能です。

ファイル システムのディスク構造に関する詳細な知識を必要とせずに最適化を可能にするために、3 つの制御コードのセットが提供されます。 コントロール コードには、次の機能があります。

  • アプリケーションで空のクラスターを検索できるようにする
  • ファイル クラスターのディスクの場所を決定する
  • ディスク上のクラスターの移動

また、制御コードは、移動中に他のプロセスがファイルの読み取りと書き込みを禁止し、許可する問題も透過的に処理します。

これらの操作は、他のプロセスの実行を禁止することなく実行できます。 ただし、ディスク ドライブの最適化中は、他のプロセスの応答時間が遅くなります。

ファイルを最適化するには

  1. FSCTL_GET_VOLUME_BITMAPコントロール コードを使用して、ファイル全体を受け入れるのに十分な大きさのボリューム上の場所を見つけます。

    注意

    必要に応じて、他のファイルを移動して、十分な大きさの場所を作成します。 理想的には、ファイルの最初のエクステントの後に十分な未割り当てクラスターがあり、その後のエクステントを最初のエクステントの後のスペースに移動できます。

     

  2. FSCTL_GET_RETRIEVAL_POINTERSコントロール コードを使用して、ディスク上のファイルの現在のレイアウトのマップを取得します。

  3. FSCTL_GET_RETRIEVAL_POINTERSによって返される RETRIEVAL_POINTERS_BUFFER 構造体をウォーク します

  4. FSCTL_MOVE_FILE制御コードを使用して、構造を歩く際に各クラスターを移動します。

    注意

    他のプロセスがディスクに書き込む際に、ビットマップまたは取得構造、またはその両方をさまざまな時点で更新する必要がある場合があります。

     

最適化プロセスで使用される 2 つの操作には、ボリュームへのハンドルが必要です。 管理者のみがボリュームのハンドルを取得できるため、管理者のみがボリュームを最適化できます。 アプリケーションは、最適化ソフトウェアの実行を試みるユーザーの権限を確認する必要があり、ユーザーが適切な権限を持っていない場合は、ユーザーがボリュームを最適化できないようにする必要があります。

FAT または FAT32 ファイル システム ボリュームの最適化中に CreateFile を使用してディレクトリを開く場合は、 GENERIC_READ アクセス マスク値を指定します。 MAXIMUM_ALLOWED アクセス マスク値は指定しないでください。 ディレクトリへのアクセスが行われた場合、アクセスは拒否されます。

クラスターの丸められたファイル サイズを超えて拡張される NTFS ファイル システムで割り当てられたクラスターを移動しないでください。結果はエラーであるためです。

NTFS ファイル システム ボリューム内のポイント、ビットマップ、属性リストを再解析し、最適化し、読み取りと同期のために開き、 file:name:type 構文を使用して名前を付けることができます。たとえば、 dirname:$i 30:$INDEX_ALLOCATION、 mrp::$DATA、 mrp::$REPARSE_POINT、 mrp::$ATTRIBUTE_LIST などです。

NTFS ファイル システム ボリュームを最適化する場合は、ファイルの割り当てサイズを超えて仮想クラスターを最適化できます。

最適化コピーとシャドウ コピー間の相互作用を最小限に抑える

可能な場合は、16 キロバイト (KB) 単位で互いに相対的に揃えたブロック内のデータを移動します。 これにより、シャドウ コピーが有効になっている場合の書き込み時のコピー オーバーヘッドが軽減されます。これは、シャドウ コピー領域が増加し、次の条件が発生するとパフォーマンスが低下するためです。

  • 移動要求のブロック サイズが 16 KB 以下です。
  • 移動デルタは 16 KB 単位ではありません。

移動デルタは、ソース ブロックの開始からターゲット ブロックの開始までのバイト数です。 つまり、オフセット X (ディスク上) から始まるブロックは、X から Y の絶対値が 16 KB の偶数倍の場合、開始オフセット Y に移動できます。 そのため、4 KB クラスターを想定すると、クラスター 3 からクラスター 27 への移動は最適化されますが、クラスター 18 からクラスター 24 への移動は最適化されません。 mod(3,4) = 3 = mod(27,4) であることに注意してください。 4 KB の 4 つのクラスターがそれぞれ 16 KB に相当するため、Mod 4 が選択されます。 そのため、16 KB のクラスター サイズにフォーマットされたボリュームでは、すべての移動ファイルが最適化されます。

シャドウ コピーの詳細については、「 ボリューム シャドウ コピー サービス」を参照してください。

最適化のためにサポートされているファイル、ストリーム、およびストリームの種類

ほとんどのファイルは FSCTL_MOVE_FILE コントロール コードを使用して移動できますが、すべて移動できるわけではありません。 FSCTL_MOVE_FILEでサポートされているファイル、ストリーム、ストリームの種類 (属性型コードとも呼ばれます) の一覧を次 示します。 その他のファイル、ストリーム、ストリームの種類は、 FSCTL_MOVE_FILEではサポートされていません。

任意のファイルまたはディレクトリでサポートされるストリームの種類。

  • ::$DATA
  • ::$ATTRIBUTE_LIST
  • ::$REPARSE_POINT
  • ::$EA
  • ::$LOGGED_UTILITY_STREAM

**Windows 7、Windows Server 2008 R2、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: **::$EA および ::$LOGGED_UTILITY_STREAM は、Windows 8前にサポートされていません。Windows Server 2012

任意のディレクトリでサポートされるストリームの種類。

  • ::$BITMAP
  • ::$INDEX_ALLOCATION

"filename:streamname:$typename" 形式でFSCTL_MOVE_FILEでサポートされるシステム ファイル、ストリーム、およびストリームの種類を次に示します。

  • $MFT::$DATA
  • $MFT::$ATTRIBUTE_LIST
  • $MFT::$BITMAP
  • $AttrDef::$DATA
  • $AttrDef::$ATTRIBUTE_LIST
  • $Secure:$SDS:$DATA
  • $Secure::$ATTRIBUTE_LIST
  • $Secure:$SDH:$INDEX_ALLOCATION
  • $Secure:$SDH:$BITMAP
  • $Secure:$SII:$INDEX_ALLOCATION
  • $Secure:$SII:$BITMAP
  • $UpCase::$DATA
  • $UpCase::$ATTRIBUTE_LIST
  • $Extend:$I 30:$INDEX_ALLOCATION
  • $Extend::$ATTRIBUTE_LIST
  • $Extend:$I 30:$BITMAP
  • $Extend\$UsnJrnl:$J:$DATA
  • $Extend\$UsnJrnl::$ATTRIBUTE_LIST
  • $Extend\$UsnJrnl:$Max:$DATA
  • $Extend\$Quota:$Q:$INDEX_ALLOCATION
  • $Extend\$Quota::$ATTRIBUTE_LIST
  • $Extend\$Quota:$Q:$BITMAP
  • $Extend\$Quota:$O:$INDEX_ALLOCATION
  • $Extend\$Quota:$O:$BITMAP
  • $Extend\$ObjId:$O:$INDEX_ALLOCATION
  • $Extend\$ObjId::$ATTRIBUTE_LIST
  • $Extend\$ObjId:$O:$BITMAP
  • $Extend\$Reparse:$R:$INDEX_ALLOCATION
  • $Extend\$Reparse::$ATTRIBUTE_LIST
  • $Extend\$Reparse:$R:$BITMAP
  • $Extend\$RmMetadata:$I 30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata:$I 30:$BITMAP
  • $Extend\$RmMetadata::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Repair:$DATA
  • $Extend\$RmMetadata\$Repair::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Repair:$Config:$DATA
  • $Extend\$RmMetadata\$Txf:$I 30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata\$Txf::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$Txf:$I 30:$BITMAP
  • $Extend\$RmMetadata\$Txf:$TXF_DATA:$LOGGED_UTILITY_STREAM
  • $Extend\$RmMetadata\$TxfLog:$I 30:$INDEX_ALLOCATION
  • $Extend\$RmMetadata\$TxfLog::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$TxfLog:$I 30:$BITMAP
  • $Extend\$RmMetadata\$TxfLog\$Tops:$DATA
  • $Extend\$RmMetadata\$TxfLog\$Tops::$ATTRIBUTE_LIST
  • $Extend\$RmMetadata\$TxfLog\$Tops:$T:$DATA
  • $Extend\$RmMetadata\$TxfLog\$TxfLog.blf::$DATA
  • $Extend\$RmMetadata\$TxfLog\$TxfLog.blf::$ATTRIBUTE_LIST