pgpoolについて学ぶ

PostgreSQLを使用しており、pgpool-IIも合わせて使っています。そんな時に、リカバリーの操作がうまくできていないことが発覚しました。今までpgpoolについて詳しく知らずに使っていました。そこで、マニュアルを読んで今一度学び直したいと思います。
以下は、マニュアルを読んだ際のメモです。

マニュアルを読んで

http://pgpool.projects.postgresql.org/pgpool-II/doc/pgpool-ja.html
ありがたい事に、日本語のドキュメントがあります。こちらを読んでみます。特に、リカバリ系は今必要な部分であるため、そこはしっかり読みたいと思います。

ちなみに、次のドキュメントも大変参考になります。
http://www.interdb.jp/techinfo/web+db48/pgpool.html

機能概要

コネクションプーリング、レプリケーション、負荷分散、接続数の制限、パラレルクエリとのこと。
自分的には、「pgpool-IIはPostgreSQLバックエンドとフロントエンドの通信プロトコルを理解してその間を中継します。」という、使う側から見たらpgpool使ってるけどPostgreSQL見てるのと同じってところがぐっときました。あと、パラレルクエリってどこまで使えるのか正直不安、と思いました。リスクはあるものの、メリットもあるため、リスクが許容できるのであれば使用することもやぶさかではないとは思います。

インストール

pgpool_regclassのインストールなんてものがあるんですね。すっかり抜け落ちてました。

pgpool-IIの設定

pgppoolの動作モードって詳しいところはあまり気にしていませでした。自分はレプリケーションモードを使ってます。

pcp.confの設定

pcp.confってなんの略なのかとても気になります。

共通設定項目

num_init_childrenは押さえておかなければいけなそうです

問合せのキャンセルがある場合は設定値を考える必要あり、とのこと。max_poolとのかけ合わせた数がPostgreSQLへのコネクション数というのも覚えておかなければけなそうです。

接続のキャパを増やす場合、num_init_childrenとmax_poolどちらを増やすべきか

child_life_timeとchild_max_connectionsでプロセスのリセット値があるため、リセットされる際にはmax_poolの数のコネクションが消滅されるということのはずです。とは言え、プロセス数が異常に多いとプロセス管理のコストが増えると考えるべきなのでしょう。

logdirで指定するpgpool_statusファイルの存在

pgpoolのステータスを管理するためのデータを保存するファイルのようですが、このファイルのせいなのかはまだ不明ですが、pgpool停止起動後の動きが少々おかしなことがありました。その場合、pgpool_statusファイルを削除して起動すると状態が回復するため(ファイルを消してリセットしてるので当然ですかね)、少々気になります。

failover_commandとfailback_command

ノードが切り離された時、ノードが復帰した時のことまで細かく考えていませんでした。この設定を今一度考える必要がありそうです。

log_statementやlog_per_node_statement、log_connections、debug_levelでログによる監視

何か起きたときに監視する方法も覚えておいた方が良さそうです。log_per_node_statementを指定すると、ノード毎に実行したstatementがログ出力されるので、ログファイルのサイズがえらいことになります。不具合調査時のみオンで、常時はオフの方が良さそうです。

コネクションプールモード

ユーザ:データベースでコネクションの再利用をおこなう

"[ユーザ名:データベー ス名]のペアの種類の数だけをmax_poolに指定しておく必要があります。"とゆーことは、max_poolを増やしても接続数を増やすことは難しそうですね。一つのDBの接続を増やしたい場合は、num_init_childrenの値を増やす方が良さそうですね。

レプリケーションモード

ノードを切り離して縮退運転

replication_stop_on_mismatch, failover_if_affected_tuples_mismatchなど、ノードの切り離しをおこなうポイントはいくつかあるようですね。
replication_stop_on_mismatchの場合、"各DBノードから送られてくるパケットの種類が不一致になった場合"とのことです。UPDATEの成功、失敗といった不一致で切り離されるという部分は覚えておきます。
failover_if_affected_tuples_mismatchの場合、"各DBノードで実行されたINSERT/UPDATE/DELETEの結果行数が不一致になった場合"とのことです。結果行数という部分は覚えておきます。疑問なのが、各DBノードの結果が全て帰ってくるまで、pgpoolからのレスポンスは返さないものなのでしょうか?とっととレスポンスは返してノードの切り離しの判定だけ別でやるのでしょうか。でもそうすると、トランザクションの考え方が崩れてしまいますかね。うーん、この辺りはどうなんでしょう。全てのノードがレスポンスを返すのを待っているとノードの数が増えてくるとレスポンスが遅くなって仕方ないですね。
切り離し対象は、少数派とのこと。3ノードあった場合、全て結果が異なっていた場合どうなるのかちょっと気になります。うーん。

リカバリー系の設定

recovery_user, recovery_password, recovery_1st_stage_command, recovery_1st_stage_command, recovery_timeout, client_idle_limit_in_recoveryこれらを正しく設定する必要があるようですね。

クライアント認証(HBA)のための pool_hba.conf 設定方法

pgpoolでもクライアント認証設定できるんですね。そこまでやる必要があるかは不明ですが。

pgpool-IIの起動と停止

-Dオプションによる状態を復元をしない起動

