Cómo reparar un espacio de tablas corrupto en InnoDB y recuperar bases de datos MySQL en «Crash Recovery»

El motor de almacenamiento InnoDB de MySQL/MariaDB es altamente transaccional y robusto gracias a sus archivos de registro de rehacer (Redo Logs / ib_logfile). Sin embargo, cuando se produce un apagado abrupto del servidor (corte eléctrico, kernel panic o reinicio forzado del sistema host), el proceso de recuperación en el arranque (Crash Recovery) puede entrar en un bucle infinito de reinicios.

Esto deriva en errores de lectura tipo «InnoDB: Database page corruption on disk» o «InnoDB: Page may be corrupted, cannot continue», bloqueando el acceso de aplicaciones críticas como ERPs, tiendas online o bases de datos de clientes.

A continuación, analizamos la metodología oficial para forzar la extracción de tablas dañadas y reconstruir el archivo de transacciones sin perder información.

El ciclo de recuperación de InnoDB y el parámetro innodb_force_recovery

Cuando el motor InnoDB detecta que una página de datos no coincide con su suma de comprobación (checksum) en el disco, detiene el proceso por seguridad para evitar propagar la corrupción a la base de datos principal.

Para saltarse esta protección y poder iniciar el motor exclusivamente en modo de solo lectura para volcar la información (dump), MySQL incluye la directiva innodb_force_recovery, la cual admite valores escalonados de 1 a 6.

Paso 1: Configurar el modo de recuperación forzada en my.cnf

ADVERTENCIA: No apliques de entrada un nivel 6. Se debe empezar en el nivel 1 e ir incrementando progresivamente hasta que el servicio MySQL consiga arrancar sin cerrarse.

  1. Abre el archivo de configuración del servidor MySQL (habitualmente /etc/mysql/mysql.conf.d/mysqld.cnf o /etc/my.cnf).
  2. Localiza la sección [mysqld] y añade la siguiente directiva con valor 1:

Ini, TOML

[mysqld]
innodb_force_recovery = 1
  1. Intenta arrancar el servicio desde la consola del sistema:sudo systemctl start mysql

Nivel de acción según la severidad del daño:

Nivel (1-6)Efecto de la ConfiguraciónUso Recomendado
1 (SRV_FORCE_IGNORE_CORRUPT)Ignora páginas con datos corruptos detectados en el checksum.Corrupción leve de índices secundario.
2 (SRV_FORCE_NO_BACKGROUND)Impide la ejecución de hilos de limpieza en segundo plano (purge operations).Fallos en operaciones de mantenimiento.
3 (SRV_FORCE_NO_TRX_UNDO)No ejecuta el proceso de rollback de transacciones no completadas.Transacciones atascadas en la cola.
4 (SRV_FORCE_NO_IBUF_MERGE)No calcula las inserciones de buffer pendientes.Corrupción en el buffer de inserción.
5 (SRV_FORCE_NO_UNDO_LOG_SCAN)Omite los registros de deshacer (Undo Logs) al iniciar.Daño estructural en el espacio de tablas del sistema.
6 (SRV_FORCE_NO_LOG_REDO)Ignora por completo los Redo Logs para arrancar en frío.Corrupción grave de los archivos ib_logfile.

Si con el valor 1 el servicio vuelve a caerse, edita de nuevo el archivo my.cnf, sube a 2, y repite el intento de arranque hasta dar con el nivel estable.

Paso 2: Exportar la base de datos a un archivo SQL comprimido

Una vez que el servicio de base de datos ha conseguido arrancar (en modo lectura), el objetivo principal es extraer todos los esquemas e información intacta antes de regenerar la infraestructura.

  1. Ejecuta un volcado completo de la base de datos afectada utilizando mysqldump:

Bash

mysqldump -u root -p --opt --default-character-set=utf8mb4 mi_base_de_datos > copia_seguridad_recuperada.sql
  1. Verifica que el archivo .sql resultante se haya generado con un tamaño coherente y contenga la estructura de las tablas.

Paso 3: Reconstruir el motor InnoDB y restaurar los datos

Una vez volcada la información, el espacio de tablas dañado debe ser eliminado para evitar que el servidor vuelva a fallar al reiniciar normalmente.

  1. Detén el servicio MySQL:sudo systemctl stop mysql
  2. Elimina la directiva innodb_force_recovery (o coméntala con un #) en el archivo my.cnf.
  3. Borra la base de datos corrupta desde MySQL o desde la estructura del sistema (haz un backup preventivo del directorio de datos antes de proceder):Bashsudo rm -rf /var/lib/mysql/mi_base_de_datos
  4. Inicia el servicio MySQL con normalidad:sudo systemctl start mysql
  5. Vuelve a crear la base de datos e importa el archivo .sql limpio que generaste en el Paso 2:Bashmysql -u root -p -e "CREATE DATABASE mi_base_de_datos CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" mysql -u root -p mi_base_de_datos < copia_seguridad_recuperada.sql

Preguntas Frecuentes (FAQ)

¿Puedo ejecutar sentencias UPDATE, INSERT o DELETE mientras innodb_force_recovery está activo?

No. Cuando el parámetro innodb_force_recovery está activado en un valor mayor que 0, el motor deshabilita todas las operaciones de escritura para evitar que la corrupción se extienda a otras tablas del sistema. Solo se permiten consultas SELECT.

¿Qué ocurre si el archivo ibdata1 o los registros ib_logfile están completamente inservibles?

Si el arranque falla incluso con el nivel 6, será necesario recrear el directorio de datos (datadir) por completo ejecutando mysqldb-install-db o reinstalando el paquete del servidor de base de datos e importando las copias de seguridad de los volcados SQL previa configuración.

Deja un comentario