Por que o DROP DATABASE está demorando tanto? (MySQL)

46

Nova instalação do CentOS.

Eu estava executando uma importação de um grande banco de dados (arquivo sql de 2GB) e tive um problema. O cliente SSH pareceu perder a conexão e a importação pareceu congelar. Eu usei outra janela para acessar o mysql e a importação parecia estar morta, presa em uma tabela de linhas 3M específica.

Então eu tentei

DROP DATABASE huge_db;

15-20 minutos depois, nada. Em outra janela, eu fiz:

/etc/init.d/mysqld restart

A janela DROP DB envia uma mensagem: SERVER SHUTDOWN. Então, na verdade, reiniciei o servidor físico.

Conectado novamente no mysql, verificado e o db ainda estava lá, executei

DROP DATABASE huge_db;

novamente, e novamente já estou esperando cerca de 5 minutos.

Mais uma vez, é uma nova instalação. O huge_dbé o único banco de dados (que não seja o sistema dbs). Juro que perdi db desse tamanho antes e rapidamente, mas talvez eu esteja errado.

Larguei o banco de dados com sucesso. Demorou cerca de 30 minutos. Observe também que acho que me enganei quando pensei que a importação do mysqldump estava morta. A conexão do terminal foi perdida, mas acho que o processo ainda estava em execução. Provavelmente matei a importação no meio da tabela (a tabela de linhas 3M) e provavelmente 3/4 do caminho durante todo o banco de dados. Era enganoso que "top" mostrasse o mysql usando apenas 3% da memória, quando parecia que deveria estar usando mais.

A interrupção do banco de dados levou 30 minutos, então, novamente, talvez eu não tivesse que reiniciar o servidor e possivelmente apenas esperasse o DROP terminar, mas não sei como o mysql reagiria ao obter uma consulta DROP para o mesmo db que está importando via mysqldump.

Ainda assim, a questão permanece: por que são necessários 30min + para DROP um banco de dados de 2GB quando tudo o que precisa fazer é excluir todos os arquivos db e remover todas as referências ao banco de dados do information_schema? Qual é o grande problema?

Buttle Butkus
fonte

Respostas:

73

Em vez de matar o processo, seria mais seguro se você o fizesse no 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 |
+-----+------+-----------+-------------------+---------+------+-------+------------------+

A consulta com o ID 174 é a única exclusão de bloqueio do banco de dados 'exemplo'; portanto, antes de finalizar qualquer processo, deixe o MySQL tentar finalizar a consulta:

$ mysqladmin kill 174

Execute o processlistcomando acima novamente para confirmar que ele foi morto.

Se isso não funcionar, talvez você possa tentar matar o processo incorreto, mas antes disso você pode tentar reiniciar o servidor MySQL.

Você também pode executar comandos como 'SHOW FULL PROCESSLIST' e 'KILL 174' no shell do MySQL, por exemplo, se você tiver apenas o cliente MySQL instalado. O ponto principal é evitar matar o processo usando 'kill' no shell, a menos que seja absolutamente necessário.

De um modo geral, você pode usar mysqlou mysqladmin. Você não precisa executar comandos como esse com frequência; Depois de começar a matar consultas regularmente, algo definitivamente está errado e é melhor corrigir esse problema (matar o processo de consulta é apenas tratar o sintoma).

Stefan Magnuson
fonte
1
@BugsBuggy Uma maneira comum de ocorrer isso é se outro processo (por exemplo, um servidor web ou, neste caso, um processo de importação) estiver em execução e estiver conectado ao banco de dados. Quando você emitir o DROP DATABASEcomando, o servidor não continuará até que todas as conexões tenham sido fechadas.
Stefan Magnuson
11

Embora eu pensasse que o processo de importação havia morrido, provavelmente ainda estava em execução.

O DROP DATABASEcomando provavelmente esperou o banco de dados concluir a importação antes de ser executado.

Então, em vez de DROP DATABASEdemorar muito, provavelmente era apenas a importação.

Se alguém mais ler isso e tentar cancelar uma importação de banco de dados e descartá-lo, recomendo que você encontre primeiro o PID (ID do processo) da importação e execute-o em um terminal diferente:

$ kill [PID]

... onde [PID] seria o PID real do processo.

Você verá a importação parar imediatamente se o outro terminal ainda estiver conectado.

Você também pode executar SHOW PROCESSLISTna guia SQL do phpMyAdmin. A tabela resultante mostra os processos em execução, e clicar no 'x' próximo à linha que você deseja eliminar deve fazer o truque.

Então corra

DROP DATABASE `database_name`;

E tudo deve estar limpo.


Outra resposta sugeriu que matar o processo dentro do mysql é melhor do que fazê-lo de fora. Eu não testei essa resposta, mas parece muito plausível. Então eu marquei como a "resposta aceita" em vez desta.

Buttle Butkus
fonte
3

Tente truncar as maiores tabelas no banco de dados youra antes de soltá-lo. Vi um comportamento muito semelhante ao trabalhar com arquivos MySQL de tráfego de firewall e isso ajudou imensamente.

Tim Brigham
fonte
De acordo com os documentos do MySQL, "Truncar operações eliminam e recriam a tabela, que é muito mais rápida do que excluir linhas uma a uma", portanto, não há sentido em truncá
ejoubaud 16/04
3

A primeira coisa que vem à mente é o status Checking Permissions...

Quando você emite DROP DATABASE mydb;tudo dentro de / var / lib / mysql / mydb, é verificado se existem permissões do sistema operacional para o direito de eliminar todos os arquivos.

Alguns acham que reduzir o número de usuários mysql pode ajudar

RolandoMySQLDBA
fonte
3

Eu enfrentei o mesmo problema. Mas desta vez eu verifiquei show processlist; ele disse verificando permissões por mais tempo. Então eu descobri que o mysqld_safe estava sendo executado como root, enquanto as permissões no nível da pasta eram apenas para o usuário mysql. Por isso, eu matei a consulta, é claro que demorou muito tempo dizendo que estava no estado morto, mas esperei que ela reagisse, e então matou a consulta e alterei as permissões no nível da pasta para root também, adicionando-a ao group e chmod para 770. Em seguida, executei o mesmo banco de dados descartado blá; funcionou para mim em 2 segundos para o banco de dados de 20 GB.

Mannoj
fonte