Dominando a Replicação PostgreSQL: Tipos e Configuração Explicados

Aprenda como funcionam a replicação streaming e lógica do PostgreSQL, quando usar cada uma e o que verificar antes de um failover em produção.

Dominando a Replicação do PostgreSQL: Tipos e Configuração Explicados

A replicação do PostgreSQL mantém um segundo servidor suficientemente próximo do primário para que você possa sobreviver a falhas de hardware, redirecionar tráfego de leitura ou realizar uma migração controlada. Se o seu banco de dados é uma dependência de produção, você precisa saber qual modelo de replicação do PostgreSQL se adequa à sua tolerância a riscos antes que um nó falhe.

O PostgreSQL oferece duas opções comuns: replicação streaming e replicação lógica. A replicação streaming copia o WAL no nível do cluster físico. A replicação lógica envia alterações no nível da linha de tabelas selecionadas por meio de publicações e assinaturas.

Por que a Replicação do PostgreSQL é Importante

A replicação ajuda com quatro problemas operacionais do dia a dia:

  • Alta disponibilidade: Se o primário falhar, você pode promover um standby e direcionar os aplicativos para ele.
  • Recuperação de desastres: Um standby em outra localização pode protegê-lo contra uma falha no nível do site.
  • Escalabilidade de leitura: Consultas somente leitura podem ser executadas em standbys ativos em vez do primário de escrita.
  • Suporte a migração: A replicação lógica pode ajudar a mover tabelas selecionadas entre versões do PostgreSQL ou layouts de banco de dados.

A replicação não substitui backups. Um bug, uma migração ruim ou um DELETE acidental podem se replicar rapidamente. Mantenha backups testados e recuperação pontual juntamente com a replicação.

Replicação Streaming (Replicação Física)

A replicação streaming é a forma mais comum e fundamental de replicação no PostgreSQL. Ela funciona enviando registros do Write-Ahead Log (WAL) do servidor primário para uma ou mais réplicas. Esses registros WAL representam cada alteração feita no banco de dados. As réplicas então aplicam esses registros WAL em seus próprios arquivos de dados, garantindo que permaneçam consistentes com o primário.

Streaming Síncrono vs. Assíncrono

A replicação síncrona faz com que o primário aguarde um ou mais standbys síncronos antes de relatar um commit ao cliente. O nível exato de segurança depende de synchronous_commit; por exemplo, aguardar a gravação do WAL é diferente de aguardar sua reprodução. Você obtém uma proteção mais forte contra a perda de commits confirmados, mas cada commit agora depende da latência da réplica e da rede.

A replicação assíncrona permite que o primário faça commit localmente e envie o WAL para as réplicas posteriormente. É mais rápida para escritas, mas uma falha no primário pode perder transações recentes que ainda não haviam chegado a um standby.

Configurando a Replicação Streaming (Exemplo Assíncrono)

A configuração da replicação streaming envolve a configuração dos servidores primário e réplica. Aqui está um guia simplificado:

1. Configurar o Servidor Primário (postgresql.conf e pg_hba.conf)

