Uma tabela MyISAM marcada como danificada fica fora de uso até ser reparada, e o reparo reconstrói os arquivos a partir do que ainda pode ser lido. O reparo resolve a maior parte dos danos, mas pode descartar linhas e perder informações do cabeçalho. Por isso, a escolha da opção acompanha o defeito encontrado, sempre depois da preservação dos arquivos.
O que o reparo alcança
O reparo trabalha nos arquivos de dados e de índices, conforme a definição da tabela no MySQL. Ele refaz os índices que fazem parte dessa definição, mas não consulta a tabela de controle das ordens da aplicação nem recalcula as colunas derivadas. Um índice apagado da definição não volta com o reparo.
O reparo também não renumera os identificadores. As linhas que continuam na tabela mantêm os valores, mas as linhas ilegíveis e as que violam um índice de valores únicos podem ser descartadas.
Antes do reparo
- a cópia dos arquivos MYD, MYI e frm, com o serviço parado ou com a tabela fora de uso;
- as medidas de referência que ainda puderem ser lidas, como a contagem, o maior identificador e o próximo valor do contador;
- o espaço livre em disco para os arquivos temporários do reparo;
- uma janela de manutenção com tempo para o reparo terminar, porque a tabela fica bloqueada para leitura e para gravação durante todo o reparo, e um reparo interrompido deixa a tabela danificada e fora de uso.
As opções do reparo
- QUICK: o comando
REPAIR TABLE vendas QUICK;tenta reconstruir só o arquivo de índices, a partir das linhas do arquivo de dados. É a primeira opção quando o dano parece limitado aos índices. - Modo padrão: o comando
REPAIR TABLE vendas;reconstrói o arquivo de dados e o de índices, montando as chaves por ordenação. Serve quando o dano vai além dos índices. - EXTENDED: o comando
REPAIR TABLE vendas EXTENDED;monta os índices linha a linha, chave por chave. É bem mais lento e resolve alguns casos que a ordenação não resolve. - USE_FRM: o comando
REPAIR TABLE vendas USE_FRM;recria o arquivo de índices a partir da definição da tabela, quando o MYI sumiu ou tem o cabeçalho ilegível. Até o MySQL 5.7, a definição vem do arquivo frm, e, no MySQL 8, do dicionário de dados.
O EXTENDED do reparo não tem relação com o EXTENDED do CHECK TABLE. No reparo, a opção muda o método de montagem dos índices, e, na verificação, aprofunda a conferência.
O que o resultado mostra
O resultado do reparo termina com o status OK ou com Operation failed, e as linhas anteriores trazem os detalhes. O aviso Number of rows changed from 99990 to 99555 mostra que o cabeçalho registrava 99.990 linhas e que o reparo terminou com 99.555. Nesse caso, 435 linhas foram descartadas, mesmo com o status OK no fim. O primeiro número vem do cabeçalho, que também pode estar danificado, e por isso a conta da perda usa a contagem anotada antes do reparo. Esse aviso pode aparecer em qualquer opção, inclusive na QUICK, quando o arquivo de dados também está danificado.
Quando o arquivo de índices não existe, o reparo comum termina com a mensagem Can't find file e o status Operation failed, e apenas a opção USE_FRM consegue recriar o arquivo.
O contador depois do USE_FRM
O cabeçalho do MYI guarda o próximo valor do contador AUTO_INCREMENT. Quando o USE_FRM recria esse arquivo, o contador passa a ser o maior identificador existente mais um. Se as últimas linhas tinham sido apagadas, os números delas voltam a ser gerados, e as tabelas que ainda citam esses números passam a apontar para registros novos. O comando a seguir restabelece o valor anotado antes do reparo, aqui representado pelo número 100001:
ALTER TABLE vendas AUTO_INCREMENT = 100001;
O USE_FRM também descarta o controle dos espaços livres deixados por exclusões. Ele não deve ser usado em tabelas compactadas, porque pode alterar o conteúdo delas, e não funciona com tabelas particionadas.
O reparo pelo myisamchk
O myisamchk faz os mesmos reparos direto nos arquivos, executado na pasta do banco, com o serviço parado:
myisamchk --recover vendas: equivale ao modo padrão;myisamchk --recover --quick vendas: equivale à opção QUICK;myisamchk --safe-recover vendas: equivale à opção EXTENDED;myisamchk --recover --backup vendas: guarda uma cópia do arquivo de dados, com a extensão BAK, antes de alterá-lo.
O myisamchk não pode trabalhar sobre uma tabela que o servidor está usando, porque os dois alterariam os mesmos arquivos ao mesmo tempo.
Como escolher
O reparo começa pela opção de menor alcance capaz de tratar o defeito encontrado. Com a tabela acessível e o dano aparentemente limitado aos índices, a primeira tentativa é a QUICK. Quando ela falha, a mensagem indica o próximo passo. Uma falta de espaço se resolve com espaço, e não com outra opção, enquanto um dano nos dados leva ao modo padrão ou ao EXTENDED. O USE_FRM tem uma finalidade própria, a recriação do arquivo de índices, e não é a última etapa obrigatória de uma sequência.
No suporte
Depois de qualquer reparo, convém comparar a contagem, o maior identificador e o contador com os valores anotados antes, e procurar no resultado o aviso Number of rows changed. Linhas descartadas são uma perda a tratar, com a cópia preservada, mesmo quando o reparo termina com OK.
Para guardar
- O reparo reconstrói os arquivos MYD e MYI a partir da definição da tabela, sem conhecer as regras da aplicação.
- A QUICK refaz os índices, o modo padrão refaz dados e índices, e o EXTENDED usa um método mais lento.
- O USE_FRM recria o arquivo de índices e perde o contador AUTO_INCREMENT.
- O aviso Number of rows changed indica linhas descartadas, mesmo com o status OK.
- O myisamchk repara os arquivos diretamente, com o serviço parado.
O reparo terminou com o status OK e o aviso Number of rows changed from 99990 to 99555. Os dados foram preservados?
Não. O reparo descartou 435 linhas que não conseguiu recuperar. A tabela voltou a funcionar, mas essas linhas precisam ser localizadas e recuperadas a partir da cópia preservada ou de outra fonte, como os dados já enviados à matriz.
O arquivo de índices sumiu, e o reparo comum falhou. Qual é o caminho, e o que conferir depois?
O caminho é a opção USE_FRM, que recria o arquivo de índices a partir da definição da tabela. Depois do reparo, o contador AUTO_INCREMENT precisa ser comparado com o valor anotado antes e restabelecido, porque o USE_FRM o recalcula a partir do maior identificador existente.