現在、新しい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";
_
これにより、_poller.php
_を開始してから1秒以内に以下が出力されます。
_Finished: 0 - Started: 1
Waiting on 1 of 1 pollers.
Finished: 1 - Started: 1
_
したがって、値は読み取られており、有効です。 Untilループが続く部分に到達します:
_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
_は、madのようにクエリを実行しているかのように読み取ります。
_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'"
_
ただし、これらのクエリのnoneはMySQLによって記録されます。それでも、自分のデータベースクエリコードを追加すると、問題なく表示されます。
ここで一体何が起こっているのですか?
データベース接続はプロセスのどこかで失われる必要があり、adodbは単に気にしないと結論付けました。
少し調べた後、デバッグメッセージを_drivers/adodb-mysql.inc.php
_関数の__close
_、529行目に配置しました。接続がいつ閉じられるかを確認したいと思いました。
私は実際に(最終的に)オンにしました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
_
そして今、私はそれを調査するのに疲れすぎています...
私はもう少し調査しましたが、データベースへの接続を閉じることは意図的なものであることに気付きました。接続は、次のポーリング実行のために再確立する必要があります。しかし、そうではありません。
これは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);
}
これでポーラーは警告なしで実行され、グラフが描画されます。しかし、まだ問題があります。次の画像からわかるように、すべてのグラフが適切に描画されているわけではありません。
これは、特定のデータソースではポーラーがほとんど実行されないことが原因であると思いました。それを解決するために、私は spine (とにかくやりたかった)に切り替えて、4つのスレッドを使用するように設定しました。
ここまでは順調ですね...
私はこの問題をより深く掘り下げ、修正したと思いました。ポーラーの再接続試行後、接続が適切に保存されていないと想定しました。
それを解決する私の試みは最初は有望に見えましたが、結果のグラフはまだ不完全でした。したがって、問題はより深いところにあります。
以前に開発し、この回答で示した回避策はまだ完全に機能します。私はこの問題にこれ以上の時間を投資せず、回避策を続けることにしました。ごめんなさい。