Posts tagged with “bash”
Almacenar fecha y hora de los picos de conexiones en MySQL
Cuando un cliente te pregunta cual ha sido el mayor pico de conexiones recibido es facil de responder:
mysql> show status like '%max_used%'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | Max_used_connections | 341 | +----------------------+-------+ 1 row in set (0.00 sec)
Pero si el cliente te pregunta cuando, no tienes ningún dato que darle, ya que MySQL no guarda ese dato. Aquí voy a presentaros dos formas de hacerlo, una más elegante pero que os llevará algo más de trabajo y una menos elegante pero más facil de implantar.
La elegante
La primera, la elegante, nos la trae el blog systemadmin.es. Se trata de un parche para la versión 5.1 que le permite a MySQL guardar no solo el pico de conexiones, si no el timestamp en el cual ocurrió. Nos añade un nuevo estado llamado Max_used_connections_ts en el que almacenará el timestamp :)
mysql> show status like 'Max_used%'; +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | Max_used_connections | 27 | | Max_used_connections_ts | 1296037707 | +-------------------------+------------+ 2 rows in set (0.00 sec)
El parche, descargable desde systemadmin.es se aplica como cualquier otro:
cd mysql-5.1.53 patch -p1 < ../patch.mysql.51.max_used_connections_ts.patch
Una vez compilado y puesto en marcha tendremos un dato más que ofrecer al cliente sobre el funcionamiento de su plataforma.
La menos elegante
La menos elegante es cosa mia :P Lo bueno que tiene es la rápida implantación. Si tienes que conocer la fecha y hora de los picos en una instalación con 100 MySQL, posiblemente termines antes así:
#!/bin/bash USER="root" PASS="xxxx" LOG="/tmp/mysql_top" if [ -e $LOG ]; then ANTES=\`cat $LOG\` else ANTES=0 fi AHORA=\`mysql -u$USER -p$PASS -e "show status like 'Max_used_connections';" | awk -F '|' '{ print $1 }' | awk '{ print $2 }' | tail -n1\` if [ $AHORA -gt $ANTES ]; then logger "$AHORA conexiones maximas de MySQL" echo "Se ha superado el pico de conexiones el" \`date\` "con $AHORA" echo $AHORA > $LOG exit 1 else echo "El pico de conexiones se mantiene" exit 0 fi
En resumen, es un script que si detecta una subida en la variable lo logea en syslog y muestra un mensaje por STDOUT. De esta forma, te sirve tanto como tarea programada en CRON para llevar un histórico, como script NRPE de Nagios gracias a los exit codes ;)
Monitorizar la replicación de Mysql
Imaginemos que tenemos una infraestructura Maestro/Esclavo y el esclavo lo usamos para lecturas, backup o simplemente para dar un servicio mínimo si el Maestro se cae. Imaginemos que dicha replicación lleva caída un mes y el Maestro se rompe. Cuando te das cuenta es demasiado tarde y entonces toca imaginarse como huir sin que te pillen :)
Monitorizar si la replicación es correcta es sencillo, ya que MySQL nos puede dar en segundos el desfase que existe entre un host y otro a la hora de replicar los cambios. Con "SHOW SLAVE STATUS\G" tendremos la información que necesitamos:
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.60.1.3
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000021
Read_Master_Log_Pos: 327326
Relay_Log_File: mysqld-relay-bin.000061
Relay_Log_Pos: 327463
Relay_Master_Log_File: mysql-bin.000021
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 327326
Relay_Log_Space: 327463
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Cada entrada en el log lleva un timestap indicando el momento exacto en el que es escrito en el Master. Por lo tanto, el "Seconds_behind_master" hace una simple resta, entre nuestro timestamp y el del master para saber la diferencia.
Dicho esto, la solución es tan sencilla como tirar de Bash Scripting:
#!/bin/sh
treshold=1200
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
if [ -z $1 ] ; then
echo "Usage: $0 /path/to/mysql.sock"
exit 255
fi
seconds=mysql -S $1 -N -e "show slave status\G" | grep Seconds_Behind_Master | cut -d: -f 2
if [ -z $seconds ] ; then
exit 255
fi
if [ $seconds = "NULL" ]; then
echo Replication kaput!!!
exit 255
fi
if [ $seconds -gt $treshold ]; then
echo Slave behind the master more than $treshold seconds!
fi
Pero claro, antes de realizar estas comprobaciones se deben tener en cuenta una serie de requisitos previos:
- Los equipos deben tener la hora sincronizada :)
- A poder ser, deben estar LAN. Si tenemos una WAN con mucha latencia y encima microcortes, olvídate de esto.
Si se busca en internet hay múltiples formas de hacerlo, pero esta es la más sencilla. Y si le añadimos algun "exit 0" y "exit 1" tenemos un checker para Nagios :P Y también es recomendable añadir otro grep más para comprobar si los threads SQL e IO están en funcionamiento (Slave_IO_Running, Slave_SQL_Running)...
Si Mikel, esta entrada va por ti xD







