無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

29.4. WAL の設定

データベースの性能に影響するような WAL に関連した設定パラメータが複数あります。 本節では、その使い方を説明します。 サーバ設定パラメータの設定方法についての詳細は 第18章 を参照してください。

チェックポイント は、一連のトランザクションにおいて、そのチェックポイント以前に書かれた全ての情報によりヒープとインデックスファイルがすでに更新されていることを保証する場所です。 チェックポイントの時刻において、全てのダーティページデータはディスクにフラッシュされ、特殊なチェックポイントレコードがログファイルに書き込まれます。 (変更されたレコードは以前に WAL フラッシュされています。) クラッシュした時、クラッシュからの復旧処理は最後のチェックポイントレコードを見つけ、ログの中でどのレコード(これはredoレコードと呼ばれています)から復旧処理がREDOログ操作を開始すべきかを決定します。 このチェックポイント以前になされたデータの変更は、すでにディスク上にあることが保証されています。 従って、チェックポイント後、redoレコード内のそのチェックポイント以前のログセグメントは不要となり、再利用または削除することができます ( WAL アーカイブが行われる場合、このログセグメントは削除もしくは再利用される前に保存されなければなりません)。

チェックポイント処理は、全てのダーティデータページをディスクへ書き出すため、大きなI/O負荷を発生させます。このため、チェックポイント処理は絞り込まれます。そうするとI/Oはチェックポイント開始から次のチェックポイントが開始する以前に停止します。これは、チェックポイント処理中の性能劣化を極力抑える効果があります。

サーバのチェックポインタプロセスは自動的にチェックポイントを頻繁に実行します。 checkpoint_segments ログセグメント数に達するか、または checkpoint_timeout 秒が経過するか、どちらかの条件が満たされるとチェックポイントが開始されます。 デフォルトの設定では、それぞれ3セグメントと300秒(5分)となっています。 前回のチェックポイント以降書き出すWALがない場合、 checkpoint_timeout が経過したとしても新しいチェックポイントが飛ばされます。 WALアーカイブ処理を使用しており、かつ、データ損失の可能性を限定するためにファイルのアーカイブ頻度に対する下限を設定したい場合、このチェックポイントパラメータではなく archive_timeout パラメータを調節しなければなりません。 また、 CHECKPOINT SQLコマンドで強制的にチェックポイントを作成することもできます。

checkpoint_segments checkpoint_timeout 、またはその両者を減少させると、チェックポイントはより頻繁に行われます。 これにより、再処理に要する時間がより少なくなりますのでクラッシュ後の修復は高速になります。 しかし、より頻繁に行われるようになる、変更されたデータページの吐き出しにより増大するコストとバランスを考えなければなりません。 full_page_writes が設定されている(デフォルトです)場合、他に考慮しなければならない点があります。 データページの一貫性を保証するために、各チェックポイント後の最初に変更されるデータページは、そのページ全体の内容がログに保存されることになります。 このような場合、チェックポイントの間隔を少なくすることは、WALログへの出力を増加させ、間隔を短くする目的の一部を無意味にします。 また、確実により多くのディスクI/Oが発生します。

チェックポイントはかなり高価なものです。 1番の理由は、この処理は現時点の全てのダーティバッファを書き出す必要があること、2番目の理由は、上記のようにその後に余計なWALの書き込みが発生することです。 そのため、チェックポイント用のパラメータを高くし、チェックポイントがあまりにも頻発することがないようにすることを勧めます。 簡単なチェックポイント用のパラメータの健全性検査として、 checkpoint_warning パラメータを設定することができます。 チェックポイントの発生間隔が checkpoint_warning 秒未満の場合、 checkpoint_segments の増加を勧めるメッセージがサーバのログに出力されます。 このメッセージが稀に現れたとしても問題にはなりませんが、頻出するようであれば、チェックポイントの制御パラメータを増加させるべきです。 checkpoint_segments を十分高く設定していないと、大規模な COPY 転送などのまとまった操作でこうした警告が多く発生するかもしれません。

