17.5. ログ先行書き込み(WAL)

WALの調整についての詳細は項27.3も参照してください。

17.5.1. 設定

fsyncboolean

このパラメータがオンであれば、PostgreSQLサーバはfsync()システム・コールを発行したり、もしくは同等の方法で(wal_sync_methodを参照)更新が物理的にディスクに書き込まれたかの確証を得ようと試みます。これはオペレーティングシステムもしくはハードウェアがクラッシュした後、確実にデータベースクラスタを一貫した状態に復旧させることができます。

とは言っても、fsyncの使用は性能を悪化させます。トランザクションがコミットされると、PostgreSQLは、オペレーティングシステムがログ先行書き込みをディスクに吐き出すまで待機しなければなりません。fsyncを無効にすると、オペレーティングシステムは、書き込みの緩衝化(バッファリング)、順序付け、そして遅延に関して最善の行動を取ることができます。これは大幅に性能を向上させます。とは言っても、システムがクラッシュすれば、最後のいくつかのコミットされたトランザクションは、一部もしくは完全に失われる可能性があります。最悪の場合、修復不可能なデータの破壊が発生します。(データベースソフトウェアそのもののクラッシュは、ここでは危険要因では ありません。オペレーティングシステムレベルのクラッシュが破壊の危険性を引き起こします。)

この危険性のため、fsyncに対する普遍的に正しい設定は存在しません。常にfsyncを無効にする管理者がいる一方、何か不都合が発生した場合に明確な再起動ポイントが存在する様な時は、初期の大量読み込みの際にのみ無効にする管理者もいます。さらに常にfsyncを有効にする管理者もいます。デフォルトは、最大限の信頼性の確保のため、fsyncを有効にしてあります。もし使用しているオペレーティングシステム、ハードウェア、電力会社(もしくはバッテリーバックアップ)を信頼するのであれば、fsyncを無効にすることを検討しても良いでしょう。

このパラメータはpostgresql.confファイル内、または、サーバのコマンドラインでのみ設定可能です。 このパラメータを無効にする場合、full_page_writesも同時に無効にすることを検討してください。

wal_sync_methodstring

WALの更新をディスクへ強制するのに使用される方法です。fsyncがオフの場合この設定は役に立ちません。と言うのは更新が全く強制されないからです。取り得る値は以下のものです。

  • open_datasyncopen() option O_DSYNCでWALファイルの書き込み)

  • fdatasync (コミット毎にfdatasync()を呼び出し)

  • fsync_writethrough (いかなるディスク書き込みキャッシュもライトスルーさせるため、コミット毎にfsync()を呼び出し)

  • fsync (コミット毎にfsync()を呼び出し)

  • open_syncopen() option O_SYNCでWALファイルの書き込み)

全てのプラットホームでこれら全ての選択肢が使えるわけではありません。 デフォルトは、上のリストでプラットフォームでサポートされるものの中で先頭にあるものです。 また、open_*オプションは可能ならばO_DIRECTを使用します。 このパラメータはpostgresql.confファイル内、または、サーバのコマンドラインでのみ設定可能です。

full_page_writesboolean

このパラメータが有効の場合、PostgreSQLサーバはディスクページの全ての内容を、チェックポイントの後、そのページの最初の変更過程でWALに書き込みます。 オペレーティングシステムがクラッシュした時に進行中のページ書き込みは途中までしか終わっていない可能性があるため、これが必要です。 この場合、ディスク上のページは古いデータと新しいデータが混在する状態になります。 通常WAL内に保存される行レベルの変更データは、クラッシュ後のリカバリ時にこうしたページを復旧させるには不十分です。 完全なページイメージが、ページを正確に復旧できることを保証します。 しかし、WALに書き込まなければならないデータ量が増加します。 (WAL再生は常にチェックポイントから始まるため、チェックポイント後の最初の変更時にこれを行うことが十分です。 従って、完全ページ書き出しのコストを低減する方法の1つは、チェックポイント間隔パラメータを増やすことです。)

このパラメータを無効にすると、通常の操作速度が上がります。 しかし、オペレーティングシステムのクラッシュや電源障害の後のデータベース破損をもたらすかもしれません。 このリスクは小さいながらfsyncを無効にした場合と似ています。 (バッテリバックアップコントローラなどの)ハードウェアや許容できるほど低レベルまで部分書き込みの危険性を低減できるファイルシステムソフトウェア(ReiserFS 4など)があれば、このパラメータを無効にしても安全かもしれません。

このパラメータを無効にしてもポイントインタイムリカバリ(PITR)用のWALアーカイブの使用に影響ありません( 項23.3を参照してください)。

このパラメータはpostgresql.confファイル内、または、サーバのコマンドラインでのみ設定可能です。 デフォルトはonです。

