Atraso da replicação

Nesta página, descrevemos como resolver problemas e corrigir atrasos de replicação para réplicas de leitura do Cloud SQL.

Visão geral

As réplicas de leitura do Cloud SQL usam a replicação de streaming do PostgreSQL. As alterações são gravadas no registro de gravação antecipada (WAL) na instância principal. O remetente do WAL envia o WAL para o receptor do WAL na réplica, onde são aplicados.

O atraso da replicação pode acontecer em alguns cenários, como:

  • A instância principal não pode enviar as alterações com rapidez suficiente para a réplica.
  • A réplica não recebe as alterações com rapidez suficiente.
  • A réplica não pode aplicar as alterações com rapidez suficiente.
Os dois primeiros motivos mencionados acima podem ser monitorados com a métrica network_lag. O terceiro é observado por meio da métrica replica_lag. replica_lag alto significa que a réplica não pode aplicar alterações de replicação com rapidez suficiente. O atraso total pode ser observado com a métrica replica_byte_lag, que tem rótulos para indicar mais detalhes. Essas métricas são descritas na seção Monitorar atraso da replicação abaixo.

Verificar se a réplica está provisionada adequadamente

Uma instância de réplica menor que a instância principal (por exemplo, com menos vCPUs e memória) pode ter um atraso na replicação. Uma réplica menor também pode ter flags de configuração padrão diferentes em comparação com uma instância principal maior. Recomendamos que a instância de réplica seja pelo menos tão grande quanto a instância principal para ter recursos suficientes para lidar com a carga de replicação.

A alta utilização da CPU na réplica também pode causar atraso na replicação. Se a utilização da CPU da réplica estiver alta (por exemplo, acima de 90%), considere aumentar a capacidade da CPU da réplica.

Use o comando SHOW ALL para conferir a configuração da réplica e da instância principal e compará-las para identificar diferenças.

Otimizar consultas e esquema

Nesta seção, sugerimos algumas otimizações comuns de consulta e esquema que podem ser feitas para melhorar o desempenho da replicação.

Consultas de longa duração na réplica de leitura

Consultas de longa duração na réplica podem bloquear a replicação para o Cloud SQL. Isso pode acontecer quando a replicação tenta aplicar mudanças (como de uma operação VACUUM) a linhas que estão sendo lidas por uma consulta na réplica.

Talvez você queira ter réplicas separadas para fins de processamento de transações on-line (OLTP, na sigla em inglês) e processamento analítico on-line (OLAP, na sigla em inglês) e enviar apenas consultas de longa duração para a réplica OLAP.

Para ajudar a resolver atrasos ou bloqueios na replicação causados por transações de longa duração, recomendamos o seguinte:

  • Ajuste as flags de atraso de espera. As flags max_standby_archive_delay e max_standby_streaming_delay controlam quanto tempo uma réplica aguarda antes de cancelar consultas em espera que conflitam com a replicação. Valores razoáveis costumam ficar entre 30 e 60 segundos. Confira a visualização pg_stat_database_conflicts para insights sobre conflitos de consultas.
  • Ative a flag hot_standby_feedback. Definir a flag hot_standby_feedback como on na réplica pode ajudar a atrasar as operações de limpeza na principal. No entanto, isso pode causar o aumento da tabela no servidor principal, então é uma troca.

Consulte a documentação do PostgreSQL para mais informações.

Atraso de rede alto

Um alto atraso de rede indica que os registros WAL não estão sendo enviados pelo primário ou recebidos pela réplica com rapidez suficiente. Isso pode ser causado por:

  • Replicação entre regiões. A replicação entre regiões diferentes pode aumentar a latência da rede.
  • Uso elevado da CPU principal. Se a CPU da primária estiver acima de 90%, o processo de envio de WAL poderá não receber tempo de CPU suficiente. Considere reduzir a carga na instância principal ou aumentar a CPU dela.
  • Uso elevado da CPU da réplica. Se a CPU da réplica estiver acima de 90%, o processo de recebimento de WAL talvez não receba tempo de CPU suficiente. Considere reduzir a carga na réplica ou aumentar a CPU dela.
  • Problemas de largura de banda da rede ou gargalos de E/S de disco. Uma região mais próxima ou uma configuração de disco de maior capacidade pode ajudar. Considere modificar o valor da flag wal_compression na instância principal para ajudar a reduzir o tráfego entre regiões.
