Backups en un Cluster MySQL (PXC 5.6)

datacenterDespués de montar un clúster PXC o Galera Cluster (versión 5.6 en servidores CentOS 6.5), igualmente querremos hacer backups de nuestros datos. Para ello, bastará con realizar un backup de uno de los nodos, puesto que todos los nodos contendrán exactamente la misma información. Aunque en realidad no es tan fácil…

Problemas con los backups en un cluster Galera

Hemos de tener en cuenta que los backups, en algún punto, realizarán un FLUSH TABLES WITH READ LOCK, que hará que ese nodo no permita escrituras y por tanto, no se podrán realizar escrituras en el cluster durante ese tiempo [Fuente 1 y Fuente 2]. La explicación es que una escritura al cluster devolverá ok cuando se haya replicado a todos los nodos del mismo. Por tanto, si un nodo no puede escribir, todo el cluster no podrá escribir.

A ésto hay que sumarle que por defecto un backup en PXC/Galera no guardará los «Global Transaction ID«, necesarios para poder dar de alta nuevos nodos de forma rápida (ahorrándonos el SST inicial) a raíz de ese backup. [Fuente, transp. 44]

Posibles métodos

Así pues, no es tan fácil realizar un backup en nuestro cluster PXC/Galera, aunque hay algún método de backup que nos puede ser útil:

  1. Desconectar un nodo del cluster, para hacer el backup. De esta manera, durante el backup el cluster podrá continuar trabajando con las escrituras de la forma habitual, puesto que el nodo que está realizando el backup estará fuera del cluster. Este método lo describen perfectamente en la documentación oficial de Percona. Has de tener en cuenta que si estás usando, como parecería lógico, un balanceador de carga para distribuir la carga entre los nodos del cluster, deberás, además, sacar al nodo del balanceador antes de iniciar el backup.
  2. Servirse del mismo método de backup que el que se usa para las SST (State Snapshot Transfer) entre nodos. Para ello, tal y como dice la documentación oficial de Galera, podemos usar el ejecutable garbd en el nodo que seleccionaremos para realizar el backup.
  3. Configurar un servidor adicional como slave para que replique de algún nodo del cluster. Podemos configurar este slave para que vaya unas horas por detrás en cuanto a la replicación, para, en el caso de detectar un problema, parar la replicación y usarlo para promocionar el cluster.

Comentar que he visto en otras páginas un cuarto método, XtraBackup de Percona con la opción «–galera-info«, que se encarga de guardar la Global Transaction ID en el momento del backup, pero que irremediablemente bloqueará tablas, si se está realizando un backup funcional que permita restaurarse después (el bloqueo de tablas, como se ha explicado, deja al nodo sin poder escribir).

Backup desconectando el nodo

Mi primera opción era usar garbd para iniciar el backup, pero sinceramente, ha sido una pesadilla y al final no ha habido manera. Así pues, me decidí por desconectar un nodo del cluster, tal y como recomienda Percona.

1. El primer paso, pues, será desconectar el nodo que nos servirá para hacer el backup, del cluster (recuerda que si estás en un balanceador, deberás desconectarlo préviamente del mismo). Podemos desconectar el nodo del cluster, ejecutando el siguiente comando:

[root@percona2]# mysql -u root -pPASS -e "set global wsrep_desync=ON;"

Podemos conectarnos al cliente mysql del nodo y ver como ha pasado de Synced a Donor/Desynced una vez ejecutado el comando anterior:

mysql> show status like 'wsrep%';
(ANTES) | wsrep_local_state_comment    | Synced
(DESPUES) | wsrep_local_state_comment    | Donor/Desynced

Curiosamente, el cluster a pesar de tener un nodo en estado Desynced no ha disminuido su tamaño.

| wsrep_cluster_size           | 3

NOTA: En este momento, si modificamos algo en el cluster (mediante un insert, por ejemplo), la operación de escritura se realiza sin problemas y se replica al nodo Donor/Desynced.

2. A continuación, forzamos al nodo Donor/Desynced un FTWRL para bloquear tablas y ver qué pasa con el cluster:

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0,00 sec)

mysql> insert t(a,b) values (4,4);
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock

Como se observa, en el nodo no se pueden realizar operaciones de escritura. Sin embargo, veremos qué pasa con el resto del cluster probando a insertar en otro nodo:

mysql> insert t(a,b) values (5,5);
Query OK, 1 row affected (0,14 sec)

Como se puede ver, en el resto del cluster sí se puede escribir. Por otra parte, efectivamente el nodo Donor/Desynced no replica mientras está en estado FTWRL y Donor/Desynced.

3. En este momento, pues, deberíamos realizar el backup en el nodo Donor/Desynced, puesto que no afectaremos al funcionamiento del cluster. Podemos hacer el backup mediante nuestro método favorito, pero particularmente recomiendo XtraBackup con la opción «–galera-info«, tal y como se ha comentado anteriormente.

