O MySQL travou e não inicializa

19

Nosso servidor mysql de produção acabou de travar e não volta a funcionar. Está dando um erro de segfault. Eu tentei reiniciar e não sei mais o que tentar. Aqui está o stacktrace:

140502 14:13:05 [Nota] O plug-in 'FEDERATED' está desativado.
InnoDB: a verificação de log progrediu além do ponto de verificação lsn 108 1057948207
140502 14:13:06 InnoDB: O banco de dados não foi desligado normalmente!
InnoDB: Iniciando a recuperação de falhas.
InnoDB: Lendo informações do espaço de tabela dos arquivos .ibd ...
InnoDB: Restaurando possíveis páginas de dados semi-escritas a partir da gravação dupla
InnoDB: buffer ...
InnoDB: Fazendo recuperação: digitalizada até o número de sequência do log 108 1058059648
InnoDB: 1 transação (s) que deve ser revertida ou limpa
InnoDB: no total, 15 operações de linha para desfazer
InnoDB: o contador de identificação de Trx é 0 562485504
140502 14:13:06 InnoDB: Iniciando um lote de aplicação de registros de log no banco de dados ...
InnoDB: Progresso em porcentagens: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 97 98 99 
InnoDB: Aplicar lote concluído
InnoDB: Iniciando em segundo plano a reversão de transações não confirmadas
140502 14:13:06 InnoDB: revertendo trx com o ID 0 562485192, 15 linhas para desfazer
140502 14:13:06 InnoDB: Iniciado; número de sequência do log 108 1058059648
140502 14:13:06 InnoDB: falha de asserção no encadeamento 1873206128 no arquivo ../../../storage/innobase/fsp/fsp0fsp.c linha 1593
InnoDB: Falha na asserção: frag_n_used> 0
InnoDB: Geramos intencionalmente uma armadilha de memória.
InnoDB: envie um relatório detalhado de erros para http://bugs.mysql.com.
InnoDB: Se você repetir falhas ou falhas de asserção, mesmo
InnoDB: imediatamente após a inicialização do mysqld, pode haver
InnoDB: corrupção no espaço de tabela do InnoDB. Por favor, consulte
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: sobre forçar a recuperação.
140502 14:13:06 - o mysqld recebeu o sinal 6;
Pode ser porque você atingiu um inseto. Também é possível que esse binário
ou uma das bibliotecas às quais foi vinculada está corrompida, construída incorretamente,
ou mal configurado. Este erro também pode ser causada por hardware com defeito.
Vamos tentar o nosso melhor para obter algumas informações que, espero, ajudem a diagnosticar
o problema, mas desde que já caímos, algo está definitivamente errado
e isso pode falhar.

key_buffer_size = 16777216
read_buffer_size = 131072
max_used_connections = 0
max_threads = 151
threads_connected = 0
É possível que o mysqld possa usar até 
key_buffer_size + (read_buffer_size + sort_buffer_size) * max_threads = 345919 K
bytes de memória
Espero que esteja tudo bem; caso contrário, diminua algumas variáveis ​​na equação.

