TPL_TILSOR_TEMPLATE_TILSOR TPL_TILSOR_TEMPLATE_TILSOR

¿Que es Group Replication?

Es un complemento nativo de MySQL disponible a partir de la versión 5.7.17. Nos permite tener alta disponibilidad de una forma muy sencilla, segura y gratis.

Es parte de la solución InnoDB Cluster, la que consta de 3 componentes principales:

  • MySQL Shell: Permite crear scripts de creación y administración de un clúster InnoDB, utilizando JavaScript o Python.
  • MySQL Router: Contiene información y estado de cada miembro del Group Replication. A él se deben apuntar las conexiones de los clientes (ver imagen), ya que se encarga de enviar las solicitudes a donde corresponda dependiendo de la configuración que realicemos.
  • MySQL Group Replication: Permitir que los datos se repliquen dentro del clúster.

MySQL: Group Replication Cluster

Existen dos modalidades.

  • Single-Master: Permite escribir en un solo nodo.
  • Multi-Master: Permite escribir en todos los nodos.

Requerimientos

  • Motor InnoDB: Los datos deben estar almacenados en motores InnoDB.
  • Claves Primarias: Toda tabla dentro del grupo requiere una clave primaria.
  • IPv4 y TCP: Se requiere conectividad IPv4 y TCP para la comunicación entre los nodos.
  • Buen rendimiento de Red: Se debe tener especial cuidado en la latencia y ancho de banda de red, ya que dependiendo el trafico que se maneje, puede requerir que viaje mucha información sobre ella, y puede afectar el rendimiento del grupo.
  • Binlogs activos: El Group Replication necesita de los binlogs para funcionar, por lo tanto esto debe estar habilitado.
  • Registro de slave updates activo: Los servidores del grupo necesitan registrar todas las transacciones que reciben y aplican desde el grupo. Deben existir copias de cada transacción en cada servidor, incluso para aquellas transacciones que no se iniciaron en el propio servidor.
  • Binary log en formato ROW: Group Replication se basa en el formato de replicación basado en ROW para propagar los cambios de forma consistente entre los servidores del grupo.
  • Global Transaction Identifiers (gtid) habilitado: Es utilizado para determinar qué transacciones pueden estar en conflicto con otras.
  • Repositorios de Información de Replicación: Garantiza que el grupo tenga una recuperación consistente y una gestión transaccional de los metadatos de replicación.
  • Extracción de conjuntos de escritura de transacciones: Utilizado para que, al registrar las rows en el registro binario, el servidor recopile el conjunto de escritura también. El conjunto de escritura se basa en las claves primarias de cada fila y es una vista simplificada y compacta de una etiqueta que identifica de forma exclusiva la fila que se cambió. Esta etiqueta se utiliza para detectar conflictos.
  • Múltiples hilos: Permite que las transacciones se apliquen en paralelo.

Limitaciones

  • Replication Event Checksums: Debido a una limitación de diseño, Group Replication no puede hacer uso de ellos, por lo tanto se deben deshabilitar.
  • Gap Locks: El proceso de certificación no tiene en cuenta los bloqueos de espacio, ya que la información acerca de los bloqueos de espacios no está disponible fuera de InnoDB.
  • Table Locks and Named Locks: El proceso de certificación no tiene en cuenta los bloqueos de tablas.
  • Nivel de aislamiento SERIALIZABLE: No se admite de forma predeterminada en grupos multi-master.
  • DDL Concurrente contra Operaciones DML: Las sentencias de definición de datos concurrentes y las instrucciones de manipulación de datos que se ejecutan contra el mismo objeto pero en servidores diferentes no se admiten cuando se usa el modo multi-master.
  • Foreign Keys con restricciones en cascada: Los grupos de modo multi-master no admiten tablas con dependencias de clave externa multinivel, específicamente tablas que han definido restricciones de clave externa CASCADING.
  • Transacciones grandes: Las transacciones individuales que resultan en contenidos GTID que son lo suficientemente grandes como para que no se puedan copiar entre los miembros del grupo dentro de una ventana de 5 segundos pueden causar fallas en la comunicación de grupo.
  • Creación de un clúster desde un grupo: El uso de la opción adoptFromGR con la función dba.createCluster () para crear un clúster basado en una implementación existente de Group Replication falla con un error de que la instancia ya es parte de un grupo de replicación. Esto sucede sólo en el modo de asistente de MySQL Shell.
  • Límite máximo de servidores: Se pueden unir al grupo hasta 9 servidores.

¿Cómo configurarlo?

Para nuestro ejemplo de configuración, utilizaremos el modo multi-master con 3 nodos.

En el my.cnf del nodo 1 agregar las siguientes líneas:

