Como matar corretamente o MySQL?

28

Tenho o CentOS 64bit com o CPanel instalado e uso:

service mysql stop

Ele apenas mantém os períodos e nunca parece que ele para. Nos logs, ele apenas publica muitos:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

No err.logarquivo, vejo muitos destes:

[Warning] /usr/sbin/mysqld: Forcing close of thread

Costumava ser instantâneo. Alguma idéia de por que isso acontece e como consertar?

Agora eu tenho que fazer, killall -9 mysqlmas existe uma maneira melhor?

O servidor também é muito, muito ativo.

Isso é um problema de configuração? Tenho configurações de memroy muito altas?

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M
Paul White diz que a GoFundMonica
fonte

Respostas:

37

A maneira mais fácil de desligar o mysql quando isso é simplesmente executar

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Aqui está o porquê:

O arquivo de serviço mysql ( /etc/init.d/mysql) depende da presença do arquivo de soquete. Historicamente falando, voltando ao MySQL 4.0, o arquivo de soquete às vezes desaparece inexplicavelmente. Isso dificulta o funcionamento de um padrão service mysql stop.

Não basta dizer

mysqladmin -uroot -p -h127.0.0.1 shutdown

porque rota mysqld vontade um usuário entrando como [email protected]para root@localhostse TCP / IP não está habilitado explicitamente. Por padrão, o mysqld irá escolher o caminho de menor resistência e se conectar [email protected]a root@localhostvia o arquivo socket. No entanto, se não houver arquivo de soquete, root@localhostnunca se conectará.

Até a documentação do MySQL no mysqladmin diz o seguinte:

Se você executar o desligamento do mysqladmin ao conectar-se a um servidor local usando um arquivo de soquete Unix, o mysqladmin aguardará até que o arquivo de identificação do processo do servidor seja removido, para garantir que o servidor tenha parado corretamente.

É por isso que é essencial habilitar o TCP / IP:

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Em 30 de setembro de 2011, escrevi minha própria versão do mysqld_multichamado mysqlservice(Veja minha postagem: Executando várias instâncias no mesmo host ). Ele serve como um mecanismo virtual para conectar-se ao mysqld a partir de diferentes portas. Você só precisa criar seus próprios my.cnfparâmetros personalizados. Nesse script, emito encerramentos como este:

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

Mas o que é isso ${MYSQLD_STOP}?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

Observe que eu uso 127.0.0.1e uma porta explícita. Dessa forma, não estou confiando em um arquivo de soquete.

Eu sempre usei mysqladmin --protocol=tcp shtudowncomo a alternativa adequada para desligamentos do mysql se service mysql stoptravar. Fazendo kill -9em mysqlde mysqld_safedeve ser o último dos últimos dos últimos resorts. (Sim, eu disse três vezes).

Muitas vezes, o mysqld excluiu o mysql.sock sem aviso. Outras pessoas também tiveram esse problema ao longo dos anos:

EPÍLOGO

O segredo é exatamente como afirmei: Conecte-se ao mysql usando o mysqladmin via TCP / IP ( --protocol=tcp) e emita-o shutdown. Isso tem que funcionar porque o privilégio de encerramento é mysql.userpara o objetivo exclusivo de encerramentos autenticados. Isso salvou meu dia de trabalho algumas vezes quando pude emitir um desligamento remoto da minha máquina Windows ao desligar o mysqld em um servidor Linux.

ATUALIZAÇÃO 06-03-2013 22:48 EST

Se você está preocupado com o que está acontecendo durante o desligamento, existe uma maneira de manipular o tempo de desligamento e a maneira como os dados são liberados para o disco, especialmente se você tiver muitos dados do InnoDB no Buffer Pool

SUGESTÃO # 1

Se você tiver muitas páginas sujas, poderá reduzir o innodb_max_dirty_pages_pct para 0:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Defina isso de 15 a 30 minutos antes do desligamento. Isso dará ao mysqld a menor quantidade possível de páginas sujas para gravar no disco.

SUGESTÃO # 2

Por padrão, innodb_fast_shutdown é 1. Existem três valores para esta opção

  • 0: O InnoDB faz um desligamento lento, uma limpeza completa e um buffer de inserção mesclados antes de desligar.
  • 1: O InnoDB ignora essas operações no desligamento, um processo conhecido como desligamento rápido.
  • 2: O InnoDB limpa seus logs e desliga, como se o MySQL tivesse travado; nenhuma transação confirmada é perdida, mas a operação de recuperação de falhas leva a próxima inicialização a demorar mais tempo.

A documentação ainda diz o seguinte:

O desligamento lento pode levar minutos ou até horas em casos extremos em que quantidades substanciais de dados ainda são armazenadas em buffer. Use a técnica de desligamento lento antes de atualizar ou fazer o downgrade entre as principais versões do MySQL, para que todos os arquivos de dados sejam totalmente preparados, caso o processo de atualização atualize o formato do arquivo.

Use innodb_fast_shutdown = 2 em situações de emergência ou solução de problemas, para obter o encerramento mais rápido possível se os dados estiverem em risco de corrupção.

Os padrões para innodb_max_dirty_pages_pct e innodb_fast_shutdown devem estar bem na maioria dos casos.

RolandoMySQLDBA
fonte
2
O arquivo de soquete desaparece nos derivados do Red Hat porque o tmpwatchexclui, juntamente com tudo o mais /tmpque possui um atime mais antigo que o limite configurado.
Michael - sqlbot
Obrigado, @ Michael-sqlbot Eu precisava ouvir isso de alguém, finalmente. Eu acho que é por isso que alguém da MySQL AB (pré-Oracle, pré-Sun) decidiu adicionar o privilégio SHUTDOWN mysql.userpara contornar dores de cabeça como essa.
RolandoMySQLDBA
No Debian ou Ubuntu, use mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... esse arquivo contém credenciais para uma conta MySQL semelhante a raiz.
0xC0000022L
Como sempre, @RolandoMySQLDBA, você é um dos melhores recursos de DBA nos sites do Stack Exchange. Excelente trabalho aqui que me ajudou mais de 6 anos depois.
JakeGould 24/09
5

