1. Entendiendo la Arquitectura InnoDB

Antes de profundizar en técnicas de recuperación, es esencial entender cómo InnoDB almacena datos. Este conocimiento es crucial para una planificación efectiva de recuperación.

1.1 Estructura de Archivos InnoDB

InnoDB usa varios tipos de archivos para almacenar datos:

Tipo de Archivo Ubicación Propósito
Archivos .ibd /var/lib/mysql/nombre_base/ Archivos de tablespace individuales (modo file-per-table)
ibdata1 /var/lib/mysql/ Tablespace del sistema (diccionario de datos, logs de undo, buffer de cambios)
ib_logfile0/1 /var/lib/mysql/ Logs de redo para recuperación de crash
Archivos .frm /var/lib/mysql/nombre_base/ Definiciones de esquema de tabla (solo MySQL 5.x)
Archivos .sdi Incrustado en .ibd (MySQL 8.0+) Información de Diccionario Serializada

1.2 Estructura de Página InnoDB

InnoDB organiza los datos en páginas (16KB por defecto). Cada página contiene un encabezado, cola y área de datos. El encabezado incluye checksums para detección de corrupción.

Estructura de Página InnoDB (16KB por defecto):
┌─────────────────────────────────────────┐
│ Encabezado de Archivo (38 bytes)        │
│   - Checksum, Número de Página, LSN     │
├─────────────────────────────────────────┤
│ Encabezado de Página (56 bytes)         │
│   - Tipo de página, conteo de registros │
├─────────────────────────────────────────┤
│ Registros Infimum + Supremum (26 bytes) │
├─────────────────────────────────────────┤
│ Registros de Usuario                    │
│   - Datos reales de filas               │
├─────────────────────────────────────────┤
│ Espacio Libre                           │
├─────────────────────────────────────────┤
│ Directorio de Página                    │
├─────────────────────────────────────────┤
│ Cola de Archivo (8 bytes)               │
│   - Verificación de checksum            │
└─────────────────────────────────────────┘

1.3 File-Per-Table vs Tablespace Compartido

Modo File-Per-Table (Recomendado)

Cuando innodb_file_per_table=ON (por defecto desde MySQL 5.6), cada tabla tiene su propio archivo .ibd. Esto hace la recuperación más fácil porque puede trabajar con archivos de tabla individuales en lugar de un tablespace compartido masivo.

2. Tipos de Corrupción InnoDB

Entender el tipo de corrupción ayuda a determinar el mejor enfoque de recuperación.

2.1 Errores de Checksum de Página

[ERROR] InnoDB: Database page corruption on disk or a failed file read
[ERROR] InnoDB: Page [page id: space=5, page number=127] log sequence number 123456789

Este es el tipo de corrupción más común. El checksum almacenado de la página no coincide con el checksum calculado, indicando modificación de datos después de escribir (error de disco, corrupción de memoria o escritura incompleta).

2.2 Errores de Número de Secuencia de Log (LSN)

[ERROR] InnoDB: Page [page id: space=0, page number=5] log sequence number 293847192847
is in the future! Current system log sequence number 182736451827.

El LSN de la página es mayor que el LSN actual del log de redo. Esto usualmente sucede después de:

  • Copiar archivos de datos sin procedimientos de backup apropiados
  • Restaurar desde backups inconsistentes
  • Snapshots de VM sin quiesce de la base de datos

2.3 Desajuste de ID de Tablespace

[ERROR] InnoDB: Tablespace id 47 in file ./mydb/orders.ibd differs from the expected tablespace id 52

El ID interno de tablespace en el archivo .ibd no coincide con lo que InnoDB espera. Común después de copiar archivos .ibd entre servidores o después de operaciones ALTER TABLE incorrectas.

3. Diagnóstico de Corrupción InnoDB

3.1 Revisando el Log de Errores de MySQL

El primer paso es siempre examinar el log de errores de MySQL:

# Encontrar ubicación del log de errores
mysql -e "SHOW VARIABLES LIKE 'log_error';"

# Ubicaciones comunes:
# /var/log/mysql/error.log (Debian/Ubuntu)
# /var/log/mysqld.log (CentOS/RHEL)
# /var/lib/mysql/*.err (Windows)

# Buscar mensajes de corrupción
grep -i "corrupt\|error\|warning" /var/log/mysql/error.log | tail -100

3.2 Usando innochecksum

innochecksum es una utilidad de línea de comandos que verifica la integridad de archivos InnoDB sin iniciar MySQL.

# Verificar un solo archivo .ibd
innochecksum /var/lib/mysql/mydb/orders.ibd

