Muchas veces, puede que tengamos una aplicación no muy bien depurada en nuestro servidor web. A dicha aplicación le hemos dado su propio usuario MySQL y observamos que las conexiones no se cierran adecuadamente.
Temporalmente puede que la solución sea expulsar de vez en cuando todos los usuarios que siguen activos, con el fin de no saturar nuestro servidor MySQL. Puede que en otros servicios que tengamos activos hayamos visto el mensaje "Too many connections" impidiendo así el acceso a los demás servicios.
La primera detección del problema la podemos hacer gracias al comando "SHOW PROCESSLIST" de MySQL:
Como vemos, tenemos los usuarios gooduser y gooduser2, que son buenos, usan la base de datos y no dan problemas. Luego tenemos root, que soy yo ahora mismo, pidiendo el listado de procesos y un montón de veces ha entrado eviluser, que además vemos que tiene conexiones abiertas desde hace mucho tiempo, la columna Time nos devuelve la cantidad de segundos que el hilo lleva en el mismo estado, lo que puede indicar una conexión no cerrada adecuadamente.
Diseño del script
Aunque podemos utilizar un bucle en MySQL, he preferido hacerlo con un script en bash que va matando uno a uno los procesos. Tal vez sea la forma más lenta de hacerlo, pero no tenemos que meter un procedure en el servidor MySQL para ejecutarlo, y copiando y pegando el código desde la página nos vale.
Script rápido
De esta forma podremos expulsar los usuarios que hay actualmente conectados. Veamos detenidamente las opciones de línea de comandos para este script.
- -user y -pass : Eso está claro, ¿no?
- -socket : Especifica el socket unix con el que vamos a conectar, puede que tu base de datos no esté escuchando ningún puerto en nuestro host y tengamos que conectar de esta forma.
- -host : En cualquier caso, si no conectamos por socket, debemos conectar por host, así que uno de los dos debe estar especificado.
- -kick : Usuario que queremos expulsar, en nuestro caso eviluser.
- -time : Tiempo mínimo sin dar señales de vida. Es decir, el tiempo que lleva la conexión sin cambiar de estado. El script, por defecto señala un tiempo mínimo de 600 segundos (10 minutos), aunque podemos variarlo, incluso poner 0 para no especificar tiempo.
Hay que tener en cuenta que si no especificamos usuario y pedimos que el tiempo sea 0, preguntará si de verdad queremos echar a todos los usuarios actuales del sistema.
Requerimientos
Como mínimo necesitamos MySQL 5.1.7 porque es cuando introdujeron la opción de consultar el listado de procesos desde la base de datos information_schema.
Y bash 4 o superior, por la pregunta al usuario cuando el tiempo es 0 y no hemos metido usuario. Si quitamos esa parte, podría funcionar sin problema con versiones muy antiguas de Bash.
Más referencias
Resultado de un SELECT de MySQL en un array de BASHFoto principal: TheGlantVermin