Como você identifica a corrupção da tabela do InnoDB?

24

Eu tenho algumas tabelas que são particionadas e têm vários índices em um escravo replicado. Após copiar o snap shot (seguro verificado) para um novo escravo e atualizar o mysqld de 5.1.42 para 5.5.15 e reiniciar a replicação, estou recebendo falhas do InnoDB com a mensagem de erro "Ponteiro inválido ..."

Esses erros ocorreram em 2 servidores com hardware e sistema operacional diferentes. Depois de correr:

ALTER TABLE .... COALESCE PARTION n;

o problema desaparece para essa mesa.

Porém, minha pergunta é de escopo maior e é "Como você identifica a corrupção da tabela do InnoDB?" ou reformulou "Como você avalia a integridade da tabela do InnoDB?" É "CHECK TABLE" a única ferramenta disponível para identificar problemas pré-crash?

Não tenho certeza se isso importa, mas as falhas ocorreram em execução: Versão: soquete '5.5.15-55-log': porta '/opt/mysql.sock': porta 3306 Percona Server (GPL), versão rel21.0, revisão 158

randomx
fonte
2
Oi Randy! Eu acho que as respostas aqui são credíveis - o InnoDB identificou sua própria corrupção. Talvez você deva reformular sua pergunta. Por que o que você está fazendo causa ao InnoDB uma corrupção?
Morgan Tocker

Respostas:

18

Morgan dá uma dica em seu comentário de que o InnoDB está constantemente procurando páginas corrompidas, fazendo somas de verificação nas páginas que lê. Se o InnoDB encontrar uma incompatibilidade de soma de verificação, ele travará o servidor.

Se você deseja acelerar esse processo (em vez de esperar que o InnoDB leia a página corrompida), você pode usar innochecksum:

Como as incompatibilidades de soma de verificação farão com que o InnoDB desligue deliberadamente um servidor em execução, pode ser preferível usar essa ferramenta em vez de esperar que um servidor em uso de produção encontre as páginas danificadas.

Uma ressalva interessante:

innochecksum não pode ser usado em arquivos de espaço de tabela que o servidor já tenha aberto. Para esses arquivos, você deve usar CHECK TABLE para verificar tabelas no espaço de tabela.

Portanto, sim, para uma tabela on-line CHECK TABLEé provavelmente a ferramenta (ou como indicado em outra resposta, mysqlcheck se você quiser fazer mais do que um único banco de dados de cada vez.)

Se você pode desligar seu banco de dados, pode forçar as somas de verificação usando innochecksum

Anedótico: Em um espaço de tabela innodb de 29 GB (com innodb_file_per_table=1), esse script levou cerca de 2 minutos

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

Como um bônus, no entanto, como você está executando o Percona, eles implementaram um novo método para uma soma de verificação rápida do innodb . Eu nunca o usei, mas pode acelerar o processo.

Derek Downey
fonte
1
Vou tentar aqui, parece ser a solução que @randymelder procura +1
marcio
2
O servidor Percona possui outros recursos interessantes. Veja innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability/… (!!)
Morgan Tocker
@ Test: innochecksum é o caminho a percorrer. Este é um guardião. +1 !!!
RolandoMySQLDBA
@DTest: Tiremos o chapéu hoje para você neste !!!!
RolandoMySQLDBA
@MorganTocker Interessante. Vai ter que pegar meu vácuo de conhecimento e fazer alguma investigação sobre Percona
Derek Downey
6

AVISO: antes de tentar qualquer uma dessas instruções, é altamente recomendável verificar se há um backup saudável do seu banco de dados em mãos, apenas por precaução. (obrigado a @Nick pelo aviso)

Tente usar o mysqlcheckcomando Em um terminal:

mysqlcheck -u username -p --databases database1 database2

Este comando produzirá uma lista de todas as tabelas e um status informando se houve algum tipo de corrupção:

table1  OK
table2  OK
table3  OK
tableN  OK

Com isso em mãos, você já saberá quais mesas precisa reparar. Apenas no caso de você querer reparar tudo de uma vez:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

Mais sobre mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

Nota: você marcou sua pergunta com . Eu não tinha idéia do que era aquilo, então pesquisei no Google. Parece ser um fork do MySQL, mas não tenho motivos para acreditar que os comandos sejam incompatíveis (dedos cruzados).


Alguém me indicou este guia que contém instruções mais específicas para a recuperação do banco de dados do InnoDB para situações mais críticas em que o banco de dados inteiro não inicia: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-myisam-innodb-1634.html