É possível monitorar o atraso de rede com a métrica cloudsql.googleapis.com/database/replication/network_lag. Essa métrica tem um limite máximo de 25 segundos, mesmo que o atraso real seja maior.

Essa métrica network_lag é semelhante à métrica cloudsql.googleapis.com/database/postgresql/replication/replica_byte_lag, que mede o atraso sent_location em termos de bytes indicado pelo rótulo replica_lag_type.

Bloqueios exclusivos devido a DDL

Os comandos da linguagem de definição de dados (DDL), como ALTER TABLE e CREATE INDEX, podem causar atraso de replicação na réplica devido a bloqueios exclusivos. Para evitar a contenção de bloqueio, programe a execução do DDL quando a carga da consulta for menor nas réplicas.

Consulte a documentação do PostgreSQL para mais informações.

Réplica sobrecarregada

Se uma réplica de leitura estiver recebendo muitas consultas, a replicação poderá ser bloqueada. Divida as leituras entre várias réplicas para reduzir a carga em cada uma.

Para evitar picos de consulta, limite as consultas de leitura de réplica na lógica do aplicativo ou em uma camada de proxy, se usar uma.

Se houver picos de atividade na instância principal, considere distribuir as atualizações.

Banco de dados primário monolítico

Considere fragmentar o banco de dados primário verticalmente (ou horizontalmente) para impedir que uma ou mais tabelas atrasadas retenham todas as outras tabelas.

Monitorar atraso de replicação

Use as métricas replica_lag e network_lag para monitorar a atraso da replicação e identificar se a causa do atraso está no banco de dados principal, na rede ou na réplica.

MétricaDescrição
Atraso da replicação
(cloudsql.googleapis.com/database/replication/replica_lag)

O número de segundos em que o estado da réplica está atrasado em relação ao estado da instância principal. Essa é a diferença entre o horário atual e o carimbo de data/hora original em que o banco de dados primário confirmou a transação que está sendo aplicada na réplica. Em particular, as gravações podem ser contadas com atraso, mesmo que tenham sido recebidas pela réplica, se a réplica ainda não tiver aplicado a gravação ao banco de dados.

Essa métrica é calculada usando now() - pg_last_xact_replay_timestamp() na réplica. Isso é uma aproximação. Se a replicação estiver corrompida, a réplica não saberá o quão distante o banco de dados principal está e essa métrica não indicará o atraso total.

Bytes de atraso
(cloudsql.googleapis.com/database/postgres/replication/replica_byte_lag)

A quantidade de bytes em que o estado da réplica está atrasado em relação ao estado do banco de dados principal. replica_byte_lag exporta quatro séries temporais, e o rótulo replica_lag_type pode indicar qualquer um dos seguintes itens:

  • sent_location: indica quantos bytes do WAL foram gerados, mas ainda não foram enviados para a réplica.
  • write_location: o atraso de gravação menos enviado mostra bytes WAL na rede que foram enviados, mas ainda não foram gravados na réplica.
  • flush_location: o atraso na transferência menos o atraso na gravação mostra os bytes de WAL gravados na réplica, mas que ainda não foram transferidos para a réplica.
  • replay_location: mostra o atraso total em bytes. O atraso da reprodução menos o atraso de transferência indica um atraso na repetição.
Atraso da rede
(cloudsql.googleapis.com/database/replication/network_lag)

O tempo, em segundos, que leva da confirmação no banco de dados primário para alcançar o receptor do WAL na réplica.

Se o network_lag for zero ou insignificante, mas o replica_lag for alto, isso indica que a linha de execução SQL não pode aplicar mudanças de replicação com rapidez suficiente.

Verificar a replicação

Para verificar se a replicação está funcionando, execute a seguinte instrução na réplica:

  select status, last_msg_receipt_time from pg_stat_wal_receiver;

Se a replicação estiver acontecendo, você verá o status streaming e um último last_msg_receipt_time:

  postgres=> select status, last_msg_receipt_time from pg_stat_wal_receiver;
    status   |     last_msg_receipt_time
  -----------+-------------------------------
  streaming | 2020-01-21 20:19:51.461535+00
  (1 row)

Se a replicação não estiver acontecendo, um resultado vazio será retornado:

  postgres=> select status, last_msg_receipt_time from pg_stat_wal_receiver;
  status | last_msg_receipt_time
  --------+-----------------------
  (0 rows)

Qual é a próxima etapa?