server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log-bin=binlog
binlog_format=ROW
plugin-load=group_replication.so
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaab"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.10.10:33066"
loose-group_replication_group_seeds="192.168.10.10:33066,192.168.10.20:33066,192.168.10.30:33066"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks=TRUE
loose-group_replication_ip_whitelist=192.168.10.0/24
loose-group_replication_recovery_retry_count=3
loose-group_replication_recovery_reconnect_interval=120

En el my.cnf del nodo 2 agregar las siguientes líneas:

server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log-bin=binlog
binlog_format=ROW
plugin-load=group_replication.so
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaab"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.10.20:33066"
loose-group_replication_group_seeds="192.168.10.10:33066,192.168.10.20:33066,192.168.10.30:33066"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks=TRUE
loose-group_replication_ip_whitelist=192.168.10.0/24
loose-group_replication_recovery_retry_count=3
loose-group_replication_recovery_reconnect_interval=120

En el my.cnf del nodo 3 agregar las siguientes líneas:

server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log-bin=binlog
binlog_format=ROW
plugin-load=group_replication.so
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaab"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.10.30:33066"
loose-group_replication_group_seeds="192.168.10.10:33066,192.168.10.20:33066,192.168.10.30:33066"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks=TRUE
loose-group_replication_ip_whitelist=192.168.10.0/24
loose-group_replication_recovery_retry_count=3
loose-group_replication_recovery_reconnect_interval=120

El id se debe modificar en cada nodo, de forma que sea diferente en cada uno de ellos.

Tanto la IP local como los miembros y la whitelist se debe sustituir con la que corresponda al servidor y red que estamos configurando.

El puerto debe ser distinto al que utiliza el MySQL Server para levantar (Por defecto 3306).

Para nuestro ejemplo estableceremos la comunicación del MySQL Group Replication a través del puerto 33066.

Luego de aplicar la configuración se debe reiniciar la base para que tome los cambios.

systemctl start mysqld

Verificar en cada nodo que el plugin del MySQL Group Replication (group_replication) esta siendo utilizado:

SHOW PLUGINS;

De lo contrario se puede instalar con el siguiente comando dentro del MySQL:

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

En cada uno de los nodos, debemos configurar el usuario con el que se conectaran los miembros entre sí.

SET SQL_LOG_BIN=0;
CREATE USER rep_user@'%' IDENTIFIED BY 'rep_pass';
GRANT REPLICATION SLAVE ON *.* TO rep_user@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;

Se especifica, también en cada nodo, el usuario a utilizar para el Group Replication (el que acabamos de crear).

CHANGE MASTER TO MASTER_USER='rep_user', MASTER_PASSWORD='rep_pass' FOR CHANNEL 'group_replication_recovery';

En uno de los, inicializar el Group Replication:

SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

Validar que este "Online" el grupo:

SELECT * FROM performance_schema.replication_group_members;

En este punto solo veremos 1 nodo conectado.

En el resto de los nodos, solo se deben unir al grupo, ya que solo se inicializa una vez:

START GROUP_REPLICATION;

Luego de esto, podemos validar que los nodos estén "online":

SELECT * FROM performance_schema.replication_group_members;

En este paso deberíamos ver algo como lo siguiente:


+---------------------------+--------------------------------------+-------------------------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST                   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------------------------+-------------+--------------+
| group_replication_applier | aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa | host1                         | 3306        | ONLINE       |
| group_replication_applier | bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb | host2                         | 3306        | ONLINE       |
| group_replication_applier | cccccccc-cccc-cccc-cccc-cccccccccccc | host3                         | 3306        | ONLINE       |
+---------------------------+--------------------------------------+-------------------------------+-------------+--------------+

Listo. Ya tenemos el MySQL Group Replication levantado y los nodos sincronizados.

Esta configuracion tambien se puede realizar utilizando el componente MySQL Shell, y agregar el MySQL Router o ProxySQL para generar un ambiente completo de alta disponibilidad. Lo veremos en detalle en otra entrada.

Pruebas

Una vez creado el Group Replication, podemos realizar algunas pruebas sobre el.

Dentro del MySQL:

CREATE DATABASE prueba;
use prueba
CREATE TABLE tabla1 (campo1 INT PRIMARY KEY, campo2 TEXT NOT NULL);
INSERT INTO tabla1 VALUES (1, 'Pablo');
INSERT INTO tabla1 VALUES (2, 'Antonio');
INSERT INTO tabla1 VALUES (3, 'Diego');

SELECT * FROM tabla1;

Podemos hacer cada INSERT en nodos diferentes y verificar cómo la información se encuentra disponible en todo el grupo.

Por más información se puede consultar la documentación oficial de MySQL:

https://dev.mysql.com/doc/refman/5.7/en/