Firebird 2.1以降のスペース割り当て
Vlad Khorsun、2010年10月20日
当初から、Firebirdにはデータベースファイルのディスク容量を割り当てる方法に関するルールがありませんでした。単に「慎重な書き込み」戦略に対応するために、ページ間の依存関係により、新しく割り当てられたページを決まった順序で書き込むのではなく、不定の順序で書き込んでいました。
このアプローチは非常にシンプルですが、いくつかの欠点があります:
• 書き込みの順序が決まっていないため、新しいページを割り当てる必要があるときに、ページキャッシュに多数のダーティページが含まれている状況が発生する可能性がありますが、ディスク容量不足のため書き込めないことがあります。このような場合、管理者がディスク容量を確保する前にデータベースをシャットダウンすることを好むため、他のすべてのダーティページが失われることがよくあります。これにより深刻な破損が発生します。
• 比較的小さなチャンクでディスク容量を割り当てると、ファイルシステムレベルでファイルの断片化が大幅に発生し、大規模なスキャン(たとえばバックアップ中)のパフォーマンスが低下する可能性があります。
新しいODS 11.1を使用して、Firebirdはディスク容量不足の状況での破損を回避し、ファイルシステムに断片化を回避する機会を与えるために、ディスク容量割り当てアルゴリズムを変更します。これらの変更について以下で説明します。
a) 新しく割り当てられたすべてのページは、エンジンに戻る前にすぐにディスクに書き込まれます。ページを書き込めない場合、割り当ては行われず、PIPビットはクリアされず、適切なIOエラーが発生します。このエラーは破損につながることはありません。キャッシュ内のすべてのダーティページにディスク容量が割り当てられており、安全に書き込めることが保証されているためです。
この変更により、以前の動作と比較して、新しく割り当てられたページごとに追加の書き込みが1回発生します。したがって、データベースファイルの成長中にパフォーマンスの低下が予想されます。この低下を軽減するために、Firebirdは新しく割り当てられたページの書き込みを一度に最大128KBにグループ化し、PIPヘッダーで「初期化済み」ページの数を追跡します。
注:新しく割り当てられたページがディスクに2回書き込まれるのは、そのページが初めて割り当てられた場合のみです。つまり、ページが割り当てられ、解放され、再度割り当てられた場合、2回目の割り当てでは2回書き込まれることはありません。
b) ファイルの断片化を回避するために、Firebirdは適切なファイルシステムのAPIを使用して、比較的大きなチャンクでディスク容量を事前割り当てします。現在、このようなAPIはWindowsにのみ存在しますが、最近Linux APIに追加され、将来的にはext2などの一般的なファイルシステムで実装される可能性があります。したがって、この機能は現在FirebirdのWindowsビルドでのみ実装されており、将来的にはLinuxビルドで実装される可能性があります。
ディスク容量の事前割り当てをより適切に制御するために、Firebird.confに新しい設定が導入されました:DatabaseGrowthIncrement。これは事前割り当てチャンクサイズの上限をバイト単位で指定します。デフォルト値は128MBです。エンジンがより多くのディスク容量を必要とする場合、既に割り当てられている容量の1/16を割り当てますが、128KB以上、DatabaseGrowthIncrement値以下とします。DatabaseGrowthIncrementがゼロに設定されている場合、事前割り当ては無効になります。データベースシャドウファイル用の容量は事前割り当てされません。
また、データベースに「No reserve」オプションが設定されている場合も、事前割り当ては無効になります。
注:事前割り当てにより、ディスク容量不足の状況での破損も回避できます。このような場合、管理者がディスク容量を確保するまでデータベースが動作するのに十分な容量が事前割り当てされている可能性が高くなります。
著者:Vlad Khorsun、