thd: 0x0
Tentando voltar atrás. Você pode usar as seguintes informações para descobrir
onde o mysqld morreu. Se você não vir mensagens depois disso, algo ocorreu
terrivelmente errado ...
stack_bottom = (zero) thread_stack 0x30000
140502 14:13:06 [Nota] Agendador de Eventos: Carregado 0 eventos
140502 14:13:06 [Nota] / usr / sbin / mysqld: pronto para conexões.
Versão: '5.1.41-3ubuntu12.10' socket: '/var/run/mysqld/mysqld.sock' port: 3306 (Ubuntu)
/ usr / sbin / mysqld (my_print_stacktrace + 0x2d) [0xb7579cbd]
/ usr / sbin / mysqld (handle_segfault + 0x494) [0xb7245854]
[0xb6fc0400]
/lib/tls/i686/cmov/libc.so.6(abort+0x182) [0xb6cc5a82]
/ usr / sbin / mysqld (+ 0x4867e9) [0xb74647e9]
/ usr / sbin / mysqld (btr_page_free_low + 0x122) [0xb74f1622]
/ usr / sbin / mysqld (btr_compress + 0x684) [0xb74f4ca4]
/ usr / sbin / mysqld (btr_cur_compress_if_useful + 0xe7) [0xb74284e7]
/ usr / sbin / mysqld (btr_cur_pessimistic_delete + 0x332) [0xb7429e72]
/ usr / sbin / mysqld (btr_node_ptr_delete + 0x82) [0xb74f4012]
/ usr / sbin / mysqld (página_discard_trol + 0x175) [0xb74f41e5]
/ usr / sbin / mysqld (btr_cur_pessimistic_delete + 0x3e8) [0xb7429f28]
/ usr / sbin / mysqld (+ 0x526197) [0xb7504197]
/ usr / sbin / mysqld (row_undo_ins + 0x1b1) [0xb7504771]
/ usr / sbin / mysqld (row_undo_step + 0x25f) [0xb74c210f]
/ usr / sbin / mysqld (que_run_threads + 0x58a) [0xb74a31da]
/ usr / sbin / mysqld (trx_rollback_or_clean_all_without_sess + 0x3e3) [0xb74ded43]
/lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0xb6f9f96e]
/lib/tls/i686/cmov/libc.so.6(clone+0x5e) [0xb6d65a4e]
A página do manual em http://dev.mysql.com/doc/mysql/en/crashing.html contém
informações que devem ajudá-lo a descobrir o que está causando o acidente.

Alguma recomendação?

tilleryj
fonte
Primeiras coisas primeiro; alguém mudou a configuração do MySQL de alguma forma? Veja a data da última modificação para mais /etc/mysql/my.cnfou menos.
Janne Pikkarainen
Não. Acabou tendo que definir innodb_force_recovery = 3 para fazer um mysqldump, depois soltar e ler o banco de dados. Isso consertou.
tilleryj

Respostas:

26

Ai.

InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: about forcing recovery.

Verifique a página da Web sugerida: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html .

Basicamente, tente iniciar o servidor MySQL em um modo de recuperação e faça um backup das suas tabelas travadas .

Edite seu /etc/my.cnfe adicione:

 innodb_force_recovery = 1

... para ver se você pode acessar seu banco de dados e obter seus dados / encontrar a tabela corrompida.

Geralmente, quando isso acontece, é uma recriação (pelo menos de uma tabela corrompida ou duas).

Em http://chepri.com/mysql-innodb-corruption-and-recovery/ :

  1. Pare mysqld( service mysql stop).
  2. Cópia de segurança /var/lib/mysql/ib*
  3. Adicione a seguinte linha em /etc/my.cnf:

    innodb_force_recovery = 1
    

    (eles sugerem 4, mas é melhor começar com 1 e aumentar se não iniciar)

  4. Reinicie mysqld( service mysql start).

  5. Despejar todas as tabelas: mysqldump -A > dump.sql
  6. Elimine todos os bancos de dados que precisam de recuperação.
  7. Pare mysqld( service mysql stop).
  8. Retirar /var/lib/mysql/ib*
  9. Comentar innodb_force_recoveryem/etc/my.cnf
  10. Reinicie mysqld. Veja o log de erros do mysql. Por padrão, deve ser /var/lib/mysql/server/hostname.com.errpara ver como ele cria novos ib*arquivos.
  11. Restaure bancos de dados do dump: mysql < dump.sql