innobackupex --user=$DBUSER --password=$DBPASS --galera-info /backupfolder/FULL/
innobackupex --user=$DBUSER --password=$DBPASS --apply-log /backupfolder/FULL/2014-03-28_11-02-08/

4. Una vez finalizado el backup, desbloqueamos tablas y volvemos a añadir el nodo al cluster:

mysql> unlock tables; set global wsrep_desync=OFF;
Query OK, 0 rows affected (0,00 sec)

En este momento, vemos como el nodo vuelve a estar sincronizado.

| wsrep_local_state_comment    | Synced

También comprobamos como el nodo ha replicado los cambios que se han hecho mientras él estaba con lock tables.

Script de backup

Con éste procedimiento, se puede crear un script que realice todo el proceso por nosotros, parecido al siguiente:

#!/bin/bash

# Variables
DBUSER=usuario
DBPASS=password
bkpdir=/path/to/backup/folder
bkpname=micluster

# Desconexión del balanceador
## Aquí iría el código para desconectar al nodo del balanceador

# Desconecto el nodo del cluster
echo "... Desconecto el nodo del cluster MySQL"
mysql -u $DBUSER -p$DBPASS -e "set global wsrep_desync=ON;"

# Iniciamos el backup
mkdir $bkpdir/FULL
innobackupex --user=$DBUSER --password=$DBPASS --galera-info $bkpdir/FULL/

# Aplicamos logs para poder restaurar el backup
lastfulldir=`ls -t $bkpdir/FULL/ | head -1`
innobackupex --user=$DBUSER --password=$DBPASS --apply-log $bkpdir/FULL/$lastfulldir/

# Comprimimos el backup
cd $bkpdir
tar -czvf $bkpdir/$bkpname.$fulldate.tgz FULL/

# Borramos los ficheros, ahora que no los necesitamos
cd $bkpdir
rm -rf FULL

# Mantenemos sólo los 30 últimos backups
nlocalfiles=`ls -l $bkpname.*.tgz | wc -l`
if [ $nlocalfiles -gt 30 ]; then
toremove=`ls -tr $bkpname.*.tgz | head -1`
rm -f $toremove
fi

# Conecto el nodo de nuevo al cluster MySQL
mysql -u $DBUSER -p$DBPASS -e "set global wsrep_desync=OFF;"

# Conexión al balanceador
## Aquí iría el código para volver a conectar el nodo al balanceador

 

Con ésto tendremos cubierto el backup de nuestro cluster.

A partir de aquí, si quieres, puedes ver cómo añadir un nuevo nodo al cluster a partir de uno de nuestros backups.

Fuentes:

http://www.mysqlperformanceblog.com/2013/10/08/taking-backups-percona-xtradb-cluster-without-stalls-flow-control/

http://www.codership.com/wiki/doku.php?id=data_backup

https://groups.google.com/forum/#!msg/codership-team/OYA77HJBUNY/rj-g6A60bksJ

http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html

https://groups.google.com/forum/#!topic/codership-team/4lTEcR0X2Co

Flickr! Foto por ChrisDag

4 respuestas a «Backups en un Cluster MySQL (PXC 5.6)»

  1. Muchas gracias por la explicacion sobre como hacer respaldos en un cluster Percona. Durante el paso a paso, se bloquearon las tablas para que no se pudiera escribir en ella, pero noto que en el script no se hace este paso antes del realizar el respaldo, mi pregunta, Deben bloquearse las tablas o con solo sacar el nodo del cluster es suficiente?

    De antemano muchas gracias

    1. Hola Eduar,
      Sólo con sacar el nodo del cluster debería ser suficiente, pues el nodo dejará de replicar y por tanto, no habrá cambios mientras el nodo esté fuera del cluster. Ésto es así si como decía, anteriormente nos aseguramos de sacar el nodo del balanceador (y por tanto en efecto aseguramos que no recibirá operaciones directamente – via balanceador – ni tampoco via la propia replicación del cluster).

      Yo he estado usando este procedimiento durante un buen tiempo y no he tenido problemas, incluso teniendo que recuperar o montar algún nodo adicional a partir de un backup realizado con este método.

      En cualquier caso, te recomiendo probar y probar, para convencerte de qué es lo mejor para tu entorno. ¡Y no dudes en compartir cualquier comentario que consideres!

      Gracias por leerme 🙂

  2. Muchas gracias por responder, estoy tratando de adoptar este metodo de respaldo en un cluster en produccion. Como lo mencionas, el cluster esta detras de balanceador (HAproxy), para deshabilitar el nodo del balanceador utilizo socat y activo la accion de crear un socket en HAproxy. Mi script de respaldo correria localmente y para conectarme al HAproxy uso un script es expect para pasar los parametros al proxy via SSH. De momento todas las pruebas han salido bien. Gracias por tomarte el tiempo de compartir tu conocimiento. Saludos desde Venezuela

Responder a Adrián Pérez Cancelar la respuesta

Tu dirección de correo electrónico no será publicada.