Nesta página, descrevemos como usar o slot de failover lógico para configurar a replicação lógica do Cloud SQL para PostgreSQL de modo que funcione perfeitamente com operações de recuperação de desastres (DR) avançada, especificamente a troca e o failover de réplica em instâncias com a edição Cloud SQL Enterprise Plus.
Os recursos avançados de recuperação de desastres (DR) do Cloud SQL oferecem recursos robustos de recuperação de desastres. Quando combinado com a replicação lógica do PostgreSQL, é crucial que o fluxo de replicação permaneça ininterrupto após uma troca ou um failover de réplica.
Usando a recuperação de desastres (DR) avançada com a replicação lógica do PostgreSQL, você garante que os assinantes lógicos não percam dados e possam se reconectar automaticamente à nova instância principal após um evento de recuperação de desastres, garantindo assim a continuidade dos negócios.
É possível usar essa funcionalidade em instâncias do Cloud SQL com a seguinte configuração:
- PostgreSQL versão 17 ou mais recente
- Edição do Cloud SQL Enterprise Plus
Acesso a serviços particulares
Recomendamos usar o endpoint de gravação do serviço de nome de domínio (DNS) de acesso a serviços particulares para ativar reconexões automáticas de assinantes lógicos.
Antes de começar
-
Use a versão 502.0.0 ou posterior. Para verificar a versão do SDK Google Cloud, execute
gcloud --version. Para atualizar o SDK Google Cloud, executegcloud components update. Crie um Google Cloud projeto ou selecione um projeto atual.
Conceda os papéis e as permissões necessários do Identity and Access Management (IAM).
Para criar um projeto: Criador de projetos (
roles/resourcemanager.projectCreator)Para criar e gerenciar instâncias do Cloud SQL: Administrador do Cloud SQL (
roles/cloudsql.admin)Para criar e gerenciar VMs do Compute Engine: Administrador da instância do Compute (v1) (
roles/compute.instanceAdmin.v1) e Leitor do Compute (roles/compute.networkViewer)Para criar redes VPC: Administrador de rede (
roles/compute.networkAdmin)
Para mais informações, consulte Papéis e permissões.
Para saber como conceder papéis e permissões do IAM, consulte Gerenciar o acesso a projetos, pastas e organizações.
Configurar a recuperação avançada de desastres (DR) com replicação lógica
O processo para configurar a recuperação de desastres (DR) avançada com a replicação lógica do PostgreSQL tem as seguintes etapas gerais:
- Configure as variáveis de ambiente e a VM bastion.
- Crie e configure a instância principal.
- Criar e designar uma réplica de DR.
- Crie e configure uma instância de assinante lógico.
- Crie uma assinatura de replicação lógica.
- Faça uma troca ou um failover de réplica.
- Valide a replicação.
- Limpe o slot de replicação órfão na nova réplica.
- Opcional: faça o switchback.
Configurar variáveis de ambiente e VM bastião
Defina as seguintes variáveis de ambiente.
# Project export PROJECT="PROJECT_ID" # Instance names export PRIMARY_INSTANCE_NAME="PRIMARY_INSTANCE" export DR_REPLICA_NAME="DR_REPLICA" export SUBSCRIBER_INSTANCE_NAME="SUBSCRIBER_INSTANCE" export BASTION_VM_NAME="BASTION_VM" # Regions and zones export PRIMARY_REGION="PRIMARY_REGION" export REPLICA_REGION="REPLICA_REGION" export SUBSCRIBER_REGION="SUBSCRIBER_REGION" export VM_ZONE="VM_ZONE" # Network export NETWORK_NAME="NETWORK" # Credentials export POSTGRES_PASSWORD="PASSWORD" # Set gcloud project gcloud config set project PROJECT_IDSubstitua:
- PROJECT_ID: ID do projeto.
- PRIMARY_INSTANCE: o nome da instância principal do Cloud SQL.
- DR_REPLICA: o nome da réplica.
- SUBSCRIBER_INSTANCE: o nome da instância do assinante.
- BASTION_VM: o nome da VM bastion.
- PRIMARY_REGION: a região em que a instância principal está localizada.
- REPLICA_REGION: a região em que a réplica está localizada. A réplica precisa estar em uma região diferente da instância principal.
- SUBSCRIBER_REGION: a região em que o assinante está localizado.
- VM_ZONE: a zona em que a VM bastião está localizada.
- NETWORK: o nome da sua rede VPC.
- PASSWORD: a senha do usuário
postgres.
Crie uma VM bastion do Compute Engine.
As instâncias do Cloud SQL usam IP particular. Portanto, crie uma VM de Bastion Host do Compute Engine na sua rede VPC.
gcloud compute instances create $BASTION_VM_NAME \ --zone=$VM_ZONE \ --machine-type=e2-small \ --network=projects/$PROJECT_ID/global/networks/$NETWORK_NAME \ --image-project=debian-cloud \ --image-family=debian-11 \ --project=$PROJECTConecte-se à VM bastion.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTNa VM bastion, instale o cliente PostgreSQL.
sudo apt-get update sudo apt-get install -y postgresql-client exit
Os comandos do PostgreSQL nas etapas subsequentes precisam ser executados na VM bastion.
Criar e configurar a instância principal
Crie a instância principal do Cloud SQL.
gcloud sql instances create $PRIMARY_INSTANCE_NAME \ --database-version=POSTGRES_17 \ --edition=ENTERPRISE_PLUS \ --region=$PRIMARY_REGION \ --tier=db-perf-optimized-N-2 \ --no-assign-ip \ --network=projects/$PROJECT/global/networks/$NETWORK_NAME \ --project=$PROJECTAtive a decodificação lógica.
gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --database-flags=cloudsql.logical_decoding=on \ --project=$PROJECTDefina a senha do usuário
postgresno servidor principal.gcloud sql users set-password postgres \ --instance=$PRIMARY_INSTANCE_NAME \ --password="$POSTGRES_PASSWORD" \ --project=$PROJECTConecte-se à instância principal pela VM bastion.
Recupere o endereço IP privado da instância principal.
gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECTCopie e mantenha o endereço IP privado da instância principal.
Conecte-se por SSH à VM bastion.
gcloud compute ssh $BASTION_VM_NAME --zone=$VM_ZONE --project=$PROJECTNa VM bastion, conecte-se à instância principal.
psql -h PRIMARY_PRIVATE_IP -U postgresSubstitua PRIMARY_PRIVATE_IP pelo IP particular da instância principal que você recuperou na Etapa 4.a deste procedimento.
Quando uma senha for solicitada, insira a variável
$POSTGRES_PASSWORD.A VM bastion agora está conectada à instância principal pelo PostgreSQL.
Conceda permissões e crie a publicação.
Conceda o privilégio
REPLICATIONao usuáriopostgres.ALTER USER postgres WITH REPLICATION;Conceda os privilégios necessários no esquema e nas tabelas públicos.
GRANT SELECT ON ALL TABLES IN SCHEMA public TO postgres;Crie a publicação para todas as tabelas.
CREATE PUBLICATION my_publication FOR ALL TABLES;Digite
exitpara sair do PostgreSQL eexitnovamente para fechar a sessão SSH da VM bastion.
Criar e designar uma réplica de recuperação de desastres (réplica de DR)
Crie uma réplica de DR.
gcloud sql instances create $DR_REPLICA_NAME \ --master-instance-name=$PRIMARY_INSTANCE_NAME \ --edition=ENTERPRISE_PLUS \ --tier=db-perf-optimized-N-2 \ --region=$REPLICA_REGION \ --no-assign-ip \ --network=projects/$PROJECT/global/networks/$NETWORK_NAME \ --project=$PROJECTDesignar essa réplica como a réplica de DR.
gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --failover-dr-replica-name=$DR_REPLICA_NAME \ --project=$PROJECTConfigure a réplica de DR para sincronização de slot lógico.
gcloud sql instances patch $DR_REPLICA_NAME \ --database-flags="^:^cloudsql.logical_decoding=on:hot_standby_feedback=on:sync_replication_slots=on:cloudsql.logical_slot_sync_dbname=postgres" \ --project=$PROJECTConfigure a replicação síncrona entre a instância principal e a réplica de DR.
Para evitar a perda de dados no assinante lógico em caso de uma interrupção repentina da instância principal e um failover de réplica subsequente, recomendamos que você configure a replicação síncrona entre a instância principal e a réplica de DR.
Definir
cloudsql.synchronized_standby_replicasna instância principal força o remetente do registro de gravação antecipada (WAL) da replicação lógica da instância principal a aguardar até que a réplica de DR receba e limpe o WAL de uma determinada transação antes de enviar essa transação ao assinante lógico. Isso garante que o estado da réplica de DR esteja sempre à frente ou igual ao estado do assinante lógico.gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --database-flags="^:^cloudsql.logical_decoding=on:cloudsql.synchronized_standby_replicas=$DR_REPLICA_NAME" \ --project=$PROJECT
Criar e configurar uma instância de assinante lógico
Crie uma instância de assinante.
gcloud sql instances create $SUBSCRIBER_INSTANCE_NAME \ --database-version=POSTGRES_17 \ --tier=db-perf-optimized-N-2 \ --region=$SUBSCRIBER_REGION \ --no-assign-ip \ --network=projects/$PROJECT/global/networks/$NETWORK_NAME \ --project=$PROJECTAtive a decodificação lógica no assinante.
gcloud sql instances patch $SUBSCRIBER_INSTANCE_NAME \ --database-flags=cloudsql.logical_decoding=on \ --project=$PROJECT
Criar uma assinatura de replicação lógica
Recupere o endpoint de gravação de acesso a serviços particulares da instância principal.
gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --format="value(replicationCluster.psaWriteEndpoint)" \ --project=$PROJECTCopie e mantenha o endpoint de gravação.
Conecte-se à instância do assinante.
Atualize a senha do usuário
postgresda instância assinante.gcloud sql users set-password postgres \ --instance=$SUBSCRIBER_INSTANCE_NAME \ --password="$POSTGRES_PASSWORD" \ --project=$PROJECTRecupere o endereço IP privado da instância do assinante.
gcloud sql instances describe $SUBSCRIBER_INSTANCE_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECTCopie e guarde o endereço IP particular.
Conecte-se por SSH à VM bastion.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTNa VM bastion, conecte-se à instância do assinante pelo PostgreSQL.
psql -h SUBSCRIBER_PRIVATE_IP -U postgresSubstitua SUBSCRIBER_PRIVATE_IP pelo IP particular da instância do assinante que você copiou na Etapa 2.b deste procedimento.
Quando uma senha for solicitada, insira a variável
$POSTGRES_PASSWORD.
Crie uma assinatura.
CREATE SUBSCRIPTION my_subscription CONNECTION 'host=DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT port=5432 dbname=postgres user=postgres password=PASSWORD' PUBLICATION my_publication WITH (failover = true);Substitua:
- DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT: o endpoint de gravação de acesso a serviços particulares que você copiou na Etapa 1 deste procedimento.
- PASSWORD: o valor da variável
${POSTGRES_PASSWORD}.
Saia do PostgreSQL e da sessão SSH da VM bastion.
Opcional. Verifique a persistência do slot na réplica de DR.
Essa transição para persistente (
temporary = false) geralmente ocorre rapidamente, muitas vezes em segundos, se o primário tiver pouca atividade. Com uma carga de gravação pesada no servidor principal, esse processo pode levar mais tempo, geralmente cerca de um minuto. O slot vai permanecer após a conclusão desses comandos manuais.Consiga o endereço IP particular da réplica de DR.
gcloud sql instances describe $DR_REPLICA_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECTCopie e mantenha o endereço IP particular da réplica de DR.
Conecte-se por SSH à VM bastion.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTNa VM bastion, conecte-se à réplica de DR.
psql -h DR_REPLICA_PRIVATE_IP -U postgresSubstitua DR_REPLICA_PRIVATE_IP pelo endereço IP particular da réplica de DR que você recuperou na Etapa 5.a deste procedimento.
Quando uma senha for solicitada, insira a variável
$POSTGRES_PASSWORD.Verifique o status do slot.
SELECT slot_name, slot_type, temporary, failover, synced FROM pg_replication_slots WHERE slot_type = 'logical' AND failover = true;Aguarde até que a coluna
temporaryse tornef. Isso geralmente leva menos de um minuto.Saia do PostgreSQL e da sessão SSH da VM bastion.
Realizar uma troca ou um failover de réplica
Escolha a operação que você quer realizar com base no seu cenário:
Alternância (inversão de função planejada): escolha essa opção para manutenção planejada, teste de recuperação de desastres ou para alternar funções quando a instância principal estiver on-line e íntegra. Essa operação garante zero perda de dados para a replicação física.
gcloud sql instances switchover $DR_REPLICA_NAME \ --project=$PROJECTFailover de réplica (recuperação de desastres): escolha essa opção quando a instância principal estiver indisponível ou sem resposta. Essa operação promove a réplica de DR para principal. Para minimizar o risco de perda de dados para o assinante lógico, verifique se o
cloudsql.synchronized_standby_replicasfoi definido na instância principal conforme recomendado em Criar e designar uma réplica de recuperação de desastres (réplica de DR).gcloud sql instances promote-replica $DR_REPLICA_NAME \ --failover \ --project=$PROJECTA promoção do
$DR_REPLICA_NAMEacontece rapidamente. No entanto, a instância principal original ($PRIMARY_INSTANCE_NAME) só é reconfigurada como uma réplica da nova principal quando volta a ficar on-line. Para acompanhar isso, procure a conclusão da operaçãoRECONFIGURE_OLD_PRIMARYem$PRIMARY_INSTANCE_NAMEno registro de operações. Execute este comando:gcloud sql operations list --instance=$PRIMARY_INSTANCE_NAME --project=$PROJECT --limit=10`A configuração de recuperação de desastres só é totalmente restaurada após a conclusão dessa fase.
Depois de qualquer uma das operações, o assinante se reconecta automaticamente ao novo
$DR_REPLICA_NAME principal pelo endpoint de gravação de acesso a serviços particulares.
Gerenciamento de flags
Os fluxos de trabalho do Cloud SQL gerenciam automaticamente as flags de banco de dados necessárias nas duas instâncias do cluster de recuperação de desastres durante e após as operações de failover de réplica e de troca, incluindo:
- As flags de sincronização de slot lógico (
cloudsql.logical_decoding,hot_standby_feedback,sync_replication_slots,cloudsql.logical_slot_sync_dbname) são corretas na instância que se torna a nova réplica. - A flag
cloudsql.synchronized_standby_replicasna instância que se torna a nova principal é atualizada automaticamente para apontar para o nome da nova réplica de DR.
Não é necessário reaplicar ou mudar manualmente essas flags após uma troca ou operação de failover de réplica. O Cloud SQL mantém a configuração correta para as funções de principal e réplica.
Validar replicação
Verifique o status do assinante.
Na VM bastion, execute o seguinte comando.
psql -h SUBSCRIBER_PRIVATE_IP -U postgresSubstitua SUBSCRIBER_PRIVATE_IP pelo endereço IP privado da instância do assinante.
Na instância do assinante, execute o seguinte comando:
SELECT subname, pid IS NOT NULL AS is_active FROM pg_stat_subscription;O status precisa ser
streaming.
Verifique o status do slot de replicação da nova instância principal. O novo primário é a antiga réplica de DR (
$DR_REPLICA_NAME).Receba o endereço IP privado do novo primário.
gcloud sql instances describe $DR_REPLICA_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"Copie e mantenha o endereço IP particular da nova principal.
Conecte-se por SSH à VM bastion.
psql -h NEW_PRIMARY_PRIVATE_IP -U postgresSubstitua NEW_PRIMARY_PRIVATE_IP pelo endereço IP privado do novo primário que você copiou na etapa anterior.
Na nova instância principal, execute os seguintes comandos.
SELECT slot_name, slot_type, active, synced, active_pid, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS replication_lag FROM pg_replication_slots WHERE slot_type = 'logical';O slot (por exemplo,
my_subscription) precisa seractive = t.SELECT application_name, state FROM pg_stat_replication;pg_stat_replicationvai mostrar o assinante conectado.
Limpar o slot de replicação órfão na nova réplica
Depois que a operação de alternância e failover for concluída, a instância principal
original ($PRIMARY_INSTANCE_NAME) será uma réplica. Essa nova instância de réplica ainda retém o slot de replicação lógica original chamado my_subscription no disco. Este slot my_subscription agora está órfão porque
o assinante precisa se conectar ao novo primário ($DR_REPLICA_NAME)
pelo endpoint de gravação de acesso a serviços particulares.
O Cloud SQL não remove automaticamente esse slot órfão da nova réplica. Isso acontece porque o Cloud SQL não consegue determinar se o assinante foi configurado para usar o endereço IP da instância em vez do endpoint de gravação de acesso a serviços particulares. O assinante ainda pode estar tentando se conectar a esse slot antigo na nova réplica até que a assinatura seja alterada manualmente. A remoção automática do slot pode prejudicar essas configurações.
A presença desse slot órfão na nova réplica ($PRIMARY_INSTANCE_NAME)
faz com que o processo de trabalho slotsync nessa instância gere erros nos
registros. Talvez você veja uma mensagem de erro como esta no postgres.log da nova réplica. Esse erro continua se repetindo enquanto o worker slotsync tenta.
ERROR: exiting from slot synchronization because same name slot "my_subscription" already exists on the standby
Para evitar esses erros e permitir que o worker slotsync estabeleça corretamente uma
nova versão sincronizada do slot my_subscription nessa réplica, é necessário
descartar manualmente o slot órfão. Isso garante que a instância esteja preparada adequadamente se você pretende fazer o switchback no futuro.
Recupere o endereço IP particular da nova réplica (
$PRIMARY_INSTANCE_NAME).gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"Copie e mantenha o endereço IP privado da nova réplica.
Conecte-se por SSH à VM bastion.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTNa VM bastion, conecte-se à nova réplica.
psql -h NEW_REPLICA_IP -U postgresSubstitua NEW_REPLICA_IP pelo endereço IP da nova réplica que você copiou na Etapa 1 deste procedimento.
Quando uma senha for solicitada, insira a variável
$POSTGRES_PASSWORD.Na nova réplica (
$PRIMARY_INSTANCE_NAME), descarte o slot órfão.SELECT slot_name, slot_type, temporary, failover, synced, active FROM pg_replication_slots WHERE slot_name = 'my_subscription';Confirme se o slot existe com
synced = falseeactive = falsee solte-o.SELECT pg_drop_replication_slot('my_subscription');O slot órfão é removido.
Resincronização automática de slots
Quando o slot órfão é descartado, o worker slotsync na nova réplica
($PRIMARY_INSTANCE_NAME) se conecta automaticamente à nova instância primária
($DR_REPLICA_NAME) no próximo ciclo. Ele cria um novo slot my_subscription
local que é sincronizado com o slot ativo do novo primário.
Você pode conferir mensagens no postgres.log da nova réplica indicando sucesso,
semelhante a esta:
LOG: newly created slot "my_subscription" is sync-ready now
O novo slot sincronizado tem failover=true e, eventualmente, se torna permanente
(temporary=false), garantindo que, se você fizer o switchback mais tarde, essa instância estará pronta.
Opcional: faça o retorno
Agora, mude de volta, tornando
$PRIMARY_INSTANCE_NAMEa instância principal novamente.gcloud sql instances switchover $PRIMARY_INSTANCE_NAME \ --project=$PROJECTFaça a verificação após o switchback.
Verifique o status da instância do assinante.
SELECT subname, pid IS NOT NULL AS is_active FROM pg_stat_subscription;A assinatura ainda precisa estar ativa, ou seja,
is_active = t.Verifique o status do slot do novo primário (
$PRIMARY_INSTANCE_NAME).SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical'; SELECT * FROM pg_stat_replication;O slot precisa estar ativo e o assinante conectado.
Resolver problemas
| Problema | Solução de problemas |
|---|---|
Erro na nova réplica (ou seja, a antiga instância principal) após a troca:
|
Siga as etapas em Limpar o slot de replicação órfão na nova réplica. |