Implementação de referência do banco de dados MySQL no GDC com isolamento físico

Este guia oferece um tutorial abrangente e detalhado para implantar um cluster do InnoDB do MySQL 8.4 de alta disponibilidade em três zonas de disponibilidade em um ambiente isolado do Google Distributed Cloud (GDC). Essa arquitetura aproveita a replicação de grupo para consenso baseado em Paxos, o MySQL Router para roteamento inteligente de conexões e o MySQL Shell para orquestração de clusters.

Ao usar estritamente máquinas virtuais (VMs), essa implementação ignora as limitações do GDC com isolamento físico em relação a clusters estendidos do Kubernetes entre zonas, garantindo resiliência multizona completa sem risco de perda de dados.

Este é o diagrama de arquitetura:

Arquitetura de três VMs que executa uma pilha de serviços colocados.

Antes de começar

Implantar VMs

Siga as etapas em Criar e iniciar uma instância de VM para criar três VMs nas três zonas disponíveis.

Configure seu ambiente local para estabelecer uma conexão SSH com as VMs usando um par de chaves: Conectar-se a uma VM

Isso é necessário para usar a cópia segura (SCP, na sigla em inglês) para transferir os pacotes: Transferir arquivos

Para verificação, usamos o SO Ubuntu 22.04 e o tipo de máquina n3-standard-2-gdc. Para um ambiente de produção, use um tipo de máquina com mais recursos.

Receba os IPs das VMs usando:

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}"

Configurar as variáveis de ambiente

Defina essas variáveis na sessão do shell da estação de trabalho 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"

Configuração de rede

Caso precise acessar o banco de dados fora do projeto ou da organização, lembre-se de configurar a PNP (política de rede do projeto) de acordo.

Siga as seções da visão geral da PNP dependendo do caso de uso.

Preparação de software isolado

Fazer o download de pacotes usando o Docker

Execute o seguinte em uma estação de trabalho conectada para buscar os componentes do MySQL 8.4 e do 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')
"

Transferir e instalar

Faça o upload dos arquivos .deb para /tmp/packages/ em todas as três VMs e instale:

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

Verifique se o dpkg não retorna erros. Se isso acontecer, confira os registros para ver quais pacotes deb estão faltando e inclua-os no download.

Quando solicitado a definir a senha raiz, deixe-a em branco. Vamos definir a senha mais tarde.

Configuração do nó do MySQL

Configurar o MySQL para uso em cluster

Edite /etc/mysql/mysql.conf.d/mysqld.cnf em todos os nós para ativar GTIDs e registro binário:

[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

Reinicie o serviço:

sudo systemctl restart mysql

Em seguida, conecte-se ao banco de dados:

sudo mysql

e defina a senha raiz:

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

Inicialização e verificação do cluster do InnoDB

Criar cluster usando o MySQL Shell

SOMENTE NA VM 1, use o MySQL Shell para inicializar o cluster:

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()

Inicializar o MySQL Router

Em todas as três VMs, inicialize o roteador para detectar o novo cluster:

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

Verificar balanceamento e conexões

Execute esses comandos em qualquer nó para garantir que o roteador esteja distribuindo o tráfego corretamente.

  1. Verificar o roteamento de gravação (primário ativo): consulte a porta 6446 (RW clássico). Ela precisa retornar estritamente o nome do host do primário atual.

    mysql -u root -pyour_new_secure_password -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  2. Verificar o balanceamento de leitura (round-robin): consulte a porta 6447 (RO clássico) várias vezes. Ela precisa passar pelos nomes de host de todos os nós disponíveis no cluster.

    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. Verificar a topologia de conexão: use o MySQL Shell para confirmar se todos os membros estão ONLINE e corretamente balanceados.

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

Configuração do balanceador de carga global

Forneça um IP virtual (VIP) único e estável para seus aplicativos usando o balanceador de carga global L4 do GDC. Siga as etapas em Configurar balanceadores de carga globais internos para configurar o balanceador de carga global L4 interno e configurar suas VMs como destino dele: Configurar VMs como destino do balanceador de carga.

Verificação de failover automatizado

Esse teste confirma que o cluster elege um novo líder e o roteador redireciona o tráfego sem intervenção manual.

Simular falha primária

Identifique o primário atual (por exemplo, o nó 1) e interrompa o serviço do MySQL:

sudo systemctl stop mysql

Verificar a eleição e a mudança de roteamento

Aguarde de 10 a 20 segundos para que o protocolo de consenso eleja um novo líder.

  1. Verificar o status do cluster: na VM 2 ou 3, verifique se um novo primário foi eleito.

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

    Confirme se um dos nós restantes está marcado como PRIMARY e o nó com falha está marcado como UNREACHABLE ou MISSING.

  2. Verificar o roteamento de gravação: teste a porta RW (6446) novamente. Ela precisa retornar o nome do host do novo primário.

    mysql -u root -p -h 127.0.0.1 -P 6446 -e "SELECT @@hostname;"
    
  3. Testar a conectividade do VIP global: em um servidor de aplicativos, consulte o VIP global.

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

Recuperar e verificar a nova participação

Inicie o serviço do MySQL no nó com falha e verifique se ele participa novamente como uma réplica secundária.

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

Confirme se todos os três nós retornam o status ONLINE.