我目前正在build立一个新的Debian(6.0.5)服务器。 我昨天把仙人掌(0.8.7克)放在它上面,并从那以后一直与之作战。
我观察的最初的问题是,我的图表没有更新。 所以我检查了我的cacti.log ,发现这个消息:
POLLER: Poller[0] Maximum runtime of 298 seconds exceeded. Exiting.
那不好,对吧? 所以我去检查并开始自己的poller.php (通过sudo -u www-data php poller.php --force )。 它会抽出大量的消息(这些消息都看起来像我所期望的)然后挂起一分钟。 之后1分钟,它会循环下面的消息:
Waiting on 1 of 1 pollers.
这会持续4分钟,直到这个过程被强制结束运行超过298秒。
我花了好一个小时试图确定什么样的轮询可能仍然在运行,直到我得出结论,根本没有轮询者 。
我检查了poller.php ,看看这个警告是如何发出的,为什么。 在第368行,Cacti将从数据库中检索已完成进程的数量,并使用该值来计算还有多less进程正在运行。 那么,让我们看看这个价值!
我将下面的debugging代码添加到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开始的一秒钟内打印出以下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()应该总是返回一个结果行,不是吗?)
所以我进入lib\database.php ,看看那个db_fetch_cell() 。 一些testing证实,结果集实际上是空的。
所以我在那里添加了自己的数据库查询代码,看看会做什么:
$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.
那么,数据在那里,可以被访问没有任何问题,只是没有与方法仙人掌正在使用?
我启用MySQL日志logging,以确保我没有想象的东西。 果然,当错误消息循环播放时, 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'"
但是这些查询都没有被MySQLlogging。 但是,当我添加我自己的数据库查询代码时,它显示得很好。

点击放大
这到底是怎么回事?
我的结论是,数据库连接必须在这个过程中丢失的地方,adodb根本不在乎。
所以经过一番挖掘之后,我终于把debugging信息放在了drivers/adodb-mysql.inc.php ,第529行,在_close函数中。 我想看看连接何时closures。
我实际上(最后)打开了PHPdebugging,并实现了mysql_query()被调用了一个布尔连接id(一个有意closures连接的指示器)。
// 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
现在我太累了,无法调查…
我进一步调查了一下,意识到与数据库连接的closures是有意的。 连接应该重新build立,用于下次轮询运行。 但事实并非如此。
以下是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); }
现在,轮询器运行时没有任何警告,我的graphics正在绘制。 但是,还有一个问题。 并不是所有的graphics都能正确绘制,如下图所示:

点击放大
我以为这是由于轮询者对某些数据源运行得太less。 为了解决这个问题,我切换到脊柱 (我想要做的),并将其设置为使用4个线程。

到现在为止还挺好…
我深入研究这个问题,并认为我已经解决了这个问题。 我假设在连接尝试重新连接后没有正确存储连接。
我试图解决这个看起来很有希望,但结果图仍然是错误的。 所以问题就在于更深层次。
我早些时候开发的解决方法,在这个答案中提出的仍然完美。 我决定不再投入更多的时间来解决这个问题,并保持解决方法。 抱歉。