ホットスタンバイという単語は、サーバがアーカイブリカバリまたはスタンバイモードにある間に実行している最中に、サーバに接続し読み取り専用の問い合わせを実行することができる機能を説明するために使われます。 これは、レプリケーションという目的およびバックアップからのリストアの両方で高い精度で好ましい状態にするために有用です。 ホットスタンバイという単語はまた、ユーザが問い合わせを実行しながら、または、開いている接続を維持しながら、またはその両方で、サーバをリカバリ状態から通常の動作に移すことができる機能も示すものです。
ホットスタンバイモードにおける問い合わせは、通常の問い合わせに類似していますが、利用上および管理上の差異が多少あり、以下に説明します。
スタンバイサーバでhot_standbyパラメータが真に設定されている場合、リカバリによりシステムが一貫性を持つようになった後接続を受け付け始めます。 こうした接続はすべて読み取り専用に限定されます。 一時テーブルであっても書き込むことはできません。
スタンバイ上のデータはプライマリサーバから届くまでに多少の時間がかかります。 このため、プライマリとスタンバイの間にはある程度の遅延があります。 したがって、同じ問い合わせをほとんど同時にプライマリとスタンバイに対して実行すると、異なる結果が返る可能性があります。 スタンバイ上のデータはプライマリに対して最後には一貫性を持つといいます。 あるトランザクションのコミットレコードがスタンバイ上で再生されると、そのトランザクションでなされた変更はスタンバイで獲得されるすべての新規スナップショットで可視になります。 現在のトランザクション分離レベルに応じて、スナップショットは各問い合わせの開始時または各トランザクションの開始時に獲得されます。 詳細については13.2を参照してください。
ホットスタンバイ中に開始されたトランザクションは以下のコマンドを発行することができます。
問い合わせによるアクセス: SELECT
およびCOPY TO
カーソルコマンド: DECLARE
とFETCH
とCLOSE
設定の操作: SHOW
とSET
とRESET
トランザクション管理コマンド:
BEGIN
とEND
とABORT
とSTART TRANSACTION
SAVEPOINT
とRELEASE
とROLLBACK TO SAVEPOINT
EXCEPTION
ブロックおよびこの他の内部サブトランザクション
LOCK TABLE
。
なお、以下のモードが明示された場合に限ります。
ACCESS SHARE
またはROW SHARE
またはROW EXCLUSIVE
計画と資源: PREPARE
とEXECUTE
とDEALLOCATE
とDISCARD
プラグインと拡張: LOAD
UNLISTEN
ホットスタンバイ中に開始したトランザクションではトランザクションIDを割り当てられません。 また、システムのログ先行書き込みに書き出すことができません。 このため、以下の動作はエラーメッセージを生成します。
データ操作言語(DML):
INSERT
、UPDATE
、DELETE
、MERGE
、COPY FROM
およびTRUNCATE
。
リカバリ中にトリガ内で実行されてしまう場合でも許されていない動作であることに注意してください。
現在のホットスタンバイ環境では行うことができないトランザクションIDの割り当てを行うことなく、テーブル行の読み書きを行うことができませんので、この制限は一時テーブルであっても適用されます。
データ定義言語(DDL):
CREATE
、DROP
、ALTER
およびCOMMENT
。
この制約は一時テーブルに対しても適用されます。
これらの操作の実行がシステムカタログテーブルの更新を必要とするためです。
SELECT ... FOR SHARE | UPDATE
。
背後のデータファイルを更新することなく行ロックを獲得することはできないためです。
データ操作言語のコマンドを生成するSELECT
文のルール
ROW EXCLUSIVE MODE
より高いモードを明示的に要求するLOCK
短いデフォルト構文のLOCK
。
これはACCESS EXCLUSIVE MODE
を要求するためです。
読み取り専用でない状態を明示的に設定するトランザクション処理コマンド
BEGIN READ WRITE
とSTART TRANSACTION READ WRITE
SET TRANSACTION READ WRITE
とSET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
SET transaction_read_only = off
二相コミットコマンド: PREPARE TRANSACTION
、COMMIT PREPARED
およびROLLBACK PREPARED
。
読み取り専用トランザクションでも、プリペア相(二相コミットの第1相)においてWALの書き込みが必要だからです。
シーケンス更新の関数: nextval()
とsetval()
LISTEN
、NOTIFY
通常の操作では、「読み取り専用」トランザクションにはLISTEN
とNOTIFY
の使用が許可されています。
ホットスタンバイセッションの操作では、通常の読み取り専用セッションよりも少し厳しい制約を受けます。
将来のリリースではこの制約の一部が緩和されるかもしれません。
ホットスタンバイ中は、transaction_read_only
パラメータは常に真であり、変更することはできません。
しかし、データベースを変更するような試行がない限り、ホットスタンバイ中の接続は他のデータベース接続とほとんど同じように動作します。
もし、フェイルオーバーまたはスイッチオーバーが発生すると、データベースは通常処理モードに切り替わります。
サーバのモードが変わってもセッションは接続を保持します。
ホットスタンバイが完了すると、読み書き可能なトランザクションを(ホットスタンバイ中に始まったセッションからであっても)始められるようになります。
ユーザはSHOW in_hot_standby
を発行することで、そのセッションが読み取り専用かどうかを調べることができます。
(サーババージョンが14より前ではin_hot_standby
パラメータは存在しませんでした。古いバージョンでの可能な代替方法は、SHOW transaction_read_only
です。)
さらに、ユーザがスタンバイサーバに関する情報にアクセスできる関数群(表 9.90)があります。
これらによりデータベースの現状認識を行うプログラムを作成することができます。
これらを使用して、リカバリの進行状況を監視するために使用したり、データベースを特定の状態にリストアする複雑なプログラムを作成したりすることができます。
プライマリサーバとスタンバイサーバは、多方面でゆるく結合しています。 プライマリサーバの動作はスタンバイサーバに影響します。 その結果、負の相互作用またはコンフリクトの可能性があります。 最も分かりやすいコンフリクトは性能です。 プライマリサーバで巨大なデータがロードされた場合、スタンバイサーバにおいて同様に巨大なWALレコードが生成されるので、スタンバイサーバにおける問い合わせは互いにI/Oなどのシステム資源を奪い合います。
ホットスタンバイで発生する可能性があるコンフリクトの種類には他にもあります。 これらのコンフリクトは、問い合わせをキャンセルしなければならない可能性があり、解消させるためにはセッションの接続を閉ざすことになる場合もあるため、致命的なコンフリクトです。 ユーザにはこうしたコンフリクトを扱うための複数の方法が提供されます。 コンフリクトする状況には以下があります。
プライマリサーバで獲得されたアクセス排他ロックは、スタンバイの問い合わせにおけるテーブルアクセスとコンフリクトします。
明示的なLOCK
コマンドおよび各種DDL操作を含みます。
プライマリでテーブル空間を削除することは、一時作業ファイル用にそのテーブル空間を使用するスタンバイ側の問い合わせとコンフリクトします。
プライマリでデータベースを削除することは、スタンバイ側でそのデータベースに接続するセッションとコンフリクトします。
WALからのバキュームクリーンアップレコードの適用は、その適用により削除される行のどれか1つでも「見る」ことができるスナップショットを持つスタンバイでのトランザクションとコンフリクトします。
WALからのバキュームクリーンアップレコードは、消去されるデータが可視か否かに関係なく、スタンバイで対象ページにアクセスする問い合わせとコンフリクトします。
プライマリサーバでは、こうした状況は単に待たされるだけです。 ユーザはコンフリクトする操作をキャンセルすることを選ぶことができます。 しかし、スタンバイ側には選択肢がありません。 WALに記録された操作はすでにプライマリで発生したものですので、スタンバイではその適用に失敗してはなりません。 さらに、適用したいWALを無制限に待機させることを許すことは、まったく望まない結果になってしまうかもしれません。 なぜなら、スタンバイの状態がプライマリの状態とだんだんとかけ離れてしまうからです。 したがって適用すべきWALレコードとコンフリクトするスタンバイの問い合わせを強制的に取り消す仕組みが用意されています。
この問題の例として、スタンバイサーバで現在問い合わせ対象となっているテーブルをプライマリサーバでDROP TABLE
を行う管理者を考えてみます。
スタンバイでDROP TABLE
が適用されたら問い合わせを継続できないことは明確です。
プライマリ上でこうした状況が発生した場合は、他の問い合わせが終わるまでDROP TABLE
は待機させられます。
しかし、DROP TABLE
がプライマリで実行された時、プライマリ側でスタンバイで稼働する問い合わせに関する情報がありませんので、スタンバイ側のこうした問い合わせを待機させることはできません。
スタンバイ側で問い合わせが実行している時にWALの変更レコードがスタンバイに届けば、コンフリクトが発生します。
スタンバイサーバはWALレコードの適用を遅延させる(およびその後の適用すべても遅延させる)か、DROP TABLE
を適用できるようにコンフリクトする問い合わせを取り消すかのいずれかを行わなければなりません。
コンフリクトする問い合わせが短ければ、適用したいWALを多少遅延させることで、問い合わせを完了させることが通常望まれます。 しかし、WALの適用が長く遅延することはたいていは望まれません。 したがって、取り消し機能はmax_standby_archive_delayとmax_standby_streaming_delayというパラメータを持ちます。 これらはWAL適用に許される遅延を定義するものです。 コンフリクトする問い合わせは、何らかの新しく受信したWALデータを適用するための各種遅延設定を超えたら取り消されます。 アーカイブからWALデータを読み取る場合(つまりベースバックアップからの初期リカバリや大きく遅延したスタンバイサーバの「追従」)とストリーミングレプリケーションとで異なる遅延値を指定することができるように2つのパラメータが存在します。
主に高可用性のために存在するスタンバイサーバでは、スタンバイ側の問い合わせによって発生する遅延のためにプライマリと大きく遅延が発生することがないように、遅延パラメータを相対的に短く設定することが最善です。 しかし、スタンバイサーバが長時間かかる問い合わせを実行するためのものであれば、長い遅延もしくは制限を設けないことが好まれるかもしれません。 しかし、長時間かかる問い合わせがWALレコードの適用を遅延させてしまう場合、スタンバイサーバ上の他のセッションがプライマリにおける最近の変更を参照することができなくなることは覚えておいてください。
max_standby_archive_delay
またはmax_standby_streaming_delay
で指定した遅延を超えると、コンフリクトする問い合わせは取り消されます。
通常これは単なる取り消しエラーという結果となりますが、DROP DATABASE
を再生する場合では、コンフリクトするセッション全体が終了します。
また、コンフリクトが待機中のトランザクションで保持されるロックについてのものであれば、そのコンフリクトするセッションが終了します(この動作は将来変更されるかもしれません)。
ユーザは取り消された問い合わせをすぐに再試行するかもしれません(もちろん新規のトランザクション開始後に)。 問い合わせの取り消しは、再生されるWALレコードの性質に依存するので、取り消された問い合わせが再度実行された場合には正常に動作するかもしれません。
遅延パラメータはスタンバイサーバでWALデータを受信してからの経過時間と比べられることに注意してください。 したがって、スタンバイ上で任意の問い合わせに許される猶予期間は、この遅延パラメータよりも大きくなることは決してありません。 これまでの問い合わせを完了させるために待機した結果、あるいは、大量の更新負荷に追従することができなくなった結果、スタンバイがすでに遅延している場合は相当小さくなります。
スタンバイ側の問い合わせとWAL再生の間でもっともよくあるコンフリクト理由は「早すぎる消去」です。 通常PostgreSQLはMVCC規則にしたがって正確なデータの可視性を確実にするために、古い行バージョンを参照するトランザクションが存在しない場合それらを消去することが許されています。 しかし、この規則はプライマリ上で実行するトランザクションのみに適用させることができます。 したがって、スタンバイ上のトランザクションでまだ可視である行バージョンを、プライマリ上の消去処理が削除してしまう可能性があります。
熟練したユーザは、行バージョンの消去と行バージョンの凍結の両方ともスタンバイ側の問い合わせとコンフリクトする可能性があることに気づくはずです。
手作業でのVACUUM FREEZE
は、更新または削除された行がないテーブルであったとしてもコンフリクトを発生し易いものです。
プライマリサーバにおいて規則的かつ頻繁に更新されるテーブルは、スタンバイサーバにおける問い合わせの取り消しの原因になりやすいことを利用者は理解するべきです。
そのような場合、max_standby_archive_delay
またはmax_standby_streaming_delay
の設定値はstatement_timeout
の設定と同様に考えることができます。
スタンバイにおける問い合わせの中断が受け入れがたいほど多い場合、この問題を改善する方法が用意されています。
1つ目の選択肢は、hot_standby_feedback
パラメータを設定することです。
これはVACUUM
による最近不要になった行の削除を防止しますので、消去によるコンフリクトが発生しません。
これを行う場合、プライマリで不要になった行の消去が遅延することに注意が必要です。望まないテーブルの膨張が発生してしまうかもしれません。
しかし、スタンバイ側で行うべき問い合わせをプライマリサーバ上で直接実行することと比べ、こうした消去に関する問題を優先する価値はありません。
また、スタンバイに実行負荷を分散できるという利点があります。
スタンバイサーバが接続、切断を頻繁に繰り返す場合、hot_standby_feedback
によるフィードバックが提供されていなければ、その値を調整したいと思うでしょう。
例えば、max_standby_archive_delay
が増大し、切断している期間WALアーカイブのコンフリクト発生による問い合わせの中断が速やかに行われないことを考えてみてください。また、再接続後に速やかに問い合わせが中断されることを避けるためにmax_standby_streaming_delay
を大きくすることを考えてみてください。
他の選択肢は、不要になった行が通常よりも早く消去されないようにプライマリサーバでvacuum_defer_cleanup_ageを増やすことです。
これにより、max_standby_streaming_delay
を長くすることなく、スタンバイでキャンセルが起こるようになる前により多くの時間、問い合わせを実行することができます。
しかし、vacuum_defer_cleanup_age
はプライマリサーバ上で実行されたトランザクションを単位に測定されますので、この方法では特定の実行期間を保証することは困難です。
問い合わせキャンセルの個数とその原因はスタンバイサーバ上のpg_stat_database_conflicts
システムビューを用いて参照することができます。
またpg_stat_database
システムビューには要約された情報が含まれます。
コンフリクトのためにWAL再生がdeadlock_timeout
より長くかかる場合にログメッセージを出力するかどうかをユーザは制御できます。
log_recovery_conflict_waitsパラメータで制御します。
postgresql.conf
においてhot_standby
がon
で(これはデフォルトです)、かつstandby.signal
が存在すれば、サーバはホットスタンバイモードで稼働します。
しかし、サーバはまず問い合わせが実行できる程度の一貫性を持つ状態を提供するために十分なリカバリを完了させなければなりませんので、ホットスタンバイでの接続が有効になるまでに多少の時間がかかるかもしれません。
サーバの準備ができたことを確認するために、アプリケーションで接続試行を繰り返すか、サーバログに以下のメッセージがあるかどうかを確認します。
LOG: entering standby mode ... 多少時間が経過して ... LOG: consistent recovery state reached LOG: database system is ready to accept read-only connections
一貫性に関する情報はプライマリでチェックポイント毎に一回記録されます。
プライマリでwal_level
がreplica
もしくはlogical
に設定されていなかった期間に書き込まれたWALを読み取っている間は、ホットスタンバイを有効にすることはできません。
また、一貫性のある状態への到達は、以下の両方が存在する間遅延することがあります。
サブトランザクション数が64を超える書き込みトランザクション
非常に長く実行される書き込みトランザクション
ファイルベースのログシッピング(「ウォームスタンバイ」)を実行しているのであれば、次のWALファイルが届く、長くともプライマリのarchive_timeout
設定まで待機しなければなりません。
いくつかのパラメータの設定により、トランザクションID、ロック、準備されたトランザクションを追跡するための共有メモリのサイズが決まります。 リカバリ中に共有メモリを使い尽くすことがないことを確実にするために、スタンバイサーバにおける設定値は、プライマリサーバにおける設定値以上でなければなりません。 たとえばプライマリが準備されたトランザクションを実行していてスタンバイが準備されたトランザクションを追跡するための共有メモリを獲得していなければ、スタンバイは設定が変更されるまではリカバリを続けることができません。 影響があるパラメータは以下です。
max_connections
max_prepared_transactions
max_locks_per_transaction
max_wal_senders
max_worker_processes
これが問題にならないようにする確実な方法は、スタンバイにおけるこれらのパラメータの値をプライマリでの値以上にすることです。 ですから、これらの値を増やしたいなら、プライマリで設定を変更する前に、まずスタンバイで設定変更するべきです。 逆にこれらの値を減らしたいなら、スタンバイで設定を変更する前に、まずプライマリで設定変更するべきです。 スタンバイが昇格したときは、それが追従するスタンバイにとって必要なパラメータ設定の新しい基準になるということを覚えておいてください。 ですから、スイッチオーバーやフェイルオーバー中にこれが問題にならないようにするために、これらの設定値をすべてのスタンバイで同じにしておくことをお勧めします。
プライマリでWALはこれらのパラメータの変更を追跡します。 ホットスタンバイが現在のプライマリの値がスタンバイの値よりも大きいことを示すWALを処理すると、警告をログし、リカバリを中断します。 例を示します。
WARNING: hot standby is not possible because of insufficient parameter settings DETAIL: max_connections = 80 is a lower setting than on the primary server, where its value was 100. LOG: recovery has paused DETAIL: If recovery is unpaused, the server will shut down. HINT: You can then restart the server after making the necessary configuration changes.
この時点で、スタンバイの設定を変更し、リカバリを継続するためにインスタンスを再起動する必要があります。 スタンバイがホットスタンバイでない場合は、整合性のないパラメータの変更があると、休止することなく直ちにシャットダウンします。起動し続ける意味がないからです。
max_standby_archive_delayおよびmax_standby_streaming_delayの値が適切であるように管理者が選択することが重要です。 最善の選択は業務上の優先順位によって変化します。 例えば、サーバが主に高可用性を目的としたサーバとして作業するものであれば、短い遅延を設定したいでしょう。 非常に積極的な設定ですが、ゼロにしたいかもしれません。 スタンバイサーバが意思決定支援のための問い合わせ用の追加サーバとして作業するものであれば、数時間程度の最大の遅延値の設定、あるいは問い合わせの完了を永遠に待つことを意味する-1という設定でさえ、許容範囲であるかもしれません。
プライマリ側で「ヒントビット」として書き出されたトランザクション状態はWALに記録されません。 このためスタンバイ側のデータはスタンバイ側でヒントを再度書き出すことになります。 ユーザは大規模なソート用の一時ファイルを書き出し、relcache情報ファイルを再作成します。 したがって、ホットスタンバイモードではデータベースのすべてが本当に読み取り専用ではありません。 また、ローカルでは読み取り専用のトランザクションであってもdblinkモジュールを使用したリモートデータベースへの書き出しや、その他のPL関数を使用したデータベース外部への操作が可能であることに注意してください。
リカバリモードの間、下記の管理者用コマンドは受理されません。
データ定義言語: 例えばCREATE INDEX
権限および所有権: GRANT
とREVOKE
とREASSIGN
保守コマンド: ANALYZE
とVACUUM
とCLUSTER
とREINDEX
繰り返しますが、これらのコマンドの一部は、プライマリサーバにおける「読み取り専用」モードのトランザクションで実際に許可されていることに注意してください。
その結果、スタンバイ側にのみ存在する追加のインデックスやスタンバイ側にのみ存在する統計情報を作成することはできません。 これらの管理者用コマンドが必要な場合、プライマリ側で実行しなければなりません。 最終的にこの変更はスタンバイ側に伝播します。
pg_cancel_backend()
とpg_terminate_backend()
はユーザを扱うバックエンドでは実行できますが、リカバリを実行する起動プロセスでは実行できません。
pg_stat_activity
はリカバリ中のトランザクションをアクティブとして表示しません。
その結果、リカバリの間pg_prepared_xacts
は常に空となります。
調査が必要な準備されたトランザクションがある場合は、プライマリサーバにおいてpg_prepared_xacts
を表示し、その場でトランザクションを解決するか、リカバリが終わるのを待ってからトランザクションを解決します。
pg_locks
は通常通りバックエンドで保持されるロックを示します。
pg_locks
はまた、リカバリによって再生されているトランザクションで保持されるAccessExclusiveLocks
のすべてを所有する、起動プロセスで管理される仮想トランザクションも表示します。
起動プロセスはデータベースの変更を行うためのロックを獲得しません。
このため起動プロセスにおいてAccessExclusiveLocks
以外のロックはpg_locks
では表示されません。
これらは存在することを想定されているだけです。
存在を検知する情報が単純なので、Nagiosプラグインcheck_pgsqlは稼働します。 一部の報告値が異なった、混乱を招く結果となりますが、check_postgresの監視スクリプトも動作します。 たとえば、スタンバイではバキュームが発生しないため、最終バキューム時刻は維持されません。 それでも、プライマリで行われるバキュームはその変更をスタンバイに送信します。
リカバリの間WALの制御コマンドは稼働しません。
例えば、pg_backup_start
やpg_switch_wal
などです。
pg_stat_statements
も含み、動的に読み込み可能なモジュールは稼働します。
デッドロック検出を含むアドバイザリロックは、通常リカバリにおいて稼働します。 アドバイザリロックはWALに決して記録されないので、プライマリサーバでもスタンバイサーバでもWALの再実行においてコンフリクトが起こらないことに注意してください。 プライマリサーバでアドバイザリロックを取得して、スタンバイサーバで同様のアドバイザリロックを掛けることはできません。 アドバイザリロックは取得したサーバだけに関係するものです。
SlonyやLondisteやBucardoのようにトリガに基づいたレプリケーションシステムは、スタンバイサーバで全く稼働しません。 しかし、それによる変更がスタンバイサーバに送られるまでは、プライマリサーバにおいて問題なく稼働します。 WALの再実行はトリガに基づいたものではありません。 したがって、データベースへの付加的な書き込みを必要とするか、トリガの使用に依存するものを、スタンバイサーバを中継して他のシステムへ送ることはできません。
一部のUUIDジェネレータは、データベースに新しい状態を書き出すことに依存していない限り動作可能ですが、新しいOIDを割り当てることはできません。
現時点では、読み取り専用のトランザクションでは一時テーブルの作成は許されません。 このため既存のスクリプトが正しく動作しない場合があります。 この制限は将来のリリースで緩和されるかもしれません。 これは、標準SQLとの互換性の問題でもあり、技術的な問題でもあります。
テーブル空間が空の場合だけ、DROP TABLESPACE
が成功します。
一部のスタンバイ側のユーザはtemp_tablespaces
パラメータを介してテーブル空間を活発に使用しているかもしれません。
テーブル空間に一時ファイルが存在する場合、一時ファイルを確実に削除するためすべての問い合わせが取り消されます。
このため、WAL再生を続けながらテーブル空間を削除することができます。
プライマリサーバにおけるDROP DATABASE
またはALTER DATABASE ... SET TABLESPACE
の実行により、スタンバイサーバのデータベースに接続するすべてのユーザを強制的に接続を切断させることになるWALエントリを生成します。
これはmax_standby_streaming_delay
の設定にかかわらず、直ちに起こります。
ALTER DATABASE ... RENAME
はユーザを切断しないので大部分の場合は気がつきませんが、プログラムがデータベースの名称に依存するときは混乱の原因となることに注意してください。
通常の(リカバリ以外の)モードで、ログイン権限を持つロールが接続している間にそのロールにDROP USER
またはDROP ROLE
を発行した場合、接続中のユーザには何も起こらず、接続し続けます。
しかし、そのユーザは再接続できません。
この振舞いはリカバリモードでも適用されます。
このためプライマリ側でDROP USER
されたとしても、スタンバイ側のユーザの接続は切断されません。
リカバリの間も累積統計システムはアクティブになります。 すべてのスキャン、読み取り、ブロック、インデックスの使用などは、スタンバイサーバにおいて正常に記録されます。 しかし、WAL再生はリレーションやデータベース固有のカウンタを増加させません。 つまり、再生はpg_stat_all_tables列(n_tup_insなど)を増加させませんし、起動プロセスによって実行された読み取りや書き込みもpg_statioビューで追跡されませんし、関連するpg_stat_database列も増加されません。
リカバリの間は自動バキュームは稼働しません。 リカバリが終わると正常に起動します。
リカバリの間、チェックポイントプロセスとバックグラウンドライタプロセスは稼働しています。
チェックポイントプロセスは(プライマリサーバにおけるチェックポイントに類似した)リスタートポイントを設定し、通常のブロック消去を行います。
これはスタンバイサーバに保存されるヒントビット情報の更新を含むことができます。
リカバリの間CHECKPOINT
コマンドは受理されますが、新規のチェックポイントではなくてリスタートポイントが設定されます。
種々のパラメータが上記27.4.2および27.4.3で述べられています。
プライマリサーバでは、wal_levelおよびvacuum_defer_cleanup_ageのパラメータを使用できます。 プライマリサーバにmax_standby_archive_delayおよびmax_standby_streaming_delayを設定しても無効です。
スタンバイサーバではhot_standbyとmax_standby_archive_delayとmax_standby_streaming_delayのパラメータを使用できます。 サーバがスタンバイモードの間vacuum_defer_cleanup_ageを設定しても無効です。 しかし、スタンバイサーバがプライマリサーバになった場合、意味を持つようになります。
ホットスタンバイには幾つかの制限があります。 将来のリリースでは改善されると思われます。
スナップショットを取ることができるようになる前に、実行中のトランザクションについての完全な知識が要求されます。 (現時点では64を超える)多くのサブトランザクションを使用するトランザクションでは、実行中の最長の書き込みトランザクションが完了するまで、読み取り専用の接続の開始は遅延されます。 この状況が起こると、それを説明するメッセージがサーバログに記録されます。
スタンバイ問い合わせ用の有効な起動ポイントは、プライマリにおけるチェックポイント毎に生成されます。 プライマリが停止状態にある時にスタンバイが停止した場合、プライマリが起動し、さらに起動ポイントをWALログに生成するまで再度ホットスタンバイになることができないことがあります。 この状況は、通常考えられる状態では問題ではありません。 一般的に、プライマリが停止し利用できなくなった場合、それはスタンバイに対して新しいプライマリに切り替わることを要求するような深刻な失敗が原因であることが多いはずです。 また、プライマリを意図的に停止させるような状況では、それに伴いスタンバイが新しいプライマリになめらかに切り替わることも普通の手順です。
リカバリの終了において、準備されたトランザクションが保持するAccessExclusiveLocks
には、通常の2倍のロックテーブルへのエントリ数が必要です。
通常AccessExclusiveLocks
を取るプリペアドトランザクションを大量に同時実行させる、または、多くのAccessExclusiveLocks
を取る大規模なトランザクションを1つ実行させることを考えている場合、max_locks_per_transaction
の値を、おそらくプライマリサーバのパラメータ値の倍程度に大きくすることを勧めます。
max_prepared_transactions
の設定が0ならば、これを検討する必要はまったくありません。
シリアライザブルトランザクション分離レベルはまだホットスタンバイでは利用できません。 (13.2.3および13.4.1参照) ホットスタンバイにおいてトランザクションをシリアライザブルトランザクション分離レベルに設定しようとすると、エラーになります。