今後のPostgreSQL9.0の新しいホットスタンバイ機能により、以前はリカバリプロセスを実行するだけだったスタンバイノードに対してクエリを実行できます。この機能を期待しているユーザーから聞いた2つの一般的な期待は、両方のノードに短いクエリを分散できるか、マスターのリソースを使用せずにスタンバイに対して長いレポートを実行できるようになることです。これらは両方とも現在実行可能ですが、ホットスタンバイの動作に伴うトレードオフを理解していない限り、ここで予期しない動作が発生する可能性があります。
標準の長時間実行クエリ
PostgreSQLなどのMVCCを使用するデータベースの従来の問題の1つは、データベースがクエリに必要なデータを削除しないようにするために、実行時間の長いクエリがリソース(現在のPostgres実装ではスナップショットと呼ばれる)を開いたままにする必要があることです。動作します。たとえば、別のクライアントが行を削除してコミットしたという理由だけで、すでに実行中のクエリがその行を完了する必要がある場合、その行に関連する物理ディスクブロックをまだ実際に消去することはできません。行が表示されることを期待する開いているクエリがまだ存在しなくなるまで待つ必要があります。
ホットスタンバイの制限
ホットスタンバイに実行させたい長時間実行クエリがある場合、リカバリプロセスが更新を適用しているときに発生する可能性のあるいくつかのタイプの悪いことがあります。これらについては、ホットスタンバイドキュメントで詳しく説明されています。これらの悪いことのいくつかは、直感的に明らかではないかもしれない理由でスタンバイで実行されているクエリをキャンセルする原因になります:
- クエリが表示されると予想されるものを削除するために、HOT更新またはVACUUM関連の更新が到着します
- Bツリーの削除が表示されます
- 実行しているクエリと、更新を処理するために必要なロックの間にロックの問題があります。
ロックの状況に対処するのは困難ですが、スタンバイで読み取り専用クエリを実行しているだけの場合、MVCCを介して分離されるため、実際にはそれほど長くは発生しません。他の2つは遭遇するのは難しいことではありません。理解しておくべき基本的なことは、任意 マスターでのUPDATEまたはDELETEは、スタンバイでのクエリの中断につながる可能性があります。変更がクエリの実行内容に関連しているかどうかは関係ありません。
良い、速い、安い:2つ選ぶ
基本的に、人々が優先したいと思うかもしれない3つのことがあります:
- マスターの制限を回避する:xidと関連するスナップショットをマスター上で無制限に進めることを許可します。これにより、VACUUMや同様のクリーンアップがスタンバイの実行によって妨げられることがなくなります。
- 無制限のクエリ:スタンバイで任意の期間クエリを実行します
- 現在のリカバリ:スタンバイでのリカバリプロセスをマスターで何が起こっているかを最新の状態に保ち、HAの高速フェイルオーバーを可能にします
ホットスタンバイのある状況では、3つすべてを同時に持つことは文字通り不可能です。トレードオフを選択することしかできません。利用可能な調整可能なパラメータにより、いくつかの方法を最適化できます。
- これらの遅延/延期設定をすべて無効にすると、常に最新のリカバリが最適化されますが、クエリが予想よりもキャンセルされる可能性が高くなります。
- max_standby_delay リカバリを最新に保つことを犠牲にして、より長いクエリ用に最適化します。これにより、問題の原因となる更新(HOT、VACUUM、Bツリーの削除など)が発生すると、スタンバイへの更新の適用が遅れます。
- vacuum_defer_cleanup_age スナップショットハックの中には、他の2つの問題を改善するためのマスター制限を導入するものもありますが、それを行うにはUIが弱くなります。 vacuum_defer_cleanup_ageはトランザクションIDの単位です。人々がこの問題について考える方法(「レポートが実行されるように少なくとも1時間延期する」)をこの値の設定に変えるには、システムでの単位時間あたりのxidチャーンの平均量を把握する必要があります。 xidの消費率は、測定/予測するのに一般的または合理的なものではありません。または、スタンバイで長時間実行されるクエリを開始する前に、プライマリでスナップショットを開くことができます。これを実現する方法として、ホットスタンバイのドキュメントでdblinkが提案されています。理論的には、スタンバイ上のデーモンをユーザーランドに作成し、プライマリーに常駐させて、この問題を回避することもできます(Simonには基本的な設計があります)。基本的に、一連のプロセスを開始し、それぞれがスナップショットを取得してから、それを解放する前に一定期間スリープします。それぞれがスリープする時間の間隔を空けることで、xidスナップショットがマスター上であまりにも速く進むことがないようにすることができます。これがどれほどひどいハッキングになるかは、すでに明らかなように聞こえるはずです。
改善の可能性
これらのうち、本当にきれいにできることは、マスター制限のUIを強化して改善することだけです。これは、これをデータベースにすでに存在する従来の問題に変えます。長時間実行されるクエリは、マスターでスナップショットを開いたままにし(または、少なくとも可視性に関連するトランザクションIDの進行を制限し)、マスターがそのクエリに必要なものを削除できないようにします。完了。あるいは、これを自動調整のvacuum_defer_cleanup_ageと考えることもできます。
問題は、プライマリを作成する方法です。 スタンバイで長時間実行されるクエリのニーズを尊重する 。これは、スタンバイのトランザクションの可視性要件に関する詳細情報がマスターと共有されている場合に可能になる可能性があります。この種の交換を行うことは、新しいストリーミングレプリケーションの実装が共有するのにより適切なことです。単純なホットスタンバイサーバーのプロビジョニング方法では、前述のdblinkハックなどのアプローチ以外に、このデータを交換するのに適したマスターへのフィードバックは提供されません。
PostgreSQL 9.0が4番目のアルファリリースに到達したばかりの場合、 9.0リリースの前に、この領域でいくつかの改善を確認する時間はまだあります。このリリースでのコーディングが完全にフリーズする前に、どちらも単独では完全に実行できないことを実現する方法で、ホットスタンバイとストリーミングレプリケーションが実際に統合されているのを見るのは素晴らしいことです。