Cactiはなぜデッドポーラープロセスを待機し続けるのですか?


11

現在、新しいDebian(6.0.5)サーバーをセットアップしています。私は昨日サボテン(0.8.7g)を入れて以来、それと戦っています。

新規作成

私が観察していた最初の問題は、グラフが更新されないことでした。だから私は私をチェックし、cacti.logこれに関するメッセージを見つけました:

POLLER: Poller[0] Maximum runtime of 298 seconds exceeded. Exiting.

それは良くありませんね?それで私はチェックに行き、poller.php(を介してsudo -u www-data php poller.php --force)自分で始めました。それは多くのメッセージ(すべて私が期待するもののように見えます)を送り出してから、1分間ハングします。その1分後、次のメッセージがループします。

Waiting on 1 of 1 pollers.

これは、プロセスが強制的に終了して298秒より長く実行されるまで、さらに4分間続きます。

ここまでは順調ですね

実行中のポーラーがないという結論に至るまで、私は良い時間を過ごして、まだ実行中のポーラーを特定しようとしました。

デバッグ中

poller.phpはその警告がどのように発行されるのか、そしてその理由を確認しました。368行目で、Cactiはデータベースから終了したプロセスの数を取得し、その値を使用して、まだ実行されているプロセスの数を計算します。だから、その値を見てみましょう!

次のデバッグコードをに追加しましたpoller.php

$finished_processes = db_fetch_cell("SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'");
print "Finished: " . $finished_processes . " - Started: " . $started_processes . "\n";

結果

これにより、開始から1秒以内に以下が出力されますpoller.php

Finished: 0 - Started: 1
Waiting on 1 of 1 pollers.
Finished: 1 - Started: 1

したがって、値は読み取られており、有効です。ループし続ける部分に到達するまで

Finished:  - Started: 1
Waiting on 1 of 1 pollers.

突然、その価値はなくなります。どうして?var_dump()そこに置くことは問題を確認します:

NULL
Finished:  - Started: 1
Waiting on 1 of 1 pollers.

戻り値はNULLです。クエリするとどうなりSELECT COUNT()...ますか?(SELECT COUNT()常に1つの結果行を返す必要がありますか?)

より多くのデバッグ

それで私は入りlib\database.php、それを見ましたdb_fetch_cell()。テストの結果、結果セットは実際には空であることが確認されました。

そこで、自分のデータベースクエリコードを追加して、それが何をするかを確認しました。

$finished_processes = db_fetch_cell("SELECT count(*) FROM poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'");
print "Finished: " . $finished_processes . " - Started: " . $started_processes . "\n";

$mysqli = new mysqli("localhost","cacti","cacti","cacti");
$result = $mysqli->query("SELECT COUNT(*) FROM poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00';");
$row = $result->fetch_assoc();
var_dump( $row );

これは出力されます

Finished:  - Started: 1
array(1) {
  ["COUNT(*)"]=>
  string(1) "2"
}
Waiting on 1 of 1 pollers.

それで、データはそこにあり、Cactiが使用している方法ではなく、問題なくアクセスできますか?

それを再確認してください!

MySQLのロギングを有効にして、想像できないことを確認しました。案の定、エラーメッセージがループされると、cacti.log読み取りは、まるで怒っているかのようにクエリを実行するかのように読み込まれます。

06/29/2012 08:44:00 PM - CMDPHP: Poller[0] DEVEL: SQL Cell: "SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'"
06/29/2012 08:44:01 PM - CMDPHP: Poller[0] DEVEL: SQL Cell: "SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'"
06/29/2012 08:44:02 PM - CMDPHP: Poller[0] DEVEL: SQL Cell: "SELECT count(*) FROM cacti.poller_time WHERE poller_id=0 AND end_time>'0000-00-00 00:00:00'"

しかし、これらのクエリはいずれも MySQLによって記録されません。それでも、自分のデータベースクエリコードを追加すると、問題なく表示されます。

ここに画像の説明を入力してください
拡大するにはクリックしてください

ここで一体何が起こっているのですか?

深く掘り下げています...

データベース接続はプロセスのどこかで失われる必要があり、adodbは単に気にしないと結論付けました。

そのため、少し調べた後、デバッグメッセージを関数のdrivers/adodb-mysql.inc.php529行目に配置しました_close。接続がいつ閉じたかを確認したかったのです。

私は実際に(最終的に)PHPデバッグをオンにmysql_query()し、ブール接続ID(意図的に閉じられた接続のインジケーター)で呼び出されていることに気付きました。

// returns true or false
function _close()
{
    @mysql_close($this->_connectionID);
    echo "!!!! CLOSED !!!!\n";
    debug_print_backtrace();
    $this->_connectionID = false;
}