# Verificar con salida detallada
innochecksum -v /var/lib/mysql/mydb/orders.ibd

# Verificar ibdata1
innochecksum /var/lib/mysql/ibdata1

4. Métodos Nativos de Recuperación MySQL

4.1 Parámetro innodb_force_recovery

El parámetro innodb_force_recovery fuerza a InnoDB a iniciar a pesar de la corrupción. Cada nivel habilita recuperación más agresiva (y deshabilita más características).

Nivel Nombre Efecto
1 SRV_FORCE_IGNORE_CORRUPT Ignora páginas corruptas durante escaneos
2 SRV_FORCE_NO_BACKGROUND Previene que hilos en segundo plano se ejecuten
3 SRV_FORCE_NO_TRX_UNDO No ejecuta rollbacks de transacciones después de recuperación de crash
4 SRV_FORCE_NO_IBUF_MERGE No procesa operaciones de merge del buffer de inserción
5 SRV_FORCE_NO_UNDO_LOG_SCAN No mira logs de undo al iniciar
6 SRV_FORCE_NO_LOG_REDO No realiza roll-forward del log de redo
Advertencia Importante

En niveles 4 y superiores, InnoDB es solo lectura. No puede ejecutar INSERT, UPDATE, DELETE u operaciones DDL. El objetivo es hacer SELECT de datos y volcarlos a una nueva base de datos.

# Paso 1: Detener MySQL
sudo systemctl stop mysql

# Paso 2: Editar configuración
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

# Agregar bajo [mysqld]:
innodb_force_recovery = 1  # Comenzar con 1, aumentar si es necesario

# Paso 3: Iniciar MySQL
sudo systemctl start mysql

# Paso 4: Si inicia, volcar datos inmediatamente
mysqldump -u root -p --all-databases > recovery_dump.sql

# Paso 5: Si nivel 1 falla, intentar niveles más altos (2, 3, 4, 5, 6)
# ¡Remover el parámetro después de la recuperación!

5. DBRECOVER: Recuperación Avanzada

Cuando los métodos nativos de recuperación MySQL fallan—MySQL no inicia ni siquiera con innodb_force_recovery=6, o los datos están demasiado corruptos para mysqldump— DBRECOVER para MySQL proporciona una solución de último recurso.

5.1 Cómo Funciona DBRECOVER

Acceso Directo a Archivos

DBRECOVER lee archivos .ibd directamente a nivel de página, evitando MySQL completamente. Analiza estructuras de página InnoDB, extrae datos de fila y reconstruye registros—incluso de páginas que MySQL rechazaría como corruptas.

Capacidades clave:

  • Bypass de Checksum: Ignora errores de checksum de página para extraer datos legibles
  • Auto-Detección de Esquema: Detecta tipos de columna de archivos .frm o patrones de datos de página
  • Recuperación de Página Parcial: Extrae filas válidas de páginas parcialmente corruptas
  • Sin MySQL Requerido: Trabaja en archivos .ibd independientes sin servidor en ejecución
  • Múltiples Formatos de Exportación: SQL INSERT, CSV o carga directa a base de datos

5.2 Flujo de Trabajo de Recuperación con DBRECOVER

1Preparar Entorno de Recuperación

Copie archivos corruptos a una ubicación segura. Nunca trabaje directamente en datos de producción.

# Detener MySQL (si está ejecutándose)
sudo systemctl stop mysql

# Copiar directorio de datos
mkdir /recovery
cp -r /var/lib/mysql/mydb /recovery/
cp /var/lib/mysql/ibdata1 /recovery/  # Si es necesario para diccionario

2Iniciar DBRECOVER

Inicie DBRECOVER para MySQL y abra el archivo .ibd.

# Linux
./dbrecover-mysql.sh

# Windows
dbrecover-mysql.bat

# En la GUI de DBRECOVER:
# File → Open IBD File → Seleccione orders.ibd

3Cargar Esquema (si está disponible)

Para mejores resultados, proporcione el esquema de tabla vía archivo .frm o definición SQL.

# Opción A: Cargar archivo .frm (MySQL 5.x)
# Schema → Load FRM File → Seleccione orders.frm

# Opción B: Ingresar sentencia CREATE TABLE
# Schema → Enter SQL Definition → Pegar CREATE TABLE...

4Escanear y Previsualizar Datos

DBRECOVER escanea el archivo y muestra las filas recuperables.

# La herramienta muestra:
# - Total de páginas escaneadas
# - Páginas válidas vs corruptas
# - Conteo de filas recuperables
# - Vista previa de datos en grid

5Exportar Datos Recuperados

Exporte datos a formato SQL o CSV para importar en una nueva base de datos.