Jonathan
fonte
Eu consideraria primeiro que você pode ter corrupção no sistema de arquivos ou um disco defeituoso.
bombcar
1
tente todos os valores innodb_force_recovery até 6. E adicione innodb_purge_threads = 0 - fio, por vezes, principal não pode iniciar qualquer, você vai vê-lo no log de erro
akuzminsky
2
Eu sei que este é um segmento antigo, mas alguma elaboração sobre como determinar quais bancos de dados precisam de recuperação?
Nkanderson
@nicolekanderson Eu também gostaria de alguns esclarecimentos sobre esse ponto. Depois de executar o mysqldump, isso não indica para mim que nenhum banco de dados estava corrompido.
Andrew Thaddeus Martin
ponto 10 na resposta - tente reiniciar o servidor de banco de dados e leia o log de erros; ele deve fornecer o nome das tabelas com falha. O mysqldump fornece apenas uma cópia das tabelas, nada mais.
9137 Jonathan
2

Eu estava enfrentando esse mesmo erro enquanto usava a imagem do docker mysql: 5.7. O principal erro foi tentar criar o usuário root que existe por padrão. Mais informações: https://github.com/docker-library/mysql/issues/129

Conforme fornecido no link acima, a solução foi NÃO definir MYSQL_USER e MYSQL_PASSWORD nas variáveis ​​de ambiente ao iniciar a imagem do docker.

rahuljain1311
fonte
1

Isso aconteceu comigo no Laravel Homestead (Vagrant após um pânico no kernel executando o Mac OS Sierra 10.12.4 (16E195):

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:    14.04
Codename:   trusty

$ mysql -V
mysql  Ver 14.14 Distrib 5.7.9, for Linux (x86_64) using  EditLine 
wrapper

Aqui estão alguns recursos que você pode tentar, embora nenhuma das opções de reparo tenha funcionado para mim :

https://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html

https://forums.mysql.com/read.php?22,603093,604631#msg-604631

https://support.plesk.com/hc/en-us/articles/213939865-How-to-fix-InnoDB-corruption-cases-for-the-MySQL-database

Tentei adicionar força de recuperação à configuração do mysql (inicie em 1 e suba progressivamente, pois números supostamente mais altos podem causar corrupção permanente):

sudo nano /etc/mysql/my.cnf

[mysqld]
innodb_force_recovery = 1
#innodb-read-only=1
#innodb_purge_threads=0
#key_buffer_size=16M
#event-scheduler=disabled

Em outra janela, execute:

tail -f /var/log/mysql/error.log

Então tente reiniciar o mysqld com as várias opções ativadas:

sudo /etc/init.d/mysql restart

Se expirar, você pode forçar a reinicialização dos processos mysql com:

# process id is first column with number, just ignore lines with grep because they list the process running 'grep mysql'
ps aux | grep mysql
sudo kill -9 <process-id>
sudo /etc/init.d/mysql restart

Se funcionar, o log mostrará algo como:

Version: '5.7.9' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)

Se falhar, o log mostrará algo como:

InnoDB: Assertion failure in thread 140049488692992 in file log0recv.cc line 1420


Quando piorou, tentei remover os bancos de dados que provavelmente estavam corrompidos:

sudo ls -alt /var/lib/mysql

Descobriu-se que o banco de dados em que eu estava trabalhando era o mais recentemente modificado no topo da lista. Felizmente, eu tinha um dump SQL para ele a partir desse dia, então pude removê-lo:

sudo rm -rf /var/lib/mysql/<database_name>

Deixei todos os outros arquivos e o mysql foi capaz de iniciar de qualquer maneira.

UPDATE: certifique-se de desabilitar innodb_force_recovery = 1quando o mysql estiver funcionando novamente, caso contrário, você receberá erros ao tentar modificar bancos de dados e tabelas.

Depois recriei o banco de dados com o Sequel Pro, reimportei meus dados e fui capaz de seguir em frente sem ter que jogar fora todos os bancos de dados dos meus outros projetos.

No futuro, devo assumir que qualquer banco de dados mysql pode ser corrompido e tentar manter backups diários e ter o script de recreação do banco de dados documentado ou codificado em minhas ferramentas de integração contínua.

Zack Morris
fonte