Este artículo explica cómo configurar el plugin "mysql" de collectd para recolectar estadísticas del servidor de bases de datos y el motor InnoDB.

En la serie de artículos anteriores he explicado cómo compilar y configurar collectd en Debian para almacenar métricas en una base de datos InfluxDB y cómo graficar métricas desde una base InfluxDB en Grafana. Este esquema me permite generar gráficas de monitoreo de actividad de servidores Nginx, Apache, etc. Veamos ahora cómo configurar collectd para generar estas mismas gráficas, pero con el objetivo de monitorear la actividad sobre un servidor de bases de datos MySQL.



Si la instalación de collectd no posee soporte para MySQL, será necesario compilar collectd agregando la opción --enable-mysql. Este plugin requiere contar con la librería del cliente de MySQL (libmysqlclient.so) a fin de poder conectarse a motores de bases de datos MySQL para recolectar estadísticas. Esta librería está incluida por defecto en la mayoría de las instalaciones de MySQL.

Por cierto, en mi perfil de GitHub dejé un script de configuración, compilación e instalación automática de collectd: linuxitux/scripts/Devuan/install-collectd.bash.

Si se ha compilado una versión específica de MySQL, y se ha instalado en una ruta personalizada, es muy probable que el plugin compile correctamente pero luego no funcione:

Oct 23 12:56:58 mydb collectd[4109]: dlopen ("/usr/local/collectd/lib/collectd/mysql.so") failed: libmysqlclient.so.18: cannot open shared object file: No such file or directory. The most common cause for this problem is missing dependencies. Use ldd(1) to check the dependencies of the plugin / shared object.

Sin embargo, al verificar con ldd la librería libmysqlclient.so.18 enlaza correctamente:

[root@mydb ~]# ldd /usr/local/collectd/lib/collectd/mysql.so 
        linux-vdso.so.1 =>  (0x00007ffe8c8a3000)
        libmysqlclient.so.18 => /usr/lib64/libmysqlclient.so.18 (0x00007f2da7120000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f2da6f03000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f2da6c7e000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f2da6a76000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f2da6872000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f2da64dd000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f2da61d7000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f2da5fc1000)
        /lib64/ld-linux-x86-64.so.2 (0x00005594381e0000)

Por alguna razón la llamada a dlopen() en el plugin "mysql" ignora la configuración en las variables de entorno PATH y LD_LIBRARY_PATH. Con lo cual, la solución más simple consiste en crear un simple enlace simbólico a la librería en una ruta conocida como /usr/lib64.

Configurar collectd

Editar la configuración de collectd:

# cd /usr/local/collectd/etc/
# nano collectd.conf

Habilitar el plugin "mysql":

LoadPlugin mysql

Debajo, configurar el plugin "mysql" para que recolecte estadísticas del servidor MySQL local:

<Plugin mysql>
  <Database local>
    Database "test"
    User "collectd"
    Password "trustno1"
    Socket "/tmp/mysql.sock"
    InnodbStats true
  </Database>
</Plugin>

La base de datos se utiliza sólo como parámetro en la conexión, sin embargo no se requiere ningún privilegio sobre la misma. La conexión con el motor puede ser a través del socket Unix o a través de TCP/IP sobre el puerto 3306.

Configuración de MySQL

La configuración de MySQL se reduce a crear un usuario y otorgarle permisos para recolectar métricas de InnoDB.

Conectarse al motor con el cliente de línea de comandos mysql autenticando como superusuario:

[root@mydb ~]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 678
Server version: x.y.z Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

Crear el usuario "collectd" con contraseña "trustno1"

mysql> CREATE USER 'collectd'@'localhost' IDENTIFIED BY 'trustno1';
Query OK, 0 rows affected (0,11 sec)

Si se desean recolectar métricas del motor InnoDB es necesario que el usuario tenga privilegios PROCESS:

mysql> GRANT PROCESS ON *.* TO 'collectd'@'localhost';
Query OK, 0 rows affected (0,05 sec)

El privilegio PROCESS se requiere para que el plugin "mysql" pueda recolectar estadísticas de InnoDB. Recupera datos de la tabla information_s chema.innodb_metrics.

Cerrar la sesión en el motor:

mysql> quit
Bye

Finalmente, iniciar (o reiniciar) collectd:

# service collectd stop
# service collectd start

Graficar los datos en Grafana

Estas son algunas consultas InfluxQL de ejemplo para graficar métricas de MySQL:

Consultas SELECT:

SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'mysql_commands' AND "type_instance" = 'select') AND $timeFilter GROUP BY time($__interval) fill(null)

Consultas INSERT:

SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'mysql_commands' AND "type_instance" = 'insert') AND $timeFilter GROUP BY time($__interval) fill(null)

Consultas UPDATE:

SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'mysql_commands' AND "type_instance" = 'update') AND $timeFilter GROUP BY time($__interval) fill(null)

Hilos:

SELECT mean("value") FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'threads' AND "type_instance" = 'connected') AND $timeFilter GROUP BY time($__interval) fill(null)
SELECT mean("value") FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'threads' AND "type_instance" = 'running') AND $timeFilter GROUP BY time($__interval) fill(null)

Métricas de InnoDB:

SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'mysql_innodb_data' AND "type_instance" = 'reads') AND $timeFilter GROUP BY time($__interval) fill(null)
SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'mysql_innodb_data' AND "type_instance" = 'writes') AND $timeFilter GROUP BY time($__interval) fill(null)
SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'mysql_innodb_data' AND "type_instance" = 'fsyncs') AND $timeFilter GROUP BY time($__interval) fill(null)
SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'operations' AND "type_instance" = 'adaptive_hash_searches') AND $timeFilter GROUP BY time($__interval) fill(null)
SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'operations' AND "type_instance" = 'dml_inserts') AND $timeFilter GROUP BY time($__interval) fill(null)
SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'operations' AND "type_instance" = 'dml_reads') AND $timeFilter GROUP BY time($__interval) fill(null)
SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'operations' AND "type_instance" = 'dml_updates') AND $timeFilter GROUP BY time($__interval) fill(null)

Consultas lentas (slow queries):

SELECT derivative(mean("value"), 10s) FROM "mysql_value" WHERE ("host" = 'mydb.linuxito.com' AND "instance" = 'mydb' AND "type" = 'mysql_slow_queries') AND $timeFilter GROUP BY time($__interval) fill(null)

Referencias


Tal vez pueda interesarte


Compartí este artículo