[pgpool-general-jp: 1041] 子プロセスがゾンビ状態で残留する

Naoya Anzai anzai-naoya @ mxu.nes.nec.co.jp
2012年 4月 13日 (金) 17:27:59 JST


安西と申します。

pgpool-IIをコネクションプールソフトとして使用した環境において、
pgpool-IIのストールが発生しましたのでご報告いたします。

● 構成

   < RHEL 5 >                       < RHEL 5 >
  pgpool-II(3.0.3) ----ipv4----- PostgreSQL(8.4.5)
  ---主な設定---
  num_init_children=100
  connection_cache=true
  child_life_time=300
  --------------

● 現象

上記の環境で、以下の現象が発生しています。

ネットワークを不通にした状態でPostgreSQLを再起動し、
ネットワークを復旧させてしばらくすると<defunct>プロセスが
徐々に増加していきます。

どうやら、
ネットワーク不通のエラーを検知した子プロセスによるfailover依頼が
同時に発生したことで、半永久的なセマフォのロック待ちによる
pgpool-IIのストールが発生しているようです。

● 発生手順

今回発生した現象は、以下の手順で発生します。

(1) ネットワーク断により、複数の子プロセスがエラーを検知
(2) 子プロセス1 : REQUEST_INFO_SEM(セマフォ)を獲得し親プロセスに
                  failover依頼
(3) 子プロセス1 : セマフォを解放
(4) 親プロセス  : シグナルを受信しセマフォを獲得
(5) 親プロセス  : failover処理中に全ての子プロセスに対してSIGQUIT
                  シグナルを発行
(6) 親プロセス  : セマフォを解放
(7) 子プロセスn : セマフォ解放待ちの子プロセスがセマフォ獲得
(8) 子プロセスn : (5)のシグナルを受信しプロセスが終了

上記の場合セマフォが解放されないまま子プロセスが終了(8)し、
以降、セマフォを獲得しようとしたプロセスがストールします。
親プロセスがストールした場合は、シグナルブロックを行なって
いるため、停止させるにはSIGKILLを使用する必要があります。

● 原因

本現象の原因は、子プロセスがREQUEST_INFO_SEM(セマフォ)を獲得
してから解放するまでシグナルのブロックをしていないことにあると
認識しています。以下に子プロセスが問題のセマフォを獲得する
部分を抜粋します。
------main.c:1258〜 (pgpool-II 3.0.3より)
pool_semaphore_lock(REQUEST_INFO_SEM);
Req_info->kind = NODE_DOWN_REQUEST;
for (i = 0; i < count; i++)
{
    if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS ||
        !VALID_BACKEND(node_id_set[i]))
    {
        pool_log("notice_backend_error: node %d is not valid backend.", i);
        continue;
    }

    pool_log("notice_backend_error: %d fail over request from pid %d", node_id_set[i], getpid());
    Req_info->node_id[i] = node_id_set[i];
}
kill(parent, SIGUSR1);
pool_semaphore_unlock(REQUEST_INFO_SEM);
------
現象の確認が出来ているバージョンは3.0.3ですが、ソースを確認
した限りでは最新版でも同様の現象が起こりうると認識しており
ます。ただし、実機では確認しておりません。

以上、よろしくお願い致します。


pgpool-general-jp メーリングリストの案内