pgpool_statusを設定してからpgpoolの再起動がうまくいかなくなるということがありました。その場合は、このオプションを指定して状態を復元しないというのも手なのですね。今までは、stopした後直接手でファイルを削除してstartしてました。

pgpool_statusを参照しながらおこなうシーケンス

pgpool_statusを使った動作が説明されていますね。
DBが異常な状態になったときに、どこまでこのシーケンスが信頼できるものなのでしょうか。pgpool経由で正常なDBを更新とありますが、どれが正常なDBであるかどうやって判断するのかなど少々気になります。

pgpool-IIの起動と停止

-nオプションを使用してログ出力

"-n"オプションは、pgpoolをデーモンモードで起動させないようにするオプションです。デーモンで起動してしまうと、ログが表にでてこないようですね。このオプションを使用して、ファイルにログ出力することができます。以下は、rotatelogを経由させつつログ出力しています。

pgpool -n 2>&1 | rotatelogs -l -f var/log/pgpool/pgpool.log.%Y%m%d 86400

SHOWコマンド

このコマンドで参照できる値は有用なものが多いのですが、自分の環境ではなぜかpool_statusしか参照できませんでした。このコマンドのいくつかの情報は、pcpコマンドで代用できるような気がします。pcpコマンドに関しては、下方のリファレンス部分に記載されています。

オンラインリカバリ

リカバリするノードのPostgreSQLはシャットダウンする

リカバリするのに邪魔になるようですね。当然と言えばとうぜんですね。pgpoolのみ起動しておき、PostgreSQLは停止するように気をつけます。

オンラインリカバリを 2 段階に分けて実施します

オンラインリカバリの全体の流れは覚えておきます。それにしても、ファーストステージの実行前にチェックポイントを実行してるとは言え、接続をリードオンリーにするなどの手順が入っていないのが気になります。ファーストステージでコピー処理を実行する前に入っているのかもしれません。
セカンドステージで、ファーストステージ以降で実行された更新処理が実行されるんですね。ファーストステージ前に接続を切断していなかったためどうするのか気にあるところでした。

オンラインリカバリの制限事項

"複数のホストに pgpool を 配置してレプリケーションさせている場合には、オンラインリカバリは正 しく動作しません。"ん?これはどゆことでしょう。pgpoolを複数のサーバに配置してはいけないなんてことはないですよね。オンラインリカバリをする際には、pgpoolの接続形態を切り替える必要があるということなのでしょうか?更新リクエストがあるとデータ同期できないということですので、リカバリを行う時にはDBのエンドポイントを一つにしておく必要がありそうですね。うーん、それは面倒ですね。pgpool同士は横の繋がりがないから仕方ないのかもしれませんね。ん?本当に繋がりないんでしたっけ?

C 言語関数のインストール

これ忘れててイタイ目みました。pgpoolをインストールした際は忘れずインストールするようにします。

リカバリスクリプトの配置

"リモートから postmaster を再起動 させるためのスクリプトを各ノードの $PGDATA 以下に配置します。"これも忘れてて痛い目みました。なぜか、binディレクトリの配下においてました。

PITR によるリカバリ

そもそも、PITR自体をしっかり理解していない気がします。そのため、WALから学んでPITRについて勉強しなおします。

WAL(Write Ahead Logging)

PostgreSQL関連情報
■2-10■ WALの詳細
これらのページでWALについて理解しなおしました。大雑把に言ってしまうと、異常事態に備えてまず変更のログ分だけ書き出すというイメージでしょうか。また、WALの機構を支えるためには変更のログだけではなくコミット情報やチェックポイントの情報も必要なわけですね。当然と言えば当然ですね、保存系の機構ならばファイル書き込みに関する情報は一通り必要なはずですから。

PITR(Point in time recovery)

"ポイント・イン・タイム・リカバリ (PITR) | Let's Postgres"
"25.3. 継続的アーカイブとポイントインタイムリカバリ(PITR)"
これらのページでPITRについて理解しなおしました。PITRは文字通りある時点までのリカバリーですね。そのため、WALの機構やそのログを使用して実現されていることがよくわかりました。

ファーストステージとセカンドステージ、そしてリモートスタート

リカバリーは2段階でおこなうようになっているようです。recovery.confを使用しているので、PITRのリカバリーの機構を使用しているのがわかります。

リカバリの実行

書いてありますが、確かにタイムアウトには注意しないと面倒なことになりますね。

バックアップ

レプリケーションモードで使用しているので、バックアップを実行するならリカバリーでそっくりそのまま作った方が早いような気はします。。

pgpool-IIの配置について

Webサーバやアプリケーションサーバと同居

やっぱりレプリケーションモードでリカバリーを実行する場合は起動するpgpoolは一つにする必要があるようですね。注意書きがありますね。

pgpool-HAについて

HAの導入も考えなければいけないかもです。

トラブルシューティング

自分は列挙されているエラー出力にはまだ遭遇していませんが、確かに遭遇してもおかしくないものであるように思います。一度読んで頭に入れておくのが良さそうです。ノード間のデータ整合性がなくなった場合に起こる問題が多く記載されているところからすると、何らかの理由でデータ整合性が崩れることは普通なことなのかも知れません。

チュートリアル

チュートリアルがあるとは知りませんでした。ロギングの方法が記載されていたため、早めに目を通すべきでした。このリンクは出来ればページの初めの方に欲しいですね。