Actualmente estoy configurando un nuevo servidor Debian (6.0.5). Puse Cacti (0.8.7g) ayer y he estado luchando con eso desde entonces.
Problema inicial
El problema inicial que estaba observando era que mis gráficos no se actualizaban. Así que revisé mi cacti.log
y encontré este mensaje relacionado:
POLLER: Poller[0] Maximum runtime of 298 seconds exceeded. Exiting.
Eso no puede ser bueno, ¿verdad? Así que fui a verificar y comencé poller.php
yo mismo (vía sudo -u www-data php poller.php --force
). Lanzará muchos mensajes (que se parecen a lo que esperaría) y luego se bloqueará por un minuto. Después de ese 1 minuto, repetirá el siguiente mensaje:
Waiting on 1 of 1 pollers.
Esto continúa durante 4 minutos más hasta que el proceso finaliza por la fuerza por más de 298 segundos.
Hasta ahora tan bueno
Continué durante una buena hora tratando de determinar qué encuestador aún podría estar funcionando, hasta que llegué a la conclusión de que simplemente no hay un encuestador en ejecución .
Depuración
Revisé poller.php
para ver cómo se emite esa advertencia y por qué. En la línea 368, Cacti recuperará el número de procesos terminados de la base de datos y usará ese valor para calcular cuántos procesos aún se están ejecutando. Entonces, ¡veamos ese valor!
Agregué el siguiente código de depuración en 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";
Resultado
Esto imprimirá lo siguiente dentro de un segundo de comenzar poller.php
:
Finished: 0 - Started: 1
Waiting on 1 of 1 pollers.
Finished: 1 - Started: 1
Entonces los valores se leen y son válidos. Hasta que lleguemos a la parte donde sigue girando:
Finished: - Started: 1
Waiting on 1 of 1 pollers.
De repente, el valor se ha ido. ¿Por qué? Poner var_dump()
allí confirma el problema:
NULL
Finished: - Started: 1
Waiting on 1 of 1 pollers.
El valor de retorno es NULL
. ¿Cómo puede ser eso cuando se consulta SELECT COUNT()...
? ( SELECT COUNT()
siempre debe devolver una fila de resultados, ¿no?)
Más depuración
Así que entré lib\database.php
y eché un vistazo a eso db_fetch_cell()
. Un poco de prueba confirmó que el conjunto de resultados está realmente vacío.
Así que agregué mi propio código de consulta de la base de datos para ver qué haría eso:
$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 );
Esto dará salida
Finished: - Started: 1
array(1) {
["COUNT(*)"]=>
string(1) "2"
}
Waiting on 1 of 1 pollers.
Entonces, ¿los datos están ahí y se puede acceder sin problemas, solo que no con el método que Cacti está usando?
¡Verifica eso!
He habilitado el registro de MySQL para asegurarme de que no estoy imaginando cosas. Efectivamente, cuando el mensaje de error se repite, se cacti.log
lee como si estuviera preguntando como loco:
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'"
Pero MySQL no registra ninguna de estas consultas. Sin embargo, cuando agrego mi propio código de consulta de base de datos, aparece muy bien.
¿Qué diablos está pasando aquí?
Cavar más profundo...
Llegué a la conclusión de que la conexión de la base de datos debe perderse en algún lugar del proceso y a adodb simplemente no le importa.
Entonces, después de un poco de investigación, finalmente coloqué el mensaje de depuración en la drivers/adodb-mysql.inc.php
línea 529 de la _close
función. Quería ver cuándo se cierra la conexión.
De hecho (finalmente) activé la depuración de PHP y me di cuenta de que mysql_query()
se llamaba con una identificación de conexión booleana (un indicador de una conexión cerrada intencionalmente).
// returns true or false
function _close()
{
@mysql_close($this->_connectionID);
echo "!!!! CLOSED !!!!\n";
debug_print_backtrace();
$this->_connectionID = false;
}
¿Qué imprime eso?
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
Y ahora estoy demasiado cansado para investigar eso ...