それは何を印刷しますか?

oliver@j27773:/etc/php5/conf.d$ sudo -u www-data php /usr/share/cacti/site/poller.php --force
06/30/2012 01:33:49 AM - POLLER: Poller[0] NOTE: Poller Int: '60', Cron Int: '300', Time Since Last: '61', Max Runtime '298', Poller Runs: '5'
06/30/2012 01:33:49 AM - POLLER: Poller[0] DEBUG: About to Spawn a Remote Process [CMD: /usr/bin/php, ARGS: -q "/usr/share/cacti/site/cmd.php" 0 3]
Finished: 0 - Started: 1
Waiting on 1 of 1 pollers.
Finished: 1 - Started: 1
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_sb_keepalive_100.rrd --template apache_sb_keepalive 1341012829:0
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_reqpersec_95.rrd --template apache_reqpersec 1341012829:.0228409
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_bytesperreq_90.rrd --template apache_bytesperreq 1341012829:13925.7
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_cpu_85.rrd --template cpu 1341012829:1
OK u:0.00 s:0.00 r:1.00
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_hdd_used_80.rrd --template hdd_used:hdd_total 1341012829:924741632:2677886976
OK u:0.00 s:0.00 r:1.00
OK u:0.00 s:0.01 r:1.00
OK u:0.00 s:0.01 r:1.00
06/30/2012 01:33:50 AM - POLLER: Poller[0] CACTI2RRD: /usr/bin/rrdtool update /var/lib/cacti/rra/j27773_servers_jiffybox_net_apache_sb_wait_105.rrd --template apache_sb_wait 1341012829:9
OK u:0.00 s:0.01 r:1.00
OK u:0.00 s:0.01 r:1.00
06/30/2012 01:33:50 AM - SYSTEM STATS: Time:1.1261 Method:cmd.php Processes:1 Threads:N/A Hosts:2 HostsPerProcess:2 DataSources:7 RRDsProcessed:6
Loop  Time is: 1.1291718482971
Sleep Time is: 58.867464065552
Total Time is: 1.1325359344482
!!!! CLOSED !!!!
#0  ADODB_mysql->_close() called at [/usr/share/php/adodb/adodb.inc.php:2141]
#1  ADOConnection->Close() called at [/usr/share/cacti/site/lib/database.php:68]
#2  db_close() called at [/usr/share/cacti/site/poller.php:455]
^C06/30/2012 01:33:55 AM - CMDPHP: Poller[0] WARNING: Cacti Master Poller process terminated by user

そして今、私はそれを調査するのに疲れすぎています...

回答:


6

私はもう少し調査しましたが、データベースへの接続のクローズは意図的なものであることに気付きました。接続は、次のポーリング実行のために再確立する必要があります。しかし、そうではありません。

ここからの抜粋ですpoller.php

if ($poller_runs_completed < $poller_runs) {
    db_close();
    // Debug message by myself
    echo "RECONNECTING IN " . $sleep_time . "\n";
    usleep($sleep_time * 1000000);
    db_connect_real($database_hostname, $database_username, $database_password, $database_default, $database_type, $database_port);
}

私もチェックdb_connect_realしましたが、実際にはusleep完了後に呼び出されます。だから私は掘り続けます。

とりあえず、このセクションを次のように変更しました。

if ($poller_runs_completed < $poller_runs) {
    //db_close();
    // Debug message by myself
    echo "RECONNECTING IN " . $sleep_time . "\n";
    usleep($sleep_time * 1000000);
    //db_connect_real($database_hostname, $database_username, $database_password, $database_default, $database_type, $database_port);
}

これでポーラーが警告なしで実行され、グラフが描画されます。しかし、まだ問題があります。次の画像からわかるように、すべてのグラフが適切に描画されているわけではありません。

回避策の結果を示すレンダリングされたグラフ
拡大するにはクリックしてください

これは、特定のデータソースに対してポーラーがほとんど実行されないことが原因であると考えました。それを解決するために、とにかくやりたかった脊椎に切り替えて、4つのスレッドを使用するように設定しました。

サボテンポーラーの設定

ここまでは順調ですね...

更新

私はこの問題をより深く掘り下げ、修正したと思いました。ポーラーの再接続試行後、接続が適切に保存されていないと想定しました。

それを解決する私の試みは最初は有望に見えましたが、結果のグラフはまだ不完全でした。したがって、問題はより深いところにあります。

以前に開発し、この回答で示した回避策はまだ完全に機能します。私はこの問題にこれ以上の時間を投資せず、回避策を続けることにしました。ごめんなさい。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.