ページ書き出しの集中による入出力システムの溢れを防ぐために、チェックポイント期間のダーティバッファの書き出しは一定の期間に分散されます。 この期間は checkpoint_completion_target により制御され、チェックポイント間隔の割合として指定されます。 I/Oの割合は、チェックポイントの起動時から checkpoint_segments WALセグメントが消費された時、あるいは、指定した checkpoint_timeout 秒が経過した時、このどちらかが発生するとすぐに、チェックポイントが完了するように調整されます。 デフォルトの0.5という値では、 PostgreSQL は、次のチェックポイントが始まるまでのおよそ半分の時間で各チェックポイントが完了するものと想定できることになります。 通常の操作においてほぼ最大のI/Oスループットに近いようなシステムでは、チェックポイントにおけるI/O負荷を減らすために checkpoint_completion_target を増やすことを勧めます。 この欠点は、延長されたチェックポイントがリカバリ時に影響をあたえることです。 リカバリ時に使用できるように、より多くのWALセグメントを保持する必要があるためです。 checkpoint_completion_target を最大の1.0に設定することもできますが、より低く抑えること(おそらく最大で0.9)が最善です。 チェックポイントには、ダーティバッファを書き出す以外の活動も含まれているからです。 1.0という設定は、ある時点でチェックポイントが完了しなくなるという結果に陥ります。 これは必要なWALセグメント数が想定以上に変動することになり、性能の劣化が発生することになります。

WALセグメントファイルは常に少なくとも1つあり、また、通常は(2 + checkpoint_completion_target ) * checkpoint_segments + 1、もしくは checkpoint_segments + wal_keep_segments + 1より多くはありません。 各セグメントファイルは通常16メガバイト(このサイズはサーバのコンパイル時に変更可能)です。 このことから、 WAL で必要とされる領域を推定できます。 普通、古いセグメントファイルが不要になった時、それらは再利用(つまり、番号付けられるシーケンスにおいての将来のセグメントとなるように名前が変更)されます。 短時間のログ出力のピークのためにセグメントファイル数が3× checkpoint_segments + 1を超えた場合、システムは、この上限以下になるまで、不要になったセグメントファイルを再利用せずに、削除します。

アーカイブからのリカバリもしくはスタンバイモードにおいて、サーバでは定期的に通常運用でのチェックポイント処理と似た リスタートポイント 処理を行います。これは、すでに再生されたWALを再度読み込む必要がないよう、ディスクに現在の状態を強制的に書き込み、 pg_control ファイルを更新します。また pg_xlog ディレクトリの中の古いログセグメントを再利用できるようにします。 リスタートポイント処理はチェックポイントが記録された時にしか実施されないので、マスタ側のチェックポイント処理よりも発生頻度は低いでしょう。 再開始点は、最後の再開始点より少なくとも checkpoint_timeout 秒が経過しているとすれば、チェックポイントレコードが到達された時点で始動されます。 スタンバイモードにおいて、再開始点はもし最後の再開始点から最低限 checkpoint_segments ログセグメントが再生された場合に、同様始動されます。

よく使われる2つの内部用 WAL 関数があります。 XLogInsert XLogFlush です。 XLogInsert は共有メモリ上の WAL バッファに新しいレコードを挿入します。 新しいレコードを挿入する余地がない時は、 XLogInsert は、満杯になった WAL バッファを書き込み(カーネルキャッシュに移動)しなければいけません。 これは望ましいことではありません。 なぜなら、データベースへの低レベルの変更(例えば行の挿入)の度に XLogInsert が呼ばれますが、そのような場合には変更を受けたページに対して排他ロックがかかっており、それゆえこの操作は可能な限り高速に実行されなければなりません。 さらに悪いことには、 WAL バッファへの書き込みの際に、さらに時間がかかる、強制的な新しいログセグメントの生成が必要となるかもしれません。 通常、 WAL の書き込み、吐き出しは XLogFlush 要求で実施されます。 これはたいていの場合、トランザクションコミットの際に永続的な記憶領域にトランザクションレコードが吐き出されることを保証するために行われます。 ログ出力が大量に行われるシステムでは、 XLogInsert によって必要となる書き込みを防ぐほどには XLogFlush 要求が頻繁に起こらないかもしれません。 そういうシステムでは、 wal_buffers パラメータを変更して WAL バッファの数を増やしてください。 full_page_writes が設定され、かつ、システムが高負荷状態である場合、 wal_buffers を高くすることで、各チェックポイントの直後の応答時間を滑らかにすることができます。

