You are here

XtraBackup: Como realizar copias completas e incrementales en MySQL

isholgueras's picture
Submitted by isholgueras on Fri, 07/10/2015 - 12:30

XtraBackup es una herramienta de Percona, y provée unas pocas herramientas que permiten generar backups de distintos tipos (totales, incrementales, encriptados, de esclavo,...) y con una fiabilidad y rapidez excelente, en comparación al típico mysqldump.

Las copias que realiza XtraBackup las realiza en modo binario, es decir, guarda tal cual lo existente en /var/lib/mysql o en el directorio donde tengamos almacenados los datos. Por lo que he visto, sólo permite restaurar los backups con el MySQL apagado. También hay que decir que esta herramienta sólo sirve para realizar copias de tablas INNODB. El backup para las tablas MyISAM tiene que realizarse de otra forma (mysqldump, por ejemplo)

Pues veamos qué recetas se pueden hacer. Asumimos que tenemos la siguiente configuración:

data-dir: /var/lib/mysql
backup-dir: /data/backups/mysql
usuario: root (o con permisos de sudo)

Realizar un backup completo

Es tan sencillo como ejecutar:

xtrabackup --backup --target-dir=/data/backups/mysql/2015-07-10_10-10

Esto va a copiar todo el directorio de /var/lib/mysql en la carpeta que hemos dato en target-dir. Aparecerá ibdata, my-database/,... y dos ficheros:

  • xtrabackup_checkpoints
  • xtrabackup_logfile

Y por último hay que preparar el backup para que el backup sea consistente.

xtrabackup --prepare --target-dir=/data/backups/mysql/2015-07-10_10-10/

Nos devolverá un número de secuencia y con esto ya tenemos un backup listo para restaurar.

Nota: si ejecutamos varias veces el --prepare nos dirá que ya está preparado el backup. No hay problema.

Realizar un backup incremental

Lo bueno que tienen los backups completos es que en ese backup tienes toda tu base de datos lista, pero el mayor problema es que tarda bastante y ocupa mucho espacio. Para eso tenemos los backups incrementales. Sólo copian lo nuevo desde el backup completo.

Los backups incrementales se basan en uno completo, y a partir del primer número de secuencia que genera el primer backup va generando los siguientes incrementales. Es importante saber que los números de secuencia son secuenciales, y por ello deben de ser consecutivos. El backup completo debe de tener un número de secuencia menor a los incrementales, y los incrementales previos tienen que tener un número de secuencia mayores al completo pero menores a los incrementales posteriores. Esta es lo más importante a tener en cuenta.

Por ejemplo:

  • backup-completo: LSN_from = 0; LSN_to = 334065
  • incremental-martes: LSN_from = 334065; LSN_to = 335623
  • incremental-jueves: LSN_from = 335623; LSN_to = 341754

Los incrementales pueden ser de cada día, de cada hora,... Según necesitemos.

Lo primero es ejecutar un backup completo. Pensaríamos que después de hacer el backup hay que prepararlo,  pero preparar un backup significa no poder hacer otra cosa con él mas que restaurarlo. No se pueden hacer incrementales con un backup preparado. Por lo tanto no prepararemos el backup.

Generamos el backup completo (ejecutado el lunes):

xtrabackup --backup --target-dir=/data/backups/mysql/2015-07-1st-week/full/

Generamos ahora el backup del martes (ejecutado el martes):

xtrabackup --backup --target-dir=/data/backups/mysql/2015-07-1st-week/martes/ \
     --incremental-basedir=/data/backups/mysql/2015-07-1st-week/full/

Y Generamos también el backup del jueves (ejecutado el jueves):

xtrabackup --backup --target-dir=/data/backups/mysql/2015-07-1st-week/jueves/ \
     --incremental-basedir=/data/backups/mysql/2015-07-1st-week/martes/

Hasta ahora no hemos preparado los backups, como se puede ver. Sólo se preparan cuando se van a restaurar o cuando sabemos que no los vamos a tocar.

Una vez sabemos que esos backups no los vamos a tocar, lo que hacemos es prepararlos. Preparamos únicamente los logs del completo:

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/mysql/2015-07-1st-week/full/

Sincronizamos los datos del martes al backup del lunes:

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/mysql/2015-07-1st-week/full/ \
     --incremental-dir=/data/backups/mysql/2015-07-1st-week/martes/

Y hacemos lo mismo con el del jueves:

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/mysql/2015-07-1st-week/full/ \
     --incremental-dir=/data/backups/mysql/2015-07-1st-week/jueves/

Ahora ya tenemos el backup del lunes (o el backup full) completo, sincronizado y con todos los datos. Ahora sí es momento de preparar el backup:

xtrabackup --prepare --target-dir=/data/backups/mysql/2015-07-1st-week/full/

Con esto ya tenemos este backup listo para restaurar.

Como se puede ver, es importante tener en cuenta que el backup "completo" no debemos llamarlo lunes, hay que llamarlo completo/full/o similar, puesto que es el backup al que se le van a ir integrando todos los incrementales que vayamos haciendo.

Son conceptos difíciles de entender al principio. Sobre todo si estamos muy acostumbrados al mysqldump de toda la vida, pero una vez que se entienden estos conceptos, todo se entiende muy fácilmente.

Restaurar el backup

Es muy bonito todo esto de los "backups molones incrementales" y hacer cosas nuevas distintas, pero como dice el gran NITEMAN, los backups son para poder restaurarlos, si no se pueden restaurar no son backups. (Ponle cebolla, pero no lo llames tortilla de patata).

Como hemos dicho antes, esta herramienta copia los binarios completos de los datos. Por lo tanto, la restauración que propongo tiene que realizarse con el MySQL parado.

/etc/init.d/mysql stop
cd /data/backups/mysql/2015-07-1st-week/full/
rsync -rvt --exclude 'xtrabackup_checkpoints' --exclude 'xtrabackup_logfile' \
   ./ /var/lib/mysql
chown -R mysql:mysql /var/lib/mysql/
/etc/init.d/mysql start

Con esto ya tenemos el backup restaurado.

Conclusiones

En mi trabajo, manejo bases de datos de varios Gigas. Realizar un backup completo de base de datos puede llevar varios minutos (de 5 a 8 normalmente), además de generar un fichero SQL de varios gigas. Restaurar un backup desde un mysqldump puede llegar a durar sus 15-20 minutos. Algo inviable en momentos críticos futuros (que espero que no sucedan nunca).

Con la herramienta de copias incrementales, tenemos una imagen de la base de datos de cada hora en horas de trabajo (de 8 a 17) y generamos un backup completo por la noche. Este backup incremental lo hacemos con la base de datos levantada y se ejecuta aproximadamente en 30 segundos, y el backup completo tarda unos 3 minutos.

Restaurar el backup tarda:

  • apagar el mysql: 1 minuto
  • rsync del backup: 2 minutos (como mucho)
  • encender el mysql: 30-45 segundos

Siendo objetivo, es mucho más fácil generar un mysqldump con el --single-transaction, pero una vez que le cojes el tranquillo a la herramienta, y te programes un par de scripts que te automaticen esto se puede convertir en un must have.

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.