State Snapshot Transfer (SST) es una de las dos formas que usa Galera para realizar la sincronización inicial cuando un nodo se une a un clúster, hasta que el nodo se declara sincronizado y parte del "componente principal". Según el tamaño del conjunto de datos y la carga de trabajo, SST podría ser muy rápido o una operación costosa que pondrá de rodillas su servicio de base de datos.
SST se puede realizar usando 3 métodos diferentes:
- mysqldump
- rsync (o rsync_wan)
- xtrabackup (o xtrabackup-v2, mariabackup)
La mayoría de las veces, xtrabackup-v2 y mariabackup son las opciones preferidas. Rara vez vemos personas que ejecutan rsync o mysqldump en clústeres de producción.
El problema
Cuando se inicia SST, hay varios procesos activados en el nodo de unión, que son ejecutados por el usuario "mysql":
$ ps -fu mysql
UID PID PPID C STIME TTY TIME CMD
mysql 117814 129515 0 13:06 ? 00:00:00 /bin/bash -ue /usr//bin/wsrep_sst_xtrabackup-v2 --role donor --address 192.168.55.173:4444/xtrabackup_sst//1 --socket /var/lib/mysql/mysql.sock --datadir
mysql 120036 117814 15 13:06 ? 00:00:06 innobackupex --no-version-check --tmpdir=/tmp/tmp.pMmzIlZJwa --user=backupuser --password=x xxxxxxxxxxxxxx --socket=/var/lib/mysql/mysql.sock --galera-inf
mysql 120037 117814 19 13:06 ? 00:00:07 socat -u stdio TCP:192.168.55.173:4444
mysql 129515 1 1 Oct27 ? 01:11:46 /usr/sbin/mysqld --wsrep_start_position=7ce0e31f-aa46-11e7-abda-56d6a5318485:4949331
Mientras esté en el nodo donante:
mysql 43733 1 14 Oct16 ? 03:28:47 /usr/sbin/mysqld --wsrep-new-cluster --wsrep_start_position=7ce0e31f-aa46-11e7-abda-56d6a5318485:272891
mysql 87092 43733 0 14:53 ? 00:00:00 /bin/bash -ue /usr//bin/wsrep_sst_xtrabackup-v2 --role donor --address 192.168.55.172:4444/xtrabackup_sst//1 --socket /var/lib/mysql/mysql.sock --datadir /var/lib/mysql/ --gtid 7ce0e31f-aa46-11e7-abda-56d6a5318485:2883115 --gtid-domain-id 0
mysql 88826 87092 30 14:53 ? 00:00:05 innobackupex --no-version-check --tmpdir=/tmp/tmp.LDdWzbHkkW --user=backupuser --password=x xxxxxxxxxxxxxx --socket=/var/lib/mysql/mysql.sock --galera-info --stream=xbstream /tmp/tmp.oXDumYf392
mysql 88827 87092 30 14:53 ? 00:00:05 socat -u stdio TCP:192.168.55.172:4444
SST contra un gran conjunto de datos (cientos de GBytes) no es divertido. Según el hardware, la red y la carga de trabajo, puede tardar horas en completarse. Los recursos del servidor pueden saturarse durante la operación. A pesar de que la limitación es compatible con SST (solo para xtrabackup y mariabackup) con las opciones --rlimit y --use-memory, todavía estamos expuestos a un clúster degradado cuando se está quedando sin la mayoría de los nodos activos. Por ejemplo, si tiene la mala suerte de encontrarse con solo uno de cada tres nodos en ejecución. Por lo tanto, se recomienda realizar SST durante las horas de silencio. Sin embargo, puede evitar el SST siguiendo algunos pasos manuales, como se describe en esta publicación de blog.
Detener un SST
La detención de un SST debe realizarse tanto en el nodo donante como en el nodo de unión. El ensamblador activa SST después de determinar qué tan grande es la brecha al comparar el seqno local de Galera con el seqno del clúster. Ejecuta el wsrep_sst_{wsrep_sst_method} dominio. Esto será elegido por el donante elegido, que comenzará a transmitir datos al carpintero. Un nodo donante no tiene la capacidad de rechazar la transferencia de instantáneas, una vez seleccionado por la comunicación del grupo Galera o por el valor definido en wsrep_sst_donor variable. Una vez que ha comenzado la sincronización y desea revertir la decisión, no hay un solo comando para detener la operación.
El principio básico al detener un SST es:
- Haga que el usuario parezca muerto desde el punto de vista de la comunicación del grupo de Galera (apagado, vallado, bloqueo, reinicio, desenchufado de cable, lista negra, etc.)
- Eliminar los procesos SST en el donante
Uno pensaría que matar el proceso innobackupex (kill -9 {innobackupex PID}) en el donante sería suficiente, pero ese no es el caso. Si elimina los procesos de SST en el donante (o el ensamblador) sin cercar al ensamblador, Galera aún puede ver el ensamblador como activo y marcará el proceso de SST como incompleto, reapareciendo así un nuevo conjunto de procesos para continuar o comenzar de nuevo. Volverás al punto de partida. Este es el comportamiento esperado de la secuencia de comandos /usr/bin/wsrep_sst_{method} para salvaguardar la operación SST que es vulnerable a los tiempos de espera (por ejemplo, si es de ejecución prolongada y requiere muchos recursos).
Veamos un ejemplo. Tenemos un nodo de unión bloqueado que nos gustaría volver a unir al clúster. Comenzaríamos ejecutando el siguiente comando en el carpintero:
$ systemctl start mysql # or service mysql start
Un minuto después, descubrimos que la operación es demasiado pesada en ese momento en particular y decidimos posponerla más tarde durante las horas de poco tráfico. La forma más sencilla de detener un método SST basado en xtrabackup es simplemente cerrar el nodo de unión y eliminar los procesos relacionados con SST en el nodo donante. Alternativamente, también puede bloquear los puertos entrantes en el ensamblador ejecutando el siguiente comando iptables en el ensamblador:
$ iptables -A INPUT -p tcp --dport 4444 -j DROP
$ iptables -A INPUT -p tcp --dport 4567:4568 -j DROP
Luego, en el donante, recupere el PID de los procesos SST (enumere los procesos propiedad del usuario "mysql"):
$ ps -u mysql
PID TTY TIME CMD
117814 ? 00:00:00 wsrep_sst_xtrab
120036 ? 00:00:06 innobackupex
120037 ? 00:00:07 socat
129515 ? 01:11:47 mysqld
Finalmente, elimínelos a todos excepto al proceso mysqld (¡debe tener mucho cuidado de NO eliminar el proceso mysqld en el donante!):
$ kill -9 117814 120036 120037
Luego, en el registro de errores de MySQL del donante, debería notar que aparece la siguiente línea después de ~100 segundos:
2017-10-30 13:24:08 139722424837888 [Warning] WSREP: Could not find peer: 42b85e82-bd32-11e7-87ae-eff2b8dd2ea0
2017-10-30 13:24:08 139722424837888 [Warning] WSREP: 1.0 (192.168.55.172): State transfer to -1.-1 (left the group) failed: -32 (Broken pipe)
En este punto, el donante debería volver al estado "sincronizado" según lo informado por wsrep_local_state_comment y el proceso SST se detiene por completo. El donante ha vuelto a su estado operativo y puede servir a los clientes en plena capacidad.
Para el proceso de limpieza en el carpintero, simplemente puede vaciar la cadena de iptables:
$ iptables -F
O simplemente elimine las reglas con el indicador -D:
$ iptables -D INPUT -p tcp --dport 4444 -j DROP
$ iptables -D INPUT -p tcp --dport 4567:4568 -j DROP
El enfoque similar se puede usar con otros métodos SST como rsync, mariabackup y mysqldump.
Aceleración de un SST (solo método xtrabackup)
Dependiendo de cuán ocupado esté el donante, es un buen enfoque acelerar el proceso de SST para que no afecte significativamente al donante. Hemos visto una serie de casos en los que, durante fallas catastróficas, los usuarios estaban desesperados por recuperar un clúster fallido como un solo nodo de arranque y dejar que el resto de los miembros se pusieran al día más tarde. Este intento reduce el tiempo de inactividad desde el lado de la aplicación, sin embargo, crea una carga adicional en este "clúster de un nodo", mientras que los miembros restantes aún están inactivos o recuperándose.
Xtrabackup se puede acelerar con --throttle=
[sst]
rlimit=128k
inno-apply-opts="--use-memory=200M"
Más detalles en la página de documentación de Percona Xtrabackup SST.
Sin embargo, hay una trampa. El proceso podría ser tan lento que nunca se pondrá al día con los registros de transacciones que está escribiendo InnoDB, por lo que es posible que SST nunca se complete. En general, esta situación es muy poco común, a menos que realmente tenga una carga de trabajo de escritura muy intensiva o que asigne recursos muy limitados a SST.
Conclusiones
SST es crítico pero pesado, y podría ser potencialmente una operación de larga duración según el tamaño del conjunto de datos y el rendimiento de la red entre los nodos. Independientemente de las consecuencias, todavía hay posibilidades de detener la operación para que podamos tener un mejor plan de recuperación en un mejor momento.