Algunas situaciones de emergencia necesitan ciertas dosis de ingenio. Como por ejemplo recuperar una o varias bases de datos en MySQL a partir de los ficheros binarios porque no tenemos copia de ellos en SQL. Mala práctica, pero en algunos escenarios se puede dar.
En ese sentido veremos en este post cómo montar un segundo servidor MySQL en una máquina y volcar directamente los ficheros binarios para poder consultarlos y realizar la exportación de las Bases de Datos o tablas que nos interesen. De este modo no tenemos que tocar nada del servidor MySQL ya existente en la máquina de recuperación ni en sus datos.
Los ficheros de almacenamiento en MySQL
Los datos, registros, estructura de tablas y bases de datos se almacenan obviamente en ficheros. En las mayorías de instalaciones de Linux en /var/lib/mysql
. Ahí podremos distinguir varios tipos de ficheros, según el motor de BD que utilicemos. En Windows y otros sistema operativos la estructura es la misma aunque cambie la ubicación de la instalación.
Las distintas bases de datos se encuentran almacenadas en una estructura de directorios, correspondiendo cada uno a una bases de datos. Dentro de cada una contaremos con distintos ficheros .frm
que almacenan la estructura de las tablas independientemente de si es un motor MyISAM, InnoDB, etc.
Si hemos utilizado para almacenar los datos el formato MyISAM contaremos además dentro del directorio de ficheros de datos .myd
y ficheros índice .myi
de modo que cada base de datos se encuentra compartimentada en un directorio.
Si por el contrario hemos utilizado un formato InnoDB los datos se almacenarán por defecto en ficheros ibdata
e .ibd
de forma común para todas las bases de datos en el mismo directorio /var/lib/mysql
.
Los datos relativos al acceso, tablas, permisos, etc se encuentran almacenados en la Base de Datos mysql
que es utilizada por el propio servidor MySQL como configuración. Esta base de datos es especialmente importante y deberemos de tenerla en cuenta más adelante en nuestra tarea de recuperación.
Diferencias entre una copia binaria de datos y en SQL
Si eres precavido generalmente prepararás una tarea cron
o bien manualmente realizarás copias de tus bases de datos con mysqldump. Las copias de bases de datos realizadas con esta utilidad del propio servidor tienen como ventaja que realizan una copia total del contenido, estructura, etc y luego es posible importarlas y recuperarlas independientemente de la versión de servidor MySQL que estemos utilizando.
En cambio una copia binaria de los ficheros «a lo bruto» es, si bien más rápida, tiene ciertos riesgos dado que debemos de asegurarnos que la versión del servidor MySQL es la misma. Y aún así puede haber problemas (formatos de ficheros, sistemas operativos distintos, etc). Está claro que no es una buena opción y se debe usar sólo como emergencia o como única alternativa en procesos de migración.
Arrancando una segunda instancia de nuestro servidor MySQL
En cualquier caso este artículo presupone como escenario una situación de emergencia en la cual ante quizás un fallo de disco duro sólo hemos podido rescatar los ficheros de datos y debemos de recuperar los datos desde otro equipo y otra instalación de MySQL.
Para ello crearemos los nuevos directorios necesarios y les asignaremos sus pertinentes permisos. Uno para los datos en binario y otro para los ficheros de logs. De este modo garantizamos la estanqueidad entre las distintas instancias.
mkdir /var/lib/mysql2 mkdir /var/log/mysql2 |
Copiar y configurar la nueva instancia del servidor MySQL
Lo que haremos será copiar la configuración original y crear un nuevo fichero cambiando los datos correspondientes al socket, puerto, al directorio de logs y la ubicación de los ficheros de esta nueva instancia.
cp /etc/mysql/my.cnf /etc/mysql2/my.cnf |
Reproduzco a continuación algunos de los datos que cambié en el segundo fichero de configuración, manteniendo el resto iguales.
[client] port = 3307 socket = /var/run/mysqld/mysqld2.sock [mysqld_safe] socket = /var/run/mysqld/mysqld2.sock log_error=/var/log/mysql/mysql2_error.log [mysqld] user = mysql pid-file = /var/run/mysqld/mysqld2.pid socket = /var/run/mysqld/mysqld2.sock port = 3307 basedir = /usr datadir = /var/lib/mysql2 tmpdir = /tmp log_error=/var/log/mysql2/mysql_error.log general_log_file = /var/log/mysql2/mysql.log general_log = 1 |
Instalación y puesta en marcha
Como pensarás sigue estando vacío el directorio /var/lib/mysql2
. Obviamente aquí es donde incluiremos los ficheros de datos a recuperar.
Sin embargo seguramente no será tan fácil como incluir los ficheros en este directorio para que el servidor arranque. Probablemente si lo intentaras arrancar ahora te devolvería un feo error y volverías al prompt sin levantar el servicio. Esto es debido a que seguramente el formato y estructura de las BD no sean iguales a la versión que estés corriendo en tu sistema, así que necesitaremos una Base de Datos mysql
nueva para poder arrancar el servidor, y una vez en marcha, poder lanzar la utilidad mysql_upgrade para poder leer el contenido de las bases de datos. Este ejecutable revisa y adapta las bases de datos a la versión MySQL que estamos corriendo y se utiliza en las actualizaciones de MySQL.
Así pues nos proporcionaremos una nueva instalación mysql que incluye por supuesto la preciada base de datos mysql adaptada a la versión de MySQL que estamos corriendo. Como veréis está ubicado en /temp
dado que es un recurso temporal para obtener sólo el directorio mysql de una instalación nueva.
mysql_install_db --user=mysql --datadir=/tmp/mysql/ |
Ahora lo que nos quedará es copiar dicha carpeta /tmp/mysql/mysql
a /var/lib/mysql2
.
cp /tmp/mysql/mysql /var/lib/mysql2/mysql |
Una vez todos los datos en su sitio nos aseguramos por supuesto que el usuario mysql tiene los permisos necesarios de acceso al directorio de datos y de logs en los nuevos directorios.
chown -R mysql.mysql /var/lib/mysql2/ chown -R mysql.mysql /var/log/mysql2 |
Además, como es un nuevo servidor por defecto no cuenta con ninguna contraseña en root, así que nos permitirá acceder a los datos y recuperar la información que necesitemos sin tener que acordarnos de la password original. Ya podemos arrancar el servidor.
mysqld_safe --defaults-file=/etc/mysql2/my.cnf & |
Si todo va bien obtendremos un mensaje como este:
mysqld_safe Logging to '/var/log/mysql2/mysql_error.log' mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql2 |
El siguiente paso es muy importante. Que utilicemos MySQL no nos garantiza la compatibilidad entre versiones como hemos dicho antes, así que es mejor una vez en marcha el servidor revisemos en busca de errores las bases de datos y para que las incluya en la nueva instancia. Para ello es necesario que esté corriendo el servidor.
mysql_upgrade --socket=/var/run/mysqld/mysqld2.sock |
El proceso no es muy largo. Además como veis utilizo el socket como modo de comunicación. Manías personales. 😉
Ahora la prueba definitiva. Nos conectaremos como usuario root a la segunda instancia del servidor y accederemos a los datos.
mysql --socket=/var/run/mysqld/mysqld2.sock -u root |
Si habeís podido conectaros y podéis listar y ver las bases de datos y tablas ya es muy fácil recuperarlas y obtener un volcado de todas ellas con mysqldump. Supongo que esa parte es fácil, ¿no? 😉
Volcando los datos a formato SQL
Para volcar una base de datos en concreto:
mysqldump --socket=/var/run/mysqld/mysqld2.sock -u root base_datos > /tmp/base_datos.sql |
Una vez hayáis terminado, para cerrar sólo esta instancia MySQL:
mysqladmin --socket=/var/run/mysqld/mysqld2.sock shutdown |
Espero que os sea de utilidad si tenéis la mala suerte de tener que necesitarlo.
Fuentes:
http://lasanthals.blogspot.com.es/2012/09/running-multiple-instances-of-mysql-on.html
http://dev.mysql.com/doc/refman/5.0/es/backing-up.html
http://dev.mysql.com/doc/refman/5.0/es/myisam-storage-engine.html
http://dev.mysql.com/doc/refman/5.0/es/mysqldump.html
http://dev.mysql.com/doc/refman/5.0/en/mysql-upgrade.html
Autor:
Última actualización:
Excelente articulo muy util Oscar.
Muchas gracias!