9.3. WALの設定

データベースの性能に影響するようなWALに関連したパラ メータがあります。この節では、その使い方を説明します。 設定方法の詳細についてはSection 3.4を御覧下さい。

WALには2つの共通関数があります。 LogInsertLogFlushです。 LogInsertは共有メモリ上の WALバッファに新しいレコードを挿入します。新しい レコードを挿入する余地がないときは、LogInsert は、満杯になったWALを書き込み(カーネルキャッシュ に移動)しなければなりません。これは望ましいことではありません。なぜ なら、データベースへの低レベルの変更(たとえばタプルの挿入)のたびに LogInsertが呼ばれ、そのような時には変更を受け たページに対して排他ロックがかっており、それ故このような操作は可能 な限り高速に実行されると想定されているからです。さらに悪いことには、 WALに必要な新しいログセグメントも必要となるかも 知れません。この場合、更に時間がかかります。通常、 WAL の書き込み、吐出しは LogFlush要求で実施されます。これは大抵の場合、 トランザクションコミットの際に永続記憶にトランザクションレコードが 吐出されることを保証するために行われます。ログ出力が大量に行われる システムでは、LogInsertWALバッファの書込を行うことを防ぐほどには LogFlush要求が頻繁に起らないかも知れません。そ ういうシステムでは、WAL_BUFFERS変数を変更して WALバッファの数を増やしてください。デフォルトの WALの数は8です。この数を増やすと共有メモリの使用 量に影響があります。

チェックポイントは、一連のトランザクションに おいて、それ以前のすべてのデータがログされ、データファイルも更新さ れていることが保証されている時点を指します。チェックポイントでは、 すべての変更されたページがディスクに吐出され、特別なチェックポイン トレコードがログファイルに書き込まれます。その結果、クラッシュが発 生した際に、ログの中でどのレコード(これはredoレコードと呼ばれていま す)から復旧処理がREDOログ操作を開始すべきかを知ることができます。な ぜなら、redoレコード以前にデータファイルに対して行われた変更はすで にディスク上に記録済だからです。チェックポイントが実施された後、 redoレコード以前のログセグメントはすべて削除されます。そこで、チェッ クポイントを使ってWALディレクトリ以下のディスク スペースを開放することができます(WALを使った BARが実装されれば、ログセグメントを削除する代り に保存することができます)。チェックポイントでは、 LogInsertLogFlushが新し くログセグメントを作るために時間を費やすことのないように、前もって ログセグメントを作っておくこともできます。

WALログはsegmentsと呼ばれ る16MBのファイルのセットに保持されています。デフォルトではセグメン トの75%以上が使われた時にだけ新しいセグメントが作成されます。 WAL_FILES設定パラメータを調整することにより、64 個までのログセグメントを前もって作成することができます。

クラッシュ後の回復をより早くするためには、頻繁にチェックポイントを 行うことです。ただし、変更されたページを吐出すコストとの兼ね合いで ことを行う必要があります。また、チェックポイント後の最初のデータペー ジの変更によりそのページ内容全体がログされます。したがって、ログす る量が増えるので、ログファイルのサイズも大きくなってしまいます。

postmasterは次のチェックポイントを作成するために特別なバックエンド を頻繁に起動します。CHECKPOINT_SEGMENTSログセグ メント数に達するか、またはCHECKPOINT_TIMEOUT秒が 経過するか、どちらかの条件が満たされるとチェックポイントが作成され ます。デフォルトの設定では、それぞれ3セグメントと300秒となっていま す。また、SQLコマンドのCHECKPOINTで強制的にチェッ クポイントを作成することもできます。

COMMIT_DELAYパラメータにより、 LogInsertがコミットレコードを書き込んでから LogFlushが行われるまでの間にバックエンドが何マ イクロ秒sleepするかが決まります。この遅延があることにより、ほかのバッ クエンドがコミットレコードをログに書き込んだあと、それらすべてのロ グレコードを一度のfsyncで吐出すことができます。もし COMMIT_SIBLINGSよりも少ない数のバックエンドしか 現在アクティブなトランザクションに存在しない場合は、sleepしません。 このことにより、すぐにコミットしそうなバックエンドがいないときでも sleepするのを防ぐことができます。大抵のプラットフォームでは、sleep の最小単位はミリ秒です。ですから、0でない1から10000マイクロ秒までの どんなCOMMIT_DELAYの設定も効果は同じことになるで しょう。

WAL_SYNC_METHODパラメータはPostgresがカーネルに対 してWAL更新のディスクへの書き込みを依頼する方法を決定します。どうい う設定でも信頼性は同じはずですが、プラットフォームによってどれが一 番早いかは全然違います。ちなみに、このパラメータは FSYNCが無効になっている場合は無関係です。

WAL_DEBUGを0以外のどんな値にしても、 LogInsertLogFlushWALにおける呼び出しが標準エラー出力に出力される ようになります。いまのところ、値による違いはありません。将来はもっ と汎用的な方法に置き換えられるかもしれません。