¿Por qué tarda tanto DROP DATABASE? (MySQL)

46

Nueva instalación de CentOS.

Estaba ejecutando una importación de un DB grande (archivo sql de 2GB) y tuve un problema. El cliente SSH pareció perder la conexión y la importación pareció congelarse. Utilicé otra ventana para iniciar sesión en mysql y la importación parecía estar muerta, atascada en una tabla de filas de 3M en particular.

Así que lo intenté

DROP DATABASE huge_db;

15-20 minutos después, nada. En otra ventana, hice:

/etc/init.d/mysqld restart

La ventana DROP DB envió un mensaje: SERVIDOR APAGADO. Luego reinicié el servidor físico.

Volví a iniciar sesión en mysql, verifiqué y el db seguía allí, ejecutó

DROP DATABASE huge_db;

de nuevo, y de nuevo ya estoy esperando unos 5 minutos.

Una vez más, es una instalación nueva. El huge_dbes el único db (que no sea el sistema dbs). Juro que he caído db tan grande antes y rápidamente, pero tal vez me equivoque.

He descartado con éxito la base de datos. Tomó algo así como 30 minutos. También tenga en cuenta que creo que me equivoqué cuando pensé que la importación de mysqldump estaba muerta. Se perdió la conexión del terminal, pero creo que el proceso aún se estaba ejecutando. Lo más probable es que eliminé la tabla media de importación (la tabla de filas de 3M) y probablemente 3/4 del camino a través de toda la base de datos. Fue engañoso que "top" mostrara mysql usando solo el 3% de la memoria, cuando parecía que debería estar usando más.

Dejar caer la base de datos terminó en 30 minutos, por lo que, nuevamente, es posible que no haya tenido que reiniciar el servidor y posiblemente haya esperado a que finalice DROP, pero no sé cómo reaccionaría mysql al obtener una consulta DROP para la misma base de datos que está importando a través de mysqldump.

Aún así, la pregunta sigue siendo, ¿por qué tarda más de 30 minutos en BAJAR una base de datos de 2GB cuando todo lo que debe hacer es eliminar todos los archivos db y eliminar todas las referencias a la base de datos de information_schema? ¿Cual es el problema?

Buttle Butkus
fuente

Respuestas:

73

En lugar de matar el proceso, sería más seguro si lo hicieras dentro de MySQL:

$ mysqladmin processlist -u root -p
Enter password: 
+-----+------+-----------+-------------------+---------+------+-------+------------------+
| Id  | User | Host      | db                | Command | Time | State | Info             |
+-----+------+-----------+-------------------+---------+------+-------+------------------+
| 174 | root | localhost | example           | Sleep   | 297  |       |                  |
| 407 | root | localhost |                   | Query   | 0    |       | show processlist |
+-----+------+-----------+-------------------+---------+------+-------+------------------+

La consulta con el ID 174 es la eliminación de bloqueo de la base de datos 'ejemplo', por lo que antes de eliminar cualquier proceso, primero deje que MySQL intente finalizar la consulta:

$ mysqladmin kill 174

Ejecute el processlistcomando anterior nuevamente para confirmar que se eliminó.

Si esto no funciona, entonces quizás podría considerar matar el proceso errante, pero antes de eso podría intentar reiniciar el servidor MySQL.

También puede ejecutar comandos como 'SHOW FULL PROCESSLIST' y 'KILL 174' en el shell de MySQL, por ejemplo, si solo tiene instalado el cliente MySQL. El punto principal es evitar matar el proceso usando 'kill' en el shell a menos que sea absolutamente necesario.

En términos generales, puede usar cualquiera mysqlo mysqladmin. Sin embargo, no debería necesitar ejecutar comandos como este tan a menudo; una vez que comience a eliminar consultas regularmente, algo definitivamente está mal y sería mejor que solucione ese problema (matar el proceso de consulta es solo tratar el síntoma).

Stefan Magnuson
fuente
1
@BugsBuggy Una forma común en que esto puede ocurrir es si otro proceso (por ejemplo, un servidor web, o en este caso un proceso de importación) se está ejecutando y está conectado a la base de datos. Cuando emita el DROP DATABASEcomando, el servidor no continuará hasta que se hayan cerrado todas las conexiones.
Stefan Magnuson
11

Aunque pensé que el proceso de importación había muerto, probablemente todavía se estaba ejecutando.

El DROP DATABASEcomando probablemente esperó a que la base de datos terminara de importarse antes de ejecutarse.

Entonces, en lugar de DROP DATABASEtomar mucho tiempo, probablemente fue solo la importación.

Si alguien más lee esto e intenta cancelar una importación de la base de datos y descartar la base de datos, le recomiendo que primero encuentre el PID (identificación del proceso) para la importación y lo ejecute desde un terminal diferente:

$ kill [PID]

... donde [PID] sería el PID real para el proceso.

Debería ver la detención de la importación inmediatamente si el otro terminal todavía está conectado.

También puede ejecutar SHOW PROCESSLISTen la pestaña SQL phpMyAdmin. La tabla resultante muestra los procesos en ejecución, y hacer clic en la 'x' al lado de la fila que desea eliminar debería ser el truco.

Entonces corre

DROP DATABASE `database_name`;

Y todo debe estar limpio.


Otra respuesta sugirió que matar el proceso dentro de mysql es mejor que hacerlo desde afuera. No he probado esa respuesta, pero suena muy plausible. Así que lo he marcado como la "respuesta aceptada" en lugar de esta.

Buttle Butkus
fuente
3

Intente truncar las tablas más grandes en su base de datos antes de soltarla. Vi un comportamiento muy similar al trabajar con archivos MySQL de tráfico de firewall y esto me ayudó enormemente.

Tim Brigham
fuente
De acuerdo con los documentos de MySQL, "Las operaciones de truncamiento caen y vuelven a crear la tabla, que es mucho más rápido que eliminar filas una por una", por lo que no tiene sentido truncar para soltar - dev.mysql.com/doc/refman/8.0/en/ truncate-table.html
ejoubaud
3

Me enfrenté al mismo problema . Pero esta vez verifiqué show processlist; dijo que buscaba permisos por más tiempo. Luego descubrí que mysqld_safe se estaba ejecutando como root, mientras que los permisos de nivel de carpeta eran solo para usuarios de mysql. Por lo tanto, eliminé la consulta, por supuesto, me llevó mucho tiempo decir que estaba en estado desactivado, pero esperé a que reaccionara, luego eliminó la consulta y cambió los permisos de nivel de carpeta a raíz también agregándola al grupo y chmod a 770. Luego ejecuté la misma caída de la base de datos bla; funcionó para mí en 2 segundos para una base de datos de 20 GB.

Mannoj
fuente