Implementación de referencia de la base de datos de MySQL en GDC aislado

En esta guía, se proporciona un instructivo completo paso a paso para implementar un MySQL 8.4 InnoDB Cluster con alta disponibilidad en tres zonas de disponibilidad en un entorno aislado de Google Distributed Cloud (GDC). Esta arquitectura aprovecha la replicación de grupos para el consenso basado en Paxos, el router MySQL para el enrutamiento inteligente de conexiones y MySQL Shell para la organización del clúster.

Mediante el uso estricto de máquinas virtuales (VMs), esta implementación omite las limitaciones aisladas de GDC con respecto a los clústeres de Kubernetes entre zonas, lo que garantiza una resiliencia completa en varias zonas sin riesgo de pérdida de datos.

Este es el diagrama de arquitectura:

Arquitectura de tres VMs que ejecuta una pila de servicios colocados.

Antes de comenzar

Implementa VMs

Sigue los pasos de Crea y después inicia una instancia de VM para crear tres VMs en las tres zonas disponibles.

Configura tu entorno local para establecer una conexión SSH a las VMs con un par de claves: Conéctate a una VM

Esto es necesario para usar la copia segura (SCP) para transferir los paquetes: Transfiere archivos

Para la verificación, usamos el SO Ubuntu 22.04 y el tipo de máquina n3-standard-2-gdc. Para un entorno de producción, usa un tipo de máquina con más recursos.

Obtén las IPs de las VMs con el siguiente comando:

VM_NAME=$1

if [[ -z "$VM_NAME" ]]; then
  echo "Error: VM_NAME must be provided."
  echo "Usage: $0 <VM_NAME>"
  exit 1
fi

# 1. Get External IP from 'instances list'
EXT_IP=$(gdcloud compute instances list | awk -v vm="${VM_NAME}" '$1 == vm {print $5}')

if [[ -z "$EXT_IP" ]]; then
  echo "Error: Could not find VM '${VM_NAME}' in the instance list."
  exit 1
fi

INTERNAL_IP=$(gdcloud compute instances describe "${VM_NAME}" | awk '/^status:/ {in_status=1} in_status && /- [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $2; exit}' | cut -d'/' -f1)

if [[ -z "$INTERNAL_IP" ]]; then
  INTERNAL_IP="<Not assigned or not found>"
fi

echo "${VM_NAME}"
echo "External IP: ${EXT_IP}"
echo "Internal IP: ${INTERNAL_IP}"

Configure las variables de entorno

Configura estas variables en la sesión de shell de tu estación de trabajo local:

export PROJECT_ID="your-project-id"
export VM1_NAME="mysql-node-1"
export VM2_NAME="mysql-node-2"
export VM3_NAME="mysql-node-3"
export VM1_IP="10.0.1.245" # Zone 1
export VM2_IP="10.0.1.241" # Zone 2
export VM3_IP="10.0.1.242" # Zone 3
export CLUSTER_NAME="mysql-ha-cluster"

Configuración de red

En caso de que necesites comunicarte con la base de datos fuera del proyecto o de la organización, recuerda configurar la PNP (política de red del proyecto) en consecuencia.

Sigue las secciones de Descripción general de la PNP según el caso de uso.

Preparación del software aislado

Descarga paquetes con Docker

Ejecuta lo siguiente desde una estación de trabajo conectada para recuperar los componentes de MySQL 8.4 y Shell:

mkdir -p ./mysql-packages
docker run --rm -v "$(pwd)/mysql-packages:/packages" ubuntu:22.04 bash -c "
  apt-get update && apt-get install -y curl gnupg apt-rdepends wget lsb-release
  curl -LsS https://dev.mysql.com/get/mysql-apt-config_0.8.39-1_all.deb -o config.deb
  # Configure for MySQL 8.4 LTS
  DEBIAN_FRONTEND=noninteractive dpkg -i config.deb 
  apt-get update
  cd /packages
  PACKAGES='mysql-server mysql-shell mysql-router'
  apt-get download \$(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \${PACKAGES} | grep '^\w')
"

Transfiere e instala

Sube los archivos .deb a /tmp/packages/ en las tres VMs y, luego, instálalos:

# From workstation: scp ./mysql-packages/*.deb ${VM_IP}:/tmp/packages/
# On each VM:
sudo dpkg -i /tmp/packages/*.deb

Asegúrate de que dpkg no muestre errores. Si lo hace, revisa los registros para ver qué paquetes deb te faltan y agrégalos a la descarga.

Cuando se te solicite que establezcas la contraseña raíz, déjala en blanco. La estableceremos más adelante.

Configuración del nodo de MySQL

Configura MySQL para el uso del clúster

Edita /etc/mysql/mysql.conf.d/mysqld.cnf en todos los nodos para habilitar GTIDs y el registro binario:

[mysqld]
bind-address = 0.0.0.0
server-id = 1 # Use 2 and 3 for other VMs
gtid-mode = ON
enforce-gtid-consistency = ON
binlog-format = ROW
log-bin = mysql-bin
report_host = 10.0.1.245 # Use the VM's specific IP

Reinicia el servicio:

sudo systemctl restart mysql

Luego, conéctate a la base de datos:

sudo mysql

y establece la contraseña raíz:

CREATE USER 'root'@'%' IDENTIFIED WITH 'caching_sha2_password' BY 'your_new_secure_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Inicialización y verificación del clúster de InnoDB

Crea un clúster con MySQL Shell

En VM 1 SOLAMENTE, usa MySQL Shell para inicializar el clúster:

mysqlsh --uri root@localhost
# Inside MySQL Shell:
\js
dba.configureInstance('root@VM1_IP')
var cluster = dba.createCluster('mysql-ha-cluster')
cluster.addInstance('root@VM2_IP')
cluster.addInstance('root@VM3_IP')
cluster.status()

Inicializa el router MySQL

En las tres VMs, inicializa el router para detectar el clúster nuevo:

sudo mysqlrouter --bootstrap root@VM1_IP --user=mysqlrouter
sudo systemctl restart mysqlrouter
sudo systemctl enable mysqlrouter

Verifica el balanceo y las conexiones

Ejecuta estos comandos desde cualquier nodo para asegurarte de que el router distribuya el tráfico correctamente.

  1. Verifica el enrutamiento de escritura (primario activo): Consulta el puerto 6446 (RW clásico). Debe mostrar estrictamente el nombre de host del primario actual.

    mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  2. Verifica el balanceo de lectura (Round-Robin): Consulta el puerto 6447 (RO clásico) varias veces. Debe recorrer los nombres de host de todos los nodos disponibles en el clúster.

    for i in {1..4}; do mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6447 -e "SELECT @@hostname;"; done
    
  3. Verifica la topología de conexión: Usa MySQL Shell para confirmar que todos los miembros estén ONLINE y balanceados correctamente.

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

Configuración del balanceador de cargas global

Proporciona una sola IP virtual (VIP) estable para tus aplicaciones con el balanceador de cargas global L4 de GDC. Sigue los pasos de Configura balanceadores de cargas globales internos para configurar el balanceador de cargas global L4 interno y configurar tus VMs para que sean su destino: Configura VMs como destino del balanceador de cargas.

Verificación de la conmutación por error automática

Esta prueba confirma que el clúster elige un nuevo líder y que el router redirecciona el tráfico sin intervención manual.

Simula una falla primaria

Identifica el primario actual (p.ej., el nodo 1) y detén el servicio de MySQL:

sudo systemctl stop mysql

Verifica la elección y el cambio de enrutamiento

Espera entre 10 y 20 segundos para que el protocolo de consenso elija un nuevo líder.

  1. Verifica el estado del clúster: Desde la VM 2 o 3, verifica que se haya elegido un nuevo primario.

    mysqlsh --uri root@localhost --cluster
    
    # inside the shell
    > cluster.status()
    

    Confirma que uno de los nodos restantes esté marcado como PRIMARY y que el nodo con errores esté marcado como UNREACHABLE o MISSING.

  2. Verifica el enrutamiento de escritura: Vuelve a probar el puerto RW (6446). Ahora debería devolver el nombre de host del nuevo primario.

    mysql -u root -p -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  3. Prueba la conectividad de la VIP global: Desde un servidor de aplicaciones, consulta la VIP global.

    mysql -u root -p -h ${LB_IP} -P 3306 -e "SELECT @@hostname;"
    

Recupera y verifica la unión

Inicia el servicio de MySQL en el nodo con errores y verifica que se una como una réplica secundaria.

sudo systemctl start mysql
mysqlsh --uri root@localhost --cluster -e "cluster.status()"

Confirma que los tres nodos devuelvan el estado ONLINE.