Como recuperar tablespace InnoDB corrompida no MySQL sem perda de dados
Por Kevin Marcondes · Publicado em · 8 min de leitura
Precisa recuperar tablespace InnoDB corrompida no MySQL sem perda de dados? Pare as escritas, faça uma cópia segura e siga um plano previsível. Abaixo você encontra sinais, causas, estratégias e procedimentos práticos (innodb_force_recovery, dump lógico e IMPORT TABLESPACE) para maximizar a chance de recuperar tudo com integridade.
Sinais de corrupção e quando interromper o servidor
O primeiro passo é reconhecer o problema e parar de agravar os danos. Assim que detectar corrupção, interrompa as escritas imediatamente e planeje a recuperação em um clone/snapshot.
Procure no error log mensagens típicas e confirme o alcance da falha (uma tabela isolada ou o tablespace do sistema).
- InnoDB: Page corruption: space id and page no stored in the page, read in file
- InnoDB: Space id in the header is wrong
- [ERROR] InnoDB: Corruption of an index tree
- InnoDB: Missing or invalid ibd file (table is missing)
- InnoDB: Log sequence number is in the future
- Got error -1 from storage engine ao abrir tabela
Causas prováveis e como avaliar o impacto
Corrupções costumam estar ligadas a falhas de disco/RAID, queda de energia, cache de gravação sem bateria, parâmetros de durabilidade relaxados ou bugs em versões antigas. Avalie a extensão: se o erro ocorre apenas ao acessar uma tabela, é provável que seja o .ibd dela; se o servidor não inicia ou reclama do dicionário, o alvo pode ser o tablespace do sistema (ibdata1).
Antes de qualquer tentativa: crie um backup físico frio do datadir, redo/undo (ib_logfile*, undo_00*), temporários (ibtmp1) e my.cnf. Se você usa LVM, um snapshot ajuda a congelar o estado sem downtime adicional. Veja uma forma automatizada de snapshots com upload incremental em S3 neste guia: LVM snapshots + Restic em S3.
Plano de recuperação sem perda (visão geral)
O objetivo é extrair dados logicamente íntegros e reconstruir o InnoDB em ambiente limpo. Na prática, a menor perda ocorre quando o servidor ainda sobe em modo de recuperação e permite SELECTs consistentes.
- Congelar estado: cópia fria ou snapshot do volume.
- Subir com innodb_force_recovery (níveis crescentes) apenas para leitura e extrair dumps lógicos.
- Priorizar dump por base/tabela com --single-transaction para minimizar locks.
- Se a corrupção for isolada em uma tabela, tentar dump só dela ou IMPORT TABLESPACE a partir de um backup consistente.
- Reconstruir o dicionário do InnoDB em ambiente limpo e restaurar os dumps.
- Validar integridade e counts antes de voltar o tráfego.
Estratégias por cenário (mapa rápido)
Use este quadro para decidir o caminho inicial. Seja conservador: não execute escritas enquanto estiver com innodb_force_recovery ativo.
| Cenário | Risco de perda | Ação sugerida |
|---|---|---|
| Uma tabela específica falha ao abrir | Baixo a moderado | Tentar SELECT/dump só desta tabela; se tiver backup com .cfg, usar DISCARD/IMPORT TABLESPACE. |
| Servidor não inicia; erros no dicionário (ibdata1) | Alto | Subir com innodb_force_recovery e extrair dump lógico completo; depois reconstruir o InnoDB e restaurar. |
| Redo/undo inconsistentes após pane de energia | Moderado | Tentar iniciar com níveis baixos de innodb_force_recovery para permitir dump consistente; validar todas as tabelas. |
Procedimento A: servidor inicia com innodb_force_recovery
Defina innodb_force_recovery no my.cnf começando por 1 e subindo gradualmente até o menor nível que permita o start. Níveis acima de 3 são agressivos e desabilitam partes críticas do InnoDB. Nunca escreva no banco nesse modo; use apenas para SELECT/dump.
Com o servidor de pé, extraia dumps por schema e de objetos dependentes (rotinas, eventos, triggers) com transação consistente. Desative binlog na sessão de dump se necessário.
- Ordem: usuários/privs, schemas, tabelas, dados, rotinas, eventos, triggers, views.
- Isolar tabelas problemáticas para tratar no Procedimento B.
- Guardar o error log junto com os dumps para auditoria.
mysqldump \
--single-transaction --routines --events --triggers \
--hex-blob --default-character-set=utf8mb4 \
--databases suabase > dump_suabase.sql
# Dica: para casos difíceis, dumpe tabela a tabela
# mysqldump --single-transaction suabase tabela > suabase_tabela.sql
Procedimento B: corrupção limitada a uma tabela (.ibd)
Se apenas uma tabela falha e o resto está íntegro, tente primeiro extrair um dump lógico dela (SELECT/mysqldump). Caso possua um backup consistente da tabela com o par .ibd/.cfg (gerado por FLUSH TABLES ... FOR EXPORT), é possível reconstruí-la em uma instância limpa usando DISCARD/IMPORT TABLESPACE.
O esquema da tabela deve ser idêntico. Faça isso em uma cópia isolada, valide, e só então substitua em produção.
- Garantir innodb_file_per_table=ON.
- Esquema idêntico (mesmo charset/collation/índices).
- Usar .cfg correspondente ao .ibd do backup para evitar mismatch de space_id.
-- Na instância de recuperação
CREATE TABLE suabase.minhatabela (...definição idêntica...);
ALTER TABLE suabase.minhatabela DISCARD TABLESPACE;
-- Copiar o .ibd e o .cfg do backup consistente para o datadir da tabela
ALTER TABLE suabase.minhatabela IMPORT TABLESPACE;
Procedimento C: system tablespace (ibdata1) corrompido
Quando o dicionário do InnoDB está comprometido, a rota mais segura é salvar dados logicamente com innodb_force_recovery e depois reconstruir o InnoDB do zero em uma nova instância, restaurando a partir dos dumps.
O fluxo típico é: extrair todos os schemas e objetos, inicializar um datadir novo, recriar usuários/privs, restaurar dumps e validar integridade referencial.
- Inicializar novo datadir e redo/undo limpos.
- Restaurar por ordem que respeite chaves estrangeiras (ou temporariamente desativar FOREIGN_KEY_CHECKS e revalidar ao final).
- Executar CHECK TABLE e contar linhas para comparar com o ambiente original.
- Antes de voltar o tráfego, rode testes de aplicação e relatórios críticos.
Validação pós‑recuperação e prevenção
Antes de retomar a produção, valide dados e comportamento. Depois, enderece as causas para não repetir o incidente. Se você precisa de um plano de backup/restauração confiável, veja esta implantação com políticas e testes: Backups incrementais e criptografados em S3.
- Comparar contagens por tabela com SELECT COUNT(*) e amostras de somatórios críticos.
- CHECK TABLE nas principais tabelas InnoDB (entenda que é limitado, mas útil para detectar problemas óbvios).
- Reprocessar relatórios/chaves externas e observar o error log por um período.
- Infraestrutra: usar UPS, storage confiável, fsync, monitoramento de SMART/RAID.
- Configuração: innodb_flush_log_at_trx_commit=1 e sync_binlog=1 para durabilidade.
- Backups: rotina com snapshots + armazenamento externo; testes de restauração documentados. Veja também recuperação por PITR em outro SGBD para inspiração: recuperar tabela no PostgreSQL com point‑in‑time.
- Higiene do servidor: práticas de hardening e monitoramento reduzem riscos colaterais. Consulte o checklist de segurança para VPS Linux.
Perguntas frequentes
Posso usar REPAIR TABLE em InnoDB?
Não. REPAIR TABLE é voltado a MyISAM. Para InnoDB, a abordagem correta é iniciar com innodb_force_recovery, extrair dumps lógicos e, se necessário, reconstruir o tablespace ou importar a tabela a partir de backup consistente.
Qual nível de innodb_force_recovery devo usar?
Comece em 1 e aumente gradualmente até o menor nível que permita iniciar o servidor. Níveis acima de 3 são agressivos e servem apenas para leitura e extração. Nunca escreva dados neste modo para evitar agravar a corrupção.
É possível recuperar sem o arquivo .cfg da tabela?
Sem o .cfg criado por FLUSH TABLES ... FOR EXPORT, o IMPORT TABLESPACE pode falhar por incompatibilidades de metadata. Em geral, a alternativa mais segura é recuperar via dump lógico ou restaurar a tabela de um backup consistente que inclua o par .ibd/.cfg.
Quando devo preferir dump lógico a backup físico?
Em presença de corrupção, o dump lógico é geralmente mais seguro porque reinterpreta páginas válidas em nível SQL. Backups físicos copiam blocos; se a origem está corrompida, o problema persiste. Use o físico para clonar o estado e testar abordagens off-line.
Como evitar que a corrupção volte a acontecer?
Use hardware confiável (UPS, discos e controladoras com proteção de cache), monitore SMART/RAID, configure durabilidade (innodb_flush_log_at_trx_commit=1, sync_binlog=1), mantenha o sistema atualizado e implemente rotina de backups com testes de restauração documentados.
Caso crítico? Aja com método e preserve evidências
Congele o estado (snapshot/cópia), registre erros e trabalhe em uma instância de recuperação. Para estruturar backups e testes de restauração no dia a dia, busque o apoio de um DBA/consultor de confiança.
Ver opções de backup e recuperaçãoVeja também
- 502 Bad Gateway intermitente em Docker Compose com Nginx e PHP‑FPM: como diagnosticar e corrigir timeouts e excesso de conexões
- Como diagnosticar e capturar pacotes para intermitência de rede entre containers Docker no Debian
- Como reduzir tempo de recuperação após crash de servidor Linux com playbook Ansible e runbook de recuperação
- Como reduzir tempo de build e evitar artefatos duplicados em CI para monólitos PHP grandes