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


46

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. L' huge_dbè l'unico db (diverso DBS 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?

Risposte:


73

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 di nuovo il processlistcomando 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' nella shell MySQL, 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 mysqlo mysqladmin. Tuttavia, non dovresti dover 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 è solo trattare il sintomo).


1
@BugsBuggy Un modo comune in cui ciò può accadere è se un altro processo (ad esempio un server Web o in questo caso un processo di importazione) è in esecuzione ed è collegato al database. Quando si emette il DROP DATABASEcomando, il server non procederà fino a quando tutte le connessioni non saranno state chiuse.
Stefan Magnuson,

11

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

Il DROP DATABASEcomando probabilmente ha atteso che il database terminasse l'importazione prima di essere eseguito.

Quindi, piuttosto che DROP DATABASEimpiegare 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.

È inoltre possibile eseguire SHOW PROCESSLISTnella 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.


3

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


Secondo i documenti di MySQL, "Troncare le operazioni rilasciare e ricreare la tabella, che è molto più veloce dell'eliminazione delle righe una per una", quindi non ha senso troncare per eliminare - dev.mysql.com/doc/refman/8.0/en/ truncate-table.html
ejoubaud


3

Ho affrontato lo stesso problema. Ma questa volta ho controllato show processlist; diceva controllando le autorizzazioni 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 database blah; ha funzionato per me in 2 secondi per database da 20 GB.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.