Pourquoi DROP DATABASE prend-il si longtemps? (MySQL)

46

Nouvelle installation CentOS.

J'étais en train d'exécuter une importation d'une grande base de données (fichier de 2 Go SQL) et j'ai eu un problème. Le client SSH semblait perdre la connexion et l'importation semblait se figer. J'ai utilisé une autre fenêtre pour me connecter à mysql et l'importation semblait être morte, bloquée sur une table de rangée particulière de 3M.

Alors j'ai essayé

DROP DATABASE huge_db;

15-20 minutes plus tard, rien. Dans une autre fenêtre, j'ai fait:

/etc/init.d/mysqld restart

La fenêtre de messagerie DROP DB: SERVEUR ARRÊT. Ensuite, j'ai effectivement redémarré le serveur physique.

Reconnecté à mysql, vérifié et la base de données était toujours là, a couru

DROP DATABASE huge_db;

encore, et encore j'attends déjà environ 5 minutes.

Encore une fois, c'est une nouvelle installation. La huge_dbest la seule base de données (autre que la base de données système). Je jure que j’ai largué cette grosse base de données auparavant et rapidement, mais je me trompe peut-être.

J'ai abandonné la base de données avec succès. Cela a pris environ 30 minutes. Notez également que je me suis trompé en pensant que l’importation de mysqldump était morte. La connexion du terminal a été perdue, mais je pense que le processus était toujours en cours. J'ai probablement tué la table intermédiaire d'importation (la table de rangée 3M) et probablement les 3/4 de la base entière. Il était trompeur que "top" montrait que mysql n'utilisait que 3% de mémoire, alors qu'il semblait devoir en utiliser davantage.

Abandonner la base de données a pris 30 minutes, alors encore une fois, je n’aurais peut-être pas eu à redémarrer le serveur et j’aurais peut-être attendu la fin du processus DROP, mais je ne sais pas comment mysql réagirait si une requête DROP était reçue. la même base de données qu'il importe via mysqldump.

Reste cependant à savoir pourquoi il faut plus de 30 minutes pour supprimer une base de données de 2 Go alors que tout ce qu'il devrait faire est de supprimer tous les fichiers de base de données et de supprimer toutes les références à la base de données de information_schema. Quel est le problème?

Buttle Butkus
la source

Réponses:

73

Plutôt que de tuer le processus, il serait plus sûr de le faire avec 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 requête portant l'ID 174 est la suppression la plus bloquante de la base de données 'example'. Avant de supprimer tout processus, laissez d'abord MySQL essayer de mettre fin à la requête:

$ mysqladmin kill 174

Exécutez à nouveau la processlistcommande ci-dessus pour confirmer qu'il a été tué.

Si cela ne fonctionne pas, vous pouvez peut-être essayer de supprimer le processus erroné, mais auparavant, vous pourriez essayer de redémarrer le serveur MySQL.

Vous pouvez également exécuter des commandes telles que 'SHOW FULL PROCESSLIST' et 'KILL 174' dans le shell MySQL, par exemple si vous n'avez que le client MySQL installé. Le principal est d'éviter de tuer le processus en utilisant "kill" dans la coque, sauf en cas d'absolue nécessité.

De manière générale, vous pouvez utiliser soit mysqlou mysqladmin. Vous ne devriez pas avoir besoin d’exécuter des commandes comme celle-là aussi souvent cependant; une fois que vous commencez à tuer des requêtes régulièrement, quelque chose ne va vraiment pas et vous feriez mieux de résoudre ce problème (tuer le processus de requête ne fait que traiter le symptôme).

Stefan Magnuson
la source
1
@BugsBuggy Cela peut se produire généralement si un autre processus (par exemple, un serveur Web ou, dans ce cas, un processus d'importation) est en cours d'exécution et est connecté à la base de données. Lorsque vous émettez la DROP DATABASEcommande, le serveur ne continuera pas tant que toutes les connexions n'auront pas été fermées.
Stefan Magnuson le
11

Bien que je pensais que le processus d'importation était mort, il était probablement toujours en cours d'exécution.

La DROP DATABASEcommande a probablement attendu que la base de données ait fini d'importer avant de s'exécuter.

Donc, plutôt que de DROP DATABASEprendre beaucoup de temps, c'était probablement juste l'importation.

Si quelqu'un d'autre lit ceci et tente d'annuler une importation de base de données et de la supprimer, je vous recommande tout d'abord de trouver le PID (id de processus) pour l'importation et de l'exécuter à partir d'un autre terminal:

$ kill [PID]

... où [PID] serait le PID réel du processus.

Vous devriez voir l'importation s'arrêter immédiatement si l'autre terminal est toujours connecté.

Vous pouvez également exécuter SHOW PROCESSLISTl'onglet phpMyAdmin SQL. Le tableau qui en résulte montre les processus en cours, et le fait de cliquer sur le "x" en regard de la ligne à supprimer devrait suffire.

Puis courir

DROP DATABASE `database_name`;

Et tout devrait être propre.


Une autre réponse a suggéré que tuer le processus dans mysql est mieux que de le faire de l'extérieur. Je n'ai pas testé cette réponse, mais cela semble très plausible. Donc, je l'ai marqué comme "réponse acceptée" au lieu de celle-ci.

Buttle Butkus
la source
3

Essayez de tronquer les plus grandes tables de votre base de données avant de les supprimer. J'ai constaté un comportement très similaire lorsque je travaillais avec les archives MySQL du trafic de pare-feu, ce qui m'a beaucoup aidé.

Tim Brigham
la source
Selon la documentation de MySQL, "Les opérations de tronquage
ejoubaud le
3

La première chose qui me vient à l’esprit est le statut Checking Permissions...

Lorsque vous DROP DATABASE mydb;publiez tout ce qui se trouve dans / var / lib / mysql / mydb, on vérifie s'il existe des autorisations pour le système d'exploitation permettant de supprimer tous les fichiers.

Certains pensent que réduire le nombre d'utilisateurs de mysql peut aider

RolandoMySQLDBA
la source
3

J'ai rencontré le même problème. Mais cette fois j'ai vérifié show processlist; il a dit vérifier les autorisations pour plus de temps. Ensuite, j'ai découvert que mysqld_safe fonctionnait en tant que root alors que les autorisations au niveau du dossier étaient réservées aux utilisateurs mysql. Par conséquent, j'ai tué la requête. Bien sûr, il a fallu beaucoup de temps pour déclarer son état tué, mais j'ai attendu qu'elle réagisse, puis il a tué la requête et modifié les autorisations de niveau dossier en tant que root également en l'ajoutant à un groupe et à 770 par chmod. la même base de données drop bla; cela a fonctionné pour moi en 2 secondes pour la base de données de 20Go.

Mannoj
la source