sábado, 13 de julio de 2019

MySQL Binlogs :: Cómo recuperar

Entonces me di cuenta de que no había hecho una publicación sobre esto después de esta situación que surgió recientemente.

Aquí está el escenario: una copia de seguridad se realizó a medianoche, utilizaron volcados de MySQL por base de datos. Luego, a las diez de la mañana del día siguiente, la base de datos se estrelló. Una serie de eventos sucedieron antes de que me llamaran, pero lo llevaron a una versión de la base de datos con tablas MyISAM y los archivos IBD que faltan en el espacio de tablas.

Así que la opción 1, la restauración de la copia de seguridad nos llevaría a la medianoche y perderíamos horas de datos. Opción 2, reimportamos los miles de archivos ibd y guardamos todo. Luego tuvimos la opción 3, restaurar desde la copia de seguridad, luego aplicar los registros bin para los cambios recientes.

Para hacerlo más interesante, no tenían todos los archivos ibd que me dijeron, y vi algunos faltantes. Así que no estoy seguro de cómo fue posible, pero la opción 2 se convirtió en una opción no válida. Ellos, por supuesto, querían la menor pérdida de datos posible, así que optamos por la opción 3.

Para hacerlo de forma segura, inicié otra instancia de MySQL en el puerto 3307. Esto me permitió trabajar en un lugar seguro mientras el tráfico tenía acceso de lectura a los datos de MyISAM en la instancia del puerto 3306.

Una vez que todos los archivos de copia de seguridad se descomprimieron e importaron en la instancia 3307, pude concentrarme en los archivos binlog.

Al principio, este concepto suena mucho más riesgoso de lo que realmente es. En realidad es bastante sencillo y sencillo.

Así que primero tienes que encontrar los datos que buscas. Una revisión de los archivos binlog le da una ventaja en cuanto a qué archivos son relevantes. En mi caso, de alguna manera lograron restablecer el binlog para que el archivo 117 tuviera 2 rangos de fecha dentro.

Primero para la revisión de binlog, el siguiente comando genera los datos en un formato legible.
mysqlbinlog --defaults-file=/root/.my.cnf --base64-output=DECODE-ROWS --verbose mysql-bin.000117 > review_mysql-bin.000117.sql

* Nota ... Tenga cuidado al ejecutar el comando anterior. Tenga en cuenta que lo tengo descargando el archivo directamente en la misma ubicación que binlog. Entonces valida que tu nombre de archivo sea válido. Este mysql-bin.000117.sql es diferente a este mysql-bin.000117 .sql. Perderá su binlog con la segunda opción y un espacio antes de .sql.

Ahora para guardar los datos para que puedan ser aplicados. Como tenía varios binlogs, creé un archivo y, de todos modos, quería volver a verificar los rangos de tiempo.


mysqlbinlog --defaults-file=/root/.my.cnf --start-datetime="2019-07-09 00:00:00" --stop-datetime="2019-07-10 00:00:00" mysql-bin.000117 > binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf mysql-bin.000118 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf mysql-bin.000119 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --start-datetime="2019-07-10 00:00:00" --stop-datetime="2019-07-10 10:00:00" mysql-bin.000117 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --stop-datetime="2019-07-10 10:00:00" mysql-bin.000120 >> binlog_restore.sql
mysqlbinlog --defaults-file=/root/.my.cnf --stop-datetime="2019-07-10 10:00:00" mysql-bin.000121 >> binlog_restore.sql

mysql --socket=/var/lib/mysql_restore/mysql.sock -e "source /var/lib/mysql/binlog_restore.sql"

Ahora apliqué todos los datos de esos binlogs para los rangos de tiempo dados. El cliente volvió a verificar todos los datos y estaba muy contento de tenerlos todos de vuelta.

Existían varias opciones diferentes para esta situación, esto sucedió para entrenar mejor con el cliente.

Una vez que todo lo validado estaba correcto en la versión restaurada, era simplemente detener ambas bases de datos, mover los directorios de datos (quería mantener los valores predeterminados de datadir intactos), revisar los directorios solo para estar seguro e iniciar MySQL. Ahora la instancia restaurada estaba en el puerto 3306.