pgpool-IIのオンラインリカバリ機能と格闘中
PostgreSQL, pgpool August 6th, 2008
いろいろ気づいたことのメモ。
まずは目玉機能のオンラインリカバリについて。プロジェクトのページによれば
1. CHECKPOINT 実行
2. ファーストステージの実施
3. 接続がすべて切断されるまで待機
4. CHECKPOINT 実行
5. セカンドステージの実施
6. postmaster の起動(pgpool_remote_start の実行)
7. ノードの復帰
という手順でリカバリされるのだが、手元の環境でまず引っかかったのが3の「接続がすべて切断されるまで待機」のところ。というのも、pgpool-IIにpgpoolを経由して接続するという変な環境だったのだが、child_life_timeを0に設定していたために接続がいつまで経っても切れずにここで失敗してしまったのだ。
で、pgpool-IIのソース(現時点でrev.1.21)を調べると(これは会社の同僚がやっていた)、まだ接続が切れていなければ3秒待ってから最大30回ループすることになっている。
/*
* Wait all connections are closed.
*/
static int wait_connection_closed(void)
{
int i = 0;
do {
if (Req_info->conn_counter == 0)
return 0;
if (WAIT_RETRY_COUNT != 0)
sleep(3);
} while (i++ < WAIT_RETRY_COUNT);
pool_error("wait_connection_closed: existing connections did not close in %d sec.", pool_config->recovery_timeout);
return 1;
}
なぜかしびれた。これはプログラム内に意味深な数字を見つけたときのプログラマの健康な反応なのだろう。まあ、根拠はよくわからないが、まあそういう数字であると。ふむふむ。
で、接続元がpgpoolだとコネクションを張りっぱなしになるのでこのループで終了してしまう。負荷の高いサービスだと、pgpool経由でpgpoolにつないだ状態では、child_life_timeを下げてもなかなかチャンスがこないかもしれない。というわけで現在ここを試験中。
接続の問題が解消されると、あっさり動作した。PostgreSQLは7系なのでrsyncで動作している。