# Opciones de exportación:
# - Sentencias SQL INSERT
# - Archivo CSV
# - Conexión directa a base de datos

# Ejemplo de salida SQL:
INSERT INTO orders (id,customer_id,total,created_at) 
VALUES (1,100,299.99,'2025-01-15 10:30:00');
...

6Importar a Nueva Base de Datos

Cargue datos recuperados en una instancia MySQL limpia.

# Crear nueva base de datos
mysql -u root -p -e "CREATE DATABASE mydb_recovered;"

# Importar datos recuperados
mysql -u root -p mydb_recovered < recovered_orders.sql

# Verificar datos
mysql -u root -p -e "SELECT COUNT(*) FROM mydb_recovered.orders;"

6. Escenarios Comunes de Recuperación

6.1 Recuperación de DROP DATABASE

Cuando una base de datos es eliminada accidentalmente, los archivos pueden seguir existiendo en disco hasta que sean sobrescritos. ¡Actúe inmediatamente!

# INMEDIATAMENTE detener MySQL para prevenir sobrescrituras
sudo systemctl stop mysql

# Verificar si los archivos aún existen
ls -la /var/lib/mysql/dropped_db/

# Si los archivos no están, intentar herramientas de recuperación de datos
# (photorec, testdisk, extundelete)

# Una vez que los archivos .ibd sean recuperados, use DBRECOVER para extraer datos

6.2 Recuperación de TRUNCATE TABLE

TRUNCATE vs DELETE

TRUNCATE TABLE desasigna páginas pero no sobrescribe datos inmediatamente. DBRECOVER puede escanear páginas huérfanas y recuperar datos truncados, pero la tasa de éxito disminuye con el tiempo a medida que las páginas se reutilizan.

6.3 Recuperación de ibdata1 Corrupto

Si ibdata1 (tablespace del sistema) está corrupto, MySQL no puede iniciar. DBRECOVER puede trabajar con archivos .ibd individuales incluso cuando ibdata1 está dañado.

# Con modo file-per-table, puede recuperar tablas individualmente:
# 1. Copiar todos los archivos .ibd a ubicación de recuperación
# 2. Abrir cada archivo .ibd en DBRECOVER
# 3. Proporcionar esquema (de backup, documentación o auto-detectar)
# 4. Exportar datos de cada tabla

7. Mejores Prácticas de Prevención

7.1 Estrategia de Backup

# Habilitar logging binario para recuperación point-in-time
[mysqld]
log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 14

# Backups regulares con mysqldump
mysqldump --single-transaction --routines --triggers \
  --all-databases > backup_$(date +%Y%m%d).sql

# O usar Percona XtraBackup para backups en caliente
xtrabackup --backup --target-dir=/backup/$(date +%Y%m%d)

7.2 Configuración InnoDB

[mysqld]
# Habilitar file-per-table (recuperación más fácil)
innodb_file_per_table = ON

# Habilitar checksums
innodb_checksum_algorithm = crc32

# Buffer de doble escritura (protege contra escrituras parciales de página)
innodb_doublewrite = ON

# Configuración de flush para durabilidad
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

8. Preguntas Frecuentes

P: ¿Puedo recuperar datos de una base de datos eliminada?

Posiblemente, si actúa rápidamente. Detenga MySQL inmediatamente para prevenir sobrescrituras de archivos, luego use herramientas de recuperación de datos para encontrar archivos .ibd eliminados. Una vez recuperados, use DBRECOVER para extraer los datos. La tasa de éxito depende de cuánta actividad de disco ocurrió después del DROP.

P: ¿Cuál es la diferencia entre recuperación de .ibd e ibdata1?

Los archivos .ibd contienen datos de tabla individual (con modo file-per-table), mientras que ibdata1 contiene el tablespace del sistema (diccionario de datos, logs de undo). Recuperar archivos .ibd individuales es más fácil porque puede trabajar tabla por tabla. La corrupción de ibdata1 es más severa ya que afecta toda la estructura de la base de datos.

P: ¿Necesito los archivos .frm para la recuperación?

Para MySQL 5.x, los archivos .frm contienen definiciones de esquema de tabla. Sin ellos, DBRECOVER debe detectar tipos de columna heurísticamente, lo cual funciona pero requiere verificación manual. MySQL 8.0+ almacena el esquema en formato SDI dentro del propio archivo .ibd.

¿Necesita Asistencia Experta?

Para escenarios complejos de recuperación MySQL InnoDB donde los métodos estándar han fallado, nuestros expertos en recuperación de bases de datos están disponibles 24/7.

Descargar DBRECOVER para MySQL →

Contáctenos en [email protected]