No servidor primário, você precisa habilitar o arquivamento WAL e as conexões de replicação.

  • Modificações no postgresql.conf:

    wal_level = replica  # ou logical para replicação lógica
    max_wal_senders = 5  # Número de conexões de replicação simultâneas
    wal_keep_size = 512MB # Ou wal_keep_segments para versões mais antigas
    # Para replicação síncrona, adicione:
    # synchronous_standby_names = 'replica1,replica2'
    # Ou para nome/prioridade de servidor específico:
    # synchronous_standby_names = '1 (replica1), 2 (replica2)'
    archive_mode = on
    archive_command = 'test ! -f /path/to/wal_archive/%f && cp %p /path/to/wal_archive/%f'
    
    • wal_level: Deve ser pelo menos replica para replicação streaming.
    • max_wal_senders: Especifica quantos servidores standby podem conectar simultaneamente.
    • wal_keep_size: Impede que arquivos WAL sejam excluídos antes que as réplicas possam buscá-los (uma alternativa mais simples ao archive_command para configurações básicas, mas o arquivamento é recomendado para robustez).
    • archive_mode e archive_command: Úteis para recuperação pontual (PITR) e para réplicas que precisam de WAL antigo após ficarem para trás. Em produção, use um destino de arquivamento real ou uma ferramenta de backup em vez de um comando de cópia local.
  • Modificações no pg_hba.conf:

    Permita que a réplica se conecte para replicação. Substitua replica_ip_address pelo IP real da sua réplica.

    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    host    replication     replication_user  replica_ip_address/32   md5
    

    Você também precisará criar um usuário de replicação:

    -- No servidor primário:
    CREATE ROLE replication_user WITH REPLICATION LOGIN PASSWORD 'your_password';
    

    Após modificar esses arquivos, recarregue a configuração do PostgreSQL:

    pg_ctl reload
    # Ou reinicie o PostgreSQL, se necessário
    

2. Preparar o Servidor Réplica

Antes de iniciar a réplica, ela deve ter um diretório de dados que seja uma cópia do diretório de dados do primário em um ponto específico no tempo. A maneira mais fácil é usar pg_basebackup.

  • Pare o PostgreSQL na réplica (se estiver em execução).

  • Faça um backup base:

    # Certifique-se de que PGDATA esteja vazio ou removido primeiro
    pg_basebackup -h primary_host_ip -p 5432 -U replication_user -D /var/lib/postgresql/data/ -Fp -Xs -P -R
    
    • -h, -p, -U: Especifica os detalhes de conexão do servidor primário.
    • -D: O diretório de dados para a réplica.
    • -Fp: O formato é simples.
    • -Xs: Transmite WAL durante o backup.
    • -P: Mostra o progresso.
    • -R: Escreve as configurações de conexão do standby e cria standby.signal para PostgreSQL 12 e mais recentes.
    • Você será solicitado a fornecer a senha do replication_user.

3. Configurar o Servidor Réplica

  • Modificações no postgresql.conf (para PG12+):

    hot_standby = on # Permite consultas somente leitura na réplica
    primary_conninfo = 'host=primary_host_ip port=5432 user=replication_user password=your_password'
    
    • hot_standby: Habilita consultas somente leitura no standby.
    • primary_conninfo: String de conexão para o servidor primário.
  • Versões mais antigas do PostgreSQL:

    O PostgreSQL 12 removeu recovery.conf. Se você mantém um servidor mais antigo, crie recovery.conf no diretório de dados da réplica:

    standby_mode = 'on'
    primary_conninfo = 'host=primary_host_ip port=5432 user=replication_user password=your_password'
    # Se estiver usando recuperação de arquivo em vez de streaming, especifique restore_command
    # restore_command = 'cp /path/to/wal_archive/%f %p'
    # recovery_target_timeline = 'latest'
    

    No PostgreSQL 12 e mais recentes, o modo standby é controlado por standby.signal, e primary_conninfo geralmente reside em postgresql.auto.conf quando criado por pg_basebackup -R.

4. Iniciar o Servidor Réplica

Inicie o serviço PostgreSQL na réplica. Ele se conectará ao primário, receberá registros WAL e começará a sincronizar. Você pode verificar os logs para confirmação.

Dica: Para HA robusto, considere usar ferramentas como Patroni ou repmgr, que automatizam failover e gerenciamento.

Replicação Lógica

A replicação lógica é uma forma mais flexível e granular de replicação introduzida no PostgreSQL 10. Em vez de replicar blocos inteiros de dados ou registros WAL, ela replica alterações de dados com base em seu significado lógico (por exemplo, instruções INSERT, UPDATE, DELETE) no nível da linha. Isso é alcançado decodificando os registros WAL em um fluxo de alterações lógicas.

