oscarmlage oscarmlage

Restaurar InnoDB partiendo solamente de archivos

Written by oscarmlage on

El título suena muy a "la he liado parda por favor échame una mano". En efecto. Básicamente (y creo que lo repetiré varias veces a lo largo del artículo para que queda claro), la mejor solución para no llegar nunca a este punto es hacer dumps de vuestras bases de datos.

Olvidaos de rsync, rdiff-backup o cualquier solución de backups que tengáis implementada contra ficheros, InnoDB no es MyISAM. Pero bueno, como he leído en alguna de las referencias que pongo al final del artículo, dejemos de llorar, nuestros datos todavía deberían estar ahí.

Requisitos

Para restaurar una base de datos InnoDB desde archivos (frm y binary logs), sin tener dumpeado completo, debemos tener lo siguiente:

Si tienes lo necesario podemos seguir con la intentona.

Restaurando

El primer paso es restaurar los ficheros del día adecuado, pongamos que queremos hacerlo de hace 10 días a través de nuestro rdiff-backup:

# mkdir ~/restaura/
# rdiff-backup -r 10D /backup/mysql/ibdata1 ~/restaura/ibdata1
# rdiff-backup -r 10D /backup/mysql/ib_logfile0 ~/restaura/ib_logfile0
# rdiff-backup -r 10D /backup/mysql/ib_logfile1 ~/restaura/ib_logfile1
# rdiff-backup -r 10D /backup/mysql/database ~/restaura/database/

Los pasamos a la máquina en la que vayamos a ejecutar el aislado de mysql:

# scp -r ~/restaura/ oscar@Air.local:~/restaura-innodb/

Aislando MySQL

Lo primero que hemos de tener claro es que para restaurar desde estos archivos en este escenario es que tenemos que aislar un MySQL solamente para ésto. Es decir, coger un MySQL que tengamos por ahí parado o sin mucho funcionamiento para ponerlo a funcionar sólo con la base de datos que vamos a resturar.

¿Por qué?, porque los logs binarios (ib_log e ibdata) guardan información de todas las bases de datos del servidor, así que no podemos sobreescribir los ya existentes, para ello podemos hacer una copia del directorio que actualmente está funcionando en ese servidor que vamos a usar (para posteriormente dejarlo todo tal y como estaba).

En este caso concreto voy a utilizar el de mi Mac. Lo primero de todo es parar el servidor, Luego hago copia de seguridad y preparo el nuevo directorio mysql5 para que el servidor lo detecte adecuadamente:

$ sudo kill -9 `ps aux | grep mysql | awk '{print $2}'` ; ps aux | grep mysql
# cd /opt/local/var/db/
# mv mysql5 mysql5_backup
# mkdir mysql5
# cp mysql_backup/mysql-bin* mysql5
# cp -r mysql_backup/mysql/ mysql5

Agregando los datos restaurados

Ahora que tenemos un entorno mysql mínimo funcional (todavía no hemos arrancado de nuevo el servidor), vamos a agregar la base de datos que hemos restaurado para poder acceder a los datos:

# cp -r ~/restaura-innodb/ib_logfile* /opt/local/var/db/mysql5/
# cp -r ~/restaura-innodb/ibdata1 /opt/local/var/db/mysql5/
# cp -r ~/restaura-innodb/database /opt/local/var/db/mysql5/

El nuevo directorio mysql5 tiene que quedar tal que así:

$ ls
Air.local.err       mysql-bin.000002    mysql-bin.000010    mysql-bin.000018
Air.local.pid       mysql-bin.000003    mysql-bin.000011    mysql-bin.000019
ib_logfile0     mysql-bin.000004    mysql-bin.000012    mysql-bin.000020
ib_logfile1     mysql-bin.000005    mysql-bin.000013    mysql-bin.000021
ibdata1         mysql-bin.000006    mysql-bin.000014    mysql-bin.index
database/        mysql-bin.000007    mysql-bin.000015
mysql/           mysql-bin.000008    mysql-bin.000016
mysql-bin.000001    mysql-bin.000009    mysql-bin.000017

Comprobamos que todos los ficheros tienen permisos para el usuario mysql (_mysql:_mysql en el caso concreto del MySQL de OSX instalado vía Macports), y arrancamos de nuevo el servidor. Si todo ha ido bien y tenemos algo de suerte, deberíamos tener acceso a los datos de esa base de datos que se nos resistía.

Volverlo a dejar todo como estaba

Este punto no es recomendable del todo. Como lección aprendida no deberíamos dejar todo como estaba: deberíamos mejorar las copias de seguridad para que no vuelva a pasar esta pirula del InnoDB.

Sin embargo si nos referimos al servidor MySQL que aislamos, como hemos sido previsores, será sencillo dejarlo como estaba:

# cd /opt/local/var/db/
# mv mysql5 mysql5_restauraciones
# mv mysql5_backup mysql5

Y reiniciamos el servidor.

Insistiendo en los dumps

La mejor forma de hacer una copia de seguridad de una base de datos (en general, pero sobre todo si hablamos de InnoDB) es haciendo dumps completos, así que es importante repetir hasta la saciedad que la práctica aquí descrita no es sana, ni recomendable, ni segura en absoluto. Ni para los sysadmins.

Referencias