commit_delay パラメータは、 XLogFlush 内でロックを取得してからグループコミット上位者が何マイクロ秒休止するかを定義します。一方、グループコミット追従者は上位者の後に並びます。 全てが上位者の結果として生ずる同期操作によりフラッシュされるように、この遅延は他のサーバプロセスがそれらのコミットレコードをWALバッファに追加することを許容します。 fsync が有効でないか、または commit_siblings より少ない他のセッションがその時点で活動しているトランザクションであれば休止は行われません。 ほかの何らかのセッションが直ぐにでもコミットするという起こりそうにない時の休止を避けるものです。 いくつかのプラットホームにおいて、休止要求の分解能は10ミリ秒で、どんな1から10000ミリ秒の間の非ゼロである commit_delay 設定は同じ効果となることを覚えておいてください。 いくつかのプラットフォームで、休止操作はパラメータによって要求された時間よりわずかに長くなることも覚えておいてください。

commit_delay の目的はそれぞれのフラッシュ操作のコストを同時実行されるコミットのトランザクションに渡って償却することから(潜在的にはトランザクションの待ち時間の代償により)、設定が知的に選択される以前にそのコストが定量化される必要があります。 そのコストが高ければ高いほど、 commit_delay がその時点までトランザクションの処理量が増加すると期待されます。 pg_test_fsync プログラムは、一つのWALフラッシュが必要とするマイクロ秒単位の平均時間を計測するために使用可能です。 プログラムが報告する単一の8kb書き込み操作のあとのフラッシュ平均時間の2分の1の値は、しばしば commit_delay の最も効果的な設定です。従って、この値は特定の作業負荷を最適化する時に使用する開始時点として推奨されます。 WALログが高遅延の回転ディスクに格納されているとき、 commit_delay のチューニングは特に有効であることから、半導体ドライブまたはバッテリー・バックアップされている書き込みキャッシュ付きのRAIDアレーのような、特別に高速な同期時間を所有する格納メディア上であってもメリットは特筆すべきものです。しかし、このことは代表的作業負荷に対して間違いなく検証されなければなりません。 commit_siblings の高い値は、これらの状況で使用されなければならず、一方より小さな commit_siblings の値は高遅延メディア上でしばしば有用です。 余りにも高い値の commit_delay を設定すると、ほぼ間違いなくトランザクションの負荷の総計が被るトランザクション遅延を大幅に増加させることになります。

commit_delay が(デフォルトの)ゼロに設定されると、グループコミットという種類が発生することが依然としてあります。しかし、それぞれのグループは前回のフラッシュ操作(あった場合)が発生したなかでの期間中にそれぞれのコミットレコードをフラッシュする必要があった時点に到達したセッションのみから成ります。 上位のクライアントにおいて "gangway effect" が起こりそうだと計量すると、 commit_delay がゼロであってもグループコミットの効果が著しく、そして従い、 commit_delay を明示的に設定しても役立だちません。 commit_delay の設定は(1)いくつかの同時実行するコミットトランザクションが存在すること、そして(2)コミット度合いによりある程度までスループットが制限されている場合に役立ちます。 しかし、高い回転待ち時間の場合、この設定はわずか二つのクライアントのトランザクションスループットを増加される効果があります(言いかえれば、一つの兄弟(sibling)トランザクションを所有する単一のコミットするクライアントです)。

wal_sync_method パラメータは PostgreSQL がカーネルに対して WAL 更新のディスクへの書き込みを要求する方法を決定します。 fsync_writethrough を除き、どういう設定でも信頼性は同じはずです。 fsync_writethrough は他のオプションがそうしないときでも、時々ディスクキャッシュの書き出しを強制することができます。 しかしながら、プラットフォームによってどれが一番速いのかがまったく違います。 pg_test_fsync プログラムを使って異なるオプションの速度テストを行うことができます。 ちなみに、このパラメータは fsync が無効になっている場合は役に立ちません。

wal_debug 設定パラメータを有効にすることで、 XLogInsert XLogFlush という WAL 呼び出しは毎回サーバログにログが残ります (このパラメータをサポートするように PostgreSQL をコンパイルする必要があります)。 将来このオプションはより一般的な機構に置き換わる可能性があります。


powered by SEO.CUG.NET