marcio
fonte
1
mysqlcheck é sinônimo de 'check table ...' -1
randomx 27/09
Não é verdade. Primeiro, mysqlcheck é um utilitário de linha de comando e CHECK TABLE é uma instrução SQL (é como comparar laranja com limões). Além disso, você NÃO pode verificar um banco de dados inteiro com CHECK TABLE sem incluir TODOS os nomes de tabela na instrução SQL ( também não seria muito produtivo)
marcio
E o mysqlcheck tem uma opção para reparar automaticamente as tabelas que estão corrompidas enquanto CHECK TABLE apenas verifica se as tabelas estão corrompidas ou não, mas não pode fazer nenhum reparo.
Marcio
2
@randymelder - Você está errado em dizer que mysqlcheck é sinônimo CHECK TABLE. A documentação ligada aos estados: " mysqlcheckusa as instruções SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, e OPTIMIZE TABLEde uma forma conveniente para o usuário ele determina quais declarações ao uso para a operação que deseja executar, e em seguida, envia as instruções para o servidor para ser executado.. " Isso não é sinônimo; essa é uma interface do usuário para uma coleção de instruções.
Nick Chammas
6

De acordo com o Guia de Estudo de Certificação do MySQL 5.0, Página 443.444 Seção 30.4 :

Você pode verificar as tabelas do InnoDB usando o comando CHECK TABLE ou um programa cliente para emitir a instrução para você. No entanto, se uma tabela do InnoDB tiver problemas, você não poderá corrigi-la usando REPAIR TABLE, porque essa instrução se aplica apenas ao MyISAM.

Se uma verificação de tabela indicar que uma tabela do InnoDB está com problemas, você poderá restaurar a tabela para um estado consistente despejando-a no mysqldump, descartando-a e recriando-a a partir dessa despejo.

No caso de uma falha de um servidor MySQL ou no host em que é executado, algumas tabelas do InnoDB podem precisar de reparos. Normalmente, basta simplesmente reiniciar o servidor porque o mecanismo de armazenamento InnoDB executa a recuperação automática como parte de sua sequência de inicialização. Em casos raros, o servidor pode não iniciar devido à falha da recuperação automática do InnoDB. Se isso acontecer, use o seguinte procedimento:

  • Reinicie o servidor com a opção --innodb_force_recovery configurada para um valor na faixa de 1 a 6. Esses valores indicam níveis crescentes de cuidado em evitar uma falha e níveis crescentes de tolerância para possível inconsistência nas tabelas recuperadas. Um bom valor para começar é 4.

  • Quando você inicia o servidor com --innodb_force_recovery definido como um valor diferente de zero, o InnoDB trata o espaço de tabela como somente leitura. Consequentemente, você deve despejar as tabelas do InnoDB com o mysqldump e depois descartá-las enquanto a opção estiver em vigor. Em seguida, reinicie o servidor sem a opção --innodb_force_recovery. Quando o servidor chegar, recupere as tabelas do InnoDB dos arquivos de despejo.

  • Se as etapas anteriores falharem, é necessário restaurar as tabelas do InnoDB a partir de um backup anterior.

Por favor, leia o MySQL Docs sobre InnoDB Forced Recovery  

RolandoMySQLDBA
fonte
3
FWIW, o guia de certificação tem uma resposta muito politicamente correta :) Se você CHECK TABLE em uma tabela do InnoDB e estiver realmente corrompido, ele nunca retornará como "corrompido", travará o servidor. A declaração é quase obsoleta no InnoDB, porque toda vez que você lê as páginas do InnoDB, ele verifica se há corrupção (por meio de somas de verificação de página).
Morgan Tocker 27/09/11
2

Gostaria de saber o que acontece se alguém usa os dados do InnoDB criados via InnoDB Plugin e depois muda para outra versão do InnoDB. Isso poderia criar uma possível corrupção de página aos olhos do mysqld.

Observe o que a documentação do MySQL no formato de arquivo InnoDB diz sobre essa possibilidade:

Em geral, uma versão mais recente do InnoDB pode criar uma tabela ou índice que não pode ser lido ou gravado com segurança em uma versão anterior do InnoDB sem risco de falhas, travamentos, resultados incorretos ou corrupções. O plug-in do InnoDB apresenta um novo mecanismo para proteger contra essas condições e ajudar a preservar a compatibilidade entre arquivos de banco de dados e versões do InnoDB.

Eu descartaria os dados do escravo. Na verdade, eu usaria apenas força bruta obtendo um despejo lógico (mysqldump) dos dados:

  • Elimine todos os bancos de dados usando o InnoDB no escravo
  • Shutdown mysql no escravo
  • Exclua ibdata1, ib_logfile0 e ib_logfile1 no escravo
  • Inicie o mysql no slave, permitindo que ibdata1, ib_logfile0 e ib_logfile1 sejam recriados
  • mysqldump os dados do mestre no escravo

Minha resposta original postada é considerada 'old school'. No entanto, nesse caso, eu definitivamente examinaria os formatos de arquivo usados ​​por .ibd e / ou ibdata1.

RolandoMySQLDBA
fonte