Parece que sua pergunta é menos sobre "como desligar o MySQL" e mais sobre por que a sua está sendo desligada tão lentamente.

Na minha resposta a uma pergunta semelhante , ofereci algumas sugestões para uma reinicialização suave, o que ajuda a reduzir a quantidade de atividade que deve ocorrer depois que você solicita que o MySQL inicie o processo de desligamento .

Se você não é um usuário frequente SHOW FULL PROCESSLIST;desse item 1, porque precisa ter uma noção do que está acontecendo no seu servidor, o que torna o desligamento tão lento. Se houver consultas de longa duração que possam ser interrompidas com segurança, você poderá matá-las KILL <thread-id>.

Recapitulando as outras sugestões:

A configuração da variável global innodb_fast_shutdown = 1(o padrão) acelerará a parte do desligamento do InnoDB. No entanto, isso é seguro se você estiver desligando o servidor por motivos não relacionados à execução de uma atualização. Se você estiver desligando para uma atualização, isso deve ser definido como 0.

Usar FLUSH TABLES;graciosamente fecha todas as tabelas abertas. Elas serão reabertas se referenciadas por consultas subseqüentes, mas essa ação ainda deve reduzir o tempo decorrido entre o momento em que você solicita o desligamento e o tempo em que o desligamento é concluído, porque realiza algumas tarefas de limpeza antecipada e, mais importante, define o cenário para a etapa final ...

FLUSH TABLES WITH READ LOCK;fecha todas as tabelas abertas e obtém um bloqueio exclusivo pertencente à sua conexão de cliente atual que impede que qualquer outra conexão grave em qualquer tabela em todo o servidor. Você não receberá seu mysql>aviso de volta até possuir esse bloqueio. Nesse momento, poderá emitir a solicitação de desligamento - mas não desconecte-se desta sessão.

Em um servidor ocupado, essas etapas devem reduzir o nível de atividade no servidor, tornar as coisas muito mais silenciosas e ajudar a tornar o desligamento ou a reinicialização mais suave.

Michael - sqlbot
fonte
2

É provável que o MySQL não esteja completamente bloqueado, mas esteja fazendo atividades de limpeza (reversões, etc.) ao desligar. Se você não deixar fazer tudo isso ao desligar, geralmente precisará esperar ao iniciar.

Aqui está algo para se olhar: Desligue o mysql em uma janela do terminal enquanto observa o log de erros (tail -f [yourerror.log]) em outra janela do terminal. O log de erros mostrará o que o MySQL está fazendo.

Valerie Parham-Thompson
fonte
1

Lamento ouvir sua experiência e espero que minha experiência com cenários tolos do MySQL, semelhantes a esse, possa ajudá-lo.

Em vez de tentar descobrir como eliminar o serviço MySQL do servidor, em alguns casos, você precisará verificar a integridade do sistema através do seguinte para determinar se há um abuso de serviço (a suposição é baseada na noção de Ambiente CentOS / RHEL ):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

Use o seguinte para identificar a carga média do sistema e os recursos que mais consomem no sistema.

Você também precisará instalar mytoppara obter uma visão geral das instruções SQL que estão sendo processadas pelo sistema.

Para instalar mytop, basta executar o seguinte:

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(use qualquer editor de texto que você preferir)

Pesquise "long|!" => \$config{long_nums},

Comente como #"long|!" => \$config{long_nums},

chmod 555 /usr/local/bin/mytop

E você está pronto para usar o mytop . Use-o para verificar as instruções do MySQL que estão sobrecarregando seu serviço MySQL e pará-las.

A execução das instruções acima fornecerá as seguintes habilidades:

  • Diagnóstico do status / integridade do seu servidor
  • Diagnóstico de sua causa de gargalo

Depois de eliminar a causa do gargalo, você deverá ter um dia mais fácil ao tentar reiniciar o serviço MySQL. Espero que você encontre as informações acima úteis.

Nota: mytop é antigo e sem manutenção. Você provavelmente deve usar innotopem um sistema moderno.

Michael Feng
fonte
0

A implementação padrão do script init do MySQL sinaliza o MySQL com o SIGTERM e aguarda uma certa quantidade de tempo para o MySQL desligar.

O MySQL, depois de receber um SIGTERM, primeiro interromperá o recebimento de novas conexões, concluirá a execução de quaisquer consultas ainda pendentes (isso pode demorar um pouco, dependendo da carga de trabalho e do número de clientes simultâneos) e começará a liberar os dados para o disco (isso pode demorar por muito tempo, dependendo da sua carga de trabalho, configurações, memória disponível e opções de mecanismo de armazenamento). Depois que toda a limpeza de dados for concluída, o MySQL desalocará qualquer memória alocada durante o estágio de inicialização (isso também pode demorar um pouco, dependendo da quantidade de memória alocada pelo MySQL), feche todos os identificadores de arquivo ainda abertos e depois chame "exit (0)".

Se após o seu pedido de desligamento o MySQL demorar muito para ser desligado, é bem possível que um ou mais desses estágios demorem muito tempo para serem concluídos. Se você tiver tempo, recomendo aguardar a conclusão do processo (isso evitará a perda de dados ou processos de recuperação longos quando você iniciar sua instância de banco de dados novamente).

Infelizmente, não há informações suficientes na sua pergunta para sugerir uma solução adequada para o seu problema. Espero que isso ajude a entender o problema.

LMC
fonte