it-swarm.it

Perché DROP DATABASE impiega così tanto tempo? (MySQL)

Nuova installazione CentOS.

Stavo eseguendo un'importazione di un DB di grandi dimensioni (file sql da 2 GB) e ho avuto un problema. Il client SSH sembrava perdere la connessione e l'importazione sembrava bloccarsi. Ho usato un'altra finestra per accedere a mysql e l'importazione sembrava essere morta, bloccata su una particolare tabella di righe 3M.

Quindi ci ho provato

DROP DATABASE huge_db;

15-20 minuti dopo, niente. In un'altra finestra, ho fatto:

/etc/init.d/mysqld restart

La finestra DROP DB con messaggi: SERVER SHUTDOWN. Quindi ho effettivamente riavviato il server fisico.

Tornato a mysql, controllato e il db era ancora lì, corse

DROP DATABASE huge_db;

di nuovo, e di nuovo aspetto già circa 5 minuti.

Ancora una volta, è una nuova installazione. Il huge_db è l'unico db (diverso da dbs di sistema). Ti giuro che ho lasciato il db così grande prima e rapidamente, ma forse mi sbaglio.

Ho lasciato cadere il database con successo. Ci sono voluti circa 30 minuti. Nota anche che penso di essermi sbagliato quando pensavo che l'importazione di mysqldump fosse morta. La connessione al terminale è andata persa, ma penso che il processo fosse ancora in corso. Molto probabilmente ho ucciso il tavolo intermedio di importazione (la tabella delle righe 3M) e probabilmente 3/4 dell'intero db. Era fuorviante che "top" mostrasse mysql usando solo il 3% di memoria, quando sembrava che avrebbe dovuto usarne di più.

L'eliminazione del DB ha richiesto 30 minuti, quindi, ancora una volta, non avrei dovuto riavviare il server e probabilmente avrei semplicemente aspettato che il DROP finisse, ma non so come mysql avrebbe reagito all'ottenimento di una query DROP per lo stesso db che sta importando tramite mysqldump.

Tuttavia, la domanda rimane: perché ci vogliono 30 minuti + per DROP un database da 2 GB quando tutto ciò che dovrebbe fare è cancellare tutti i file db e rimuovere tutti i riferimenti al DB da information_schema? Qual è il grosso problema?

49
Buttle Butkus

Invece di uccidere il processo, sarebbe più sicuro se lo facessi all'interno di 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 query con ID 174 è l'unica che blocca l'eliminazione del database "esempio", quindi prima di interrompere qualsiasi processo, lascia che MySQL tenti di terminare la query:

$ mysqladmin kill 174

Eseguire nuovamente il comando processlist sopra per confermare che è stato ucciso.

Se questo non funziona, potresti forse cercare di terminare il processo errato, ma prima potresti provare a riavviare il server MySQL.

Puoi anche eseguire comandi come 'SHOW FULL PROCESSLIST' e 'KILL 174' in MySQL Shell, ad esempio se hai solo il client MySQL installato. Il punto principale è evitare di uccidere il processo usando "kill" nella Shell a meno che non sia assolutamente necessario.

In generale puoi usare mysql o mysqladmin. Non dovresti aver bisogno di eseguire comandi in questo modo così spesso; una volta che inizi a uccidere le query regolarmente qualcosa è sicuramente sbagliato e faresti meglio a risolvere quel problema (uccidere il processo di query sta solo trattando il sintomo).

80
Stefan Magnuson

Sebbene pensassi che il processo di importazione fosse morto, probabilmente era ancora in corso.

Il comando DROP DATABASE Probabilmente ha aspettato che il database terminasse l'importazione prima di essere eseguito.

Quindi, piuttosto che DROP DATABASE Impiegando molto tempo, probabilmente era solo l'importazione.

Se qualcun altro legge questo e sta cercando di annullare un'importazione del database e rilasciarlo, ti consiglio di trovare prima il PID (ID processo) per l'importazione ed eseguirlo da un altro terminale:

$ kill [PID]

... dove [PID] sarebbe il PID effettivo per il processo.

Dovresti vedere immediatamente l'interruzione dell'importazione se l'altro terminale è ancora collegato.

Puoi anche eseguire SHOW PROCESSLIST Nella scheda SQL phpMyAdmin. La tabella risultante mostra i processi in esecuzione e fare clic sulla 'x' accanto alla riga che si desidera uccidere dovrebbe fare il trucco.

Quindi corri

DROP DATABASE `database_name`;

E tutto dovrebbe essere pulito.


Un'altra risposta ha suggerito che uccidere il processo all'interno di mysql è meglio che farlo dall'esterno. Non ho provato quella risposta, ma sembra molto plausibile. Quindi l'ho contrassegnata come "risposta accettata" anziché questa.

11
Buttle Butkus

Prova a troncare le tabelle più grandi nel tuo database prima di rilasciarlo. Ho visto un comportamento molto simile lavorando con gli archivi MySQL del traffico firewall e questo mi ha aiutato immensamente.

3
Tim Brigham

Ho affrontato lo stesso problema. Ma questa volta ho controllato show processlist; diceva che controllava i permessi per un tempo più lungo. Poi ho scoperto che mysqld_safe era in esecuzione come root mentre le autorizzazioni a livello di cartella erano solo per l'utente mysql. Quindi ho ucciso la query, ovviamente ci è voluto molto tempo dicendo che era nello stato ucciso ma ho aspettato che reagisse, quindi ha ucciso la query e ha cambiato le autorizzazioni a livello di cartella in root aggiungendole al gruppo e chmod a 770. Quindi ho eseguito lo stesso drop blah database; ha funzionato per me in 2 secondi per un database da 20 GB.

3
Mannoj

La prima cosa che mi viene in mente è lo stato Checking Permissions...

Quando si emette DROP DATABASE mydb; tutto all'interno di/var/lib/mysql/mydb viene controllato per vedere se esistono autorizzazioni del sistema operativo per il diritto di eliminare ogni file.

Alcuni hanno ritenuto che ridurre il numero di utenti mysql possa aiutare

3
RolandoMySQLDBA