Principais Recursos e Casos de Uso:

  • Replicação seletiva: Você pode escolher quais tabelas replicar. Versões recentes do PostgreSQL também suportam listas de colunas em publicações, mas verifique a versão do seu servidor antes de confiar nesse recurso.
  • Replicação entre versões: A replicação lógica pode replicar dados entre diferentes versões principais do PostgreSQL.
  • Controle de esquema: A replicação lógica não replica DDL automaticamente. Crie tabelas correspondentes e aplique migrações de esquema no assinante.
  • Transformação de dados: Embora não seja embutido, a replicação lógica fornece uma base para processos ETL (Extract, Transform, Load) mais complexos.
  • Replicação de um primário para uma réplica que não é um clone completo: O banco de dados de destino não precisa ser uma cópia física completa da origem.

Como Funciona:

  1. Publicador: O banco de dados de origem (primário) onde as alterações de dados ocorrem. Ele precisa de wal_level = logical. As alterações são decodificadas do WAL em um fluxo lógico.
  2. Publicação: Um conjunto nomeado de tabelas no publicador cujas alterações serão replicadas.
  3. Assinante: O banco de dados de destino (réplica) que recebe as alterações.
  4. Assinatura: Uma conexão no assinante que se conecta ao publicador e aplica as alterações de uma publicação específica.

Configurando a Replicação Lógica

1. Configurar o Publicador (Servidor Primário)

  • Modificações no postgresql.conf:

    wal_level = logical
    max_replication_slots = 10 # Para slots de replicação lógica
    max_wal_senders = 10     # Deve ser pelo menos max_replication_slots
    
  • Criar uma Publicação:

    -- No banco de dados publicador:
    CREATE PUBLICATION my_publication FOR TABLE 
        table1, 
        table2 
        WITH (publish = 'insert,update,delete');
    
    -- Ou para todas as tabelas:
    -- CREATE PUBLICATION all_tables_pub FOR ALL TABLES;
    

    Recarregue a configuração no publicador.

2. Configurar o Assinante (Servidor Réplica)

  • Certifique-se de que as tabelas de destino existam: O banco de dados assinante deve ter as tabelas de destino com o mesmo esquema do publicador. Você pode criá-las manualmente ou usar pg_dump para extrair o esquema.

  • Criar uma Assinatura:

    -- No banco de dados assinante:
    CREATE SUBSCRIPTION my_subscription
        CONNECTION 'host=publisher_host_ip port=5432 user=replication_user password=your_password dbname=publisher_db'
        PUBLICATION my_publication;
    

    O replication_user precisa de permissões apropriadas no publicador.

    O PostgreSQL criará automaticamente um slot de replicação no publicador e começará a aplicar as alterações. Você pode monitorar o status da assinatura usando pg_stat_subscription no assinante.

Dica: A replicação lógica usa a infraestrutura de decodificação lógica embutida do PostgreSQL. Ela não requer uma extensão separada para publicações e assinaturas básicas.

Escolhendo o Método de Replicação Correto

  • Replicação Streaming: Ideal para alta disponibilidade e recuperação de desastres, onde você precisa de uma cópia exata, byte por byte, do primário. É mais simples de configurar para replicação completa do banco de dados e fornece a melhor escalabilidade de leitura para réplicas somente leitura.
  • Replicação Lógica: Mais adequada para distribuição seletiva de dados, migrações, atualizações entre versões ou quando você precisa replicar apenas um subconjunto de dados. Ela permite cenários mais complexos, como replicar para esquemas diferentes ou realizar transformações de dados.

Conclusão

Use replicação streaming quando precisar de um standby completo para failover, recuperação de desastres ou tráfego somente leitura. Use replicação lógica quando precisar de tabelas selecionadas, migração entre versões ou movimento controlado de dados entre diferentes bancos de dados.

Antes de confiar em qualquer configuração, execute um teste de failover, verifique o tratamento de conexão do aplicativo, monitore o atraso da replicação e verifique se os backups ainda são restaurados corretamente. A replicação mantém outro servidor atualizado; ela não substitui os testes operacionais.