wal_buffersinteger

WALデータ用に共有メモリ内で使用されるメモリ量です。 デフォルトは64キロバイト(64kB)です。 データはそれぞれのトランザクションコミット時にディスクに書き出されるため、設定としては、1つの典型的なトランザクションによって生成されるWALデータを保存できる充分な大きさであることのみが必要です。 このパラメータはサーバ起動時のみ設定可能です。

このパラメータを増加させると、使用しているオペレーティングシステムのデフォルト構成が許容するSystem V共有メモリの限界を越えた要求をPostgreSQLが行う原因となることがあります。必要であれば、どの様にしてこのパラメータを調整するかについて項16.4.1を参照ください。

commit_delayinteger

コミットレコードをWALバッファに書き込む時と、バッファをディスクに吐き出す時のミリ秒単位の時間差遅延です。システム負荷が高く、指定期間内にコミット準備ができたトランザクションが複数存在した場合、ゼロ以外の遅延時間であれば複数のトランザクションを一度のfsync()システムコールのみで、与えられた周期以内でコミットすることができます。しかし、もし他のトランザクションがコミットできる状態にならなければ、この遅延は無駄になります。と言うことは、サーバプロセスがそのコミットレコードを書き込んだ瞬間に他のトランザクションが進行している commit_siblingsにだけ少なくとも実行されます。デフォルトの値はゼロ(遅延無し)です。

commit_siblingsinteger

commit_delay遅延を実行する前に必要とされる同時に開いているトランザクションの最小数です。 より大きい値は、遅延周期の間に、少なくとも1つの他のトランザクションがコミットの準備を整わせることを確実にします。 デフォルトは5トランザクションです。

17.5.2. Checkpoints

checkpoint_segmentsinteger

自動的WALチェックポイント間の最大間隔をログファイルセグメント(それぞれのセグメントは通常16メガバイト)で指定します。 デフォルトは3セグメントです。 このパラメータはpostgresql.confファイル内、または、サーバのコマンドラインでのみ設定可能です。

checkpoint_timeoutinteger

自動的WALチェックポイント間の最大間隔を秒単位で指定します。 デフォルトは5分(5min)です。 このパラメータはpostgresql.confファイル、または、サーバのコマンドラインでのみ設定可能です。

checkpoint_warninginteger

チェックポイントセグメントファイルが溢れることが原因で起きるチェックポイントが、ここで指定した秒数よりも頻繁に発生する場合、サーバログにメッセージを書き出します (これは、checkpoint_segmentsを呼び出す必要があることを示唆しています)。 デフォルトは30秒(30s)です。 零の場合は警告を出しません。 このパラメータはpostgresql.confファイル、または、サーバのコマンドラインでのみ設定可能です。

17.5.3. 格納

archive_commandstring

一連のWALファイルの完了したセグメントの格納を実行するシェルコマンドです。 もしこの文字列が空であれば(デフォルトです)、WALアーカイブ処理は無効です。 文字列内のいかなる%pは、格納されるファイルの絶対パスで置き換えられ、そして、%fはファイル名のみ置換します。 (このパス名はサーバの作業用ディレクトリ、つまり、クラスタのデータディレクトリからの相対パスです。) コマンド内で実際の%文字を埋め込むには%%を使用します。 より詳しくは項23.3.1を参照ください。 このパラメータはpostgresql.confファイル、または、サーバのコマンドラインでのみ設定可能です。

成功した場合に限って、またその時に限って、ゼロで抜ける状態を返す様にすることがこのコマンドでは重要です。以下に例を示します。

archive_command = 'cp "%p" /mnt/server/archivedir/"%f"'
archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Windows

archive_timeout (integer)

archive_commandは完了したWALセグメントに対してのみ呼び出されます。 サーバが少ししかWAL流量がない(処理を行わないなぎの期間がある)場合、トランザクションの完了とアーカイブ格納領域への安全な記録との間に長期にわたる遅延があることになります。 古い未アーカイブのデータをどうするかについて制限を付けるために、archive_timeoutを設定して、強制的にサーバを新しいWALセグメントに定期的に切り替えるようにすることができます。 このパラメータが0より大きければ、サーバは前回のセグメントファイル切り替えから指定秒数経過した場合に新しいセグメントファイルに切り替えます。 強制切り替えにより早期に閉ざされたアーカイブ済みファイルは完全に完了したファイルと同じ大きさを持つことに注意してください。 そのため、非常に小さなarchive_timeoutを使用することはお勧めしません。 格納領域を膨張させてしまいます。 通常ならば分単位のarchive_timeout設定が合理的です。 このパラメータは postgresql.confファイル内、または、サーバのコマンドラインでのみで設定可能です。