Alternância e failover com a replicação pglogical

Esta página fornece informações sobre como fazer a conversão e o failover com a replicação pglogical.

Antes de começar

Depois que a replicação pglogical for configurada e houver uma solução viável de alta disponibilidade (HA) e recuperação de desastres (DR), e reconhecendo que a replicação lógica não fornece true e replicação abrangente de todos os objetos do banco de dados, você precisa testar essa configuração antes de começar a usá-la.

Para mais informações sobre a extensão pglogical, consulte Sobre o pglogical.

Para saber mais sobre a replicação de dados usando pglogical, consulte Replicar dados entre Google Cloud AlloyDB e AlloyDB Omni e Replicar dados entre o AlloyDB Omni e outros bancos de dados.

Alternância com a replicação pglogical

A alternância é um processo controlado usado para alternar os papéis entre os bancos de dados do provedor e do assinante. Quando você realiza uma alternância, as funções dos dois bancos de dados, provedor e assinante, são invertidas. O provedor se torna o assinante, e o assinante se torna o provedor.

Esse recurso de comutação é importante para upgrades do sistema operacional, do PostgreSQL ou para testes de failover.

Para fazer isso em configurações de replicação unidirecional, você precisa configurar uma nova relação provedor/assinante e remover a antiga.

Criar a nova configuração de provedor/assinante

  1. Impeça que o aplicativo seja gravado no sistema do provedor para evitar outras mudanças no banco de dados e verifique o atraso da replicação para garantir que todas as transações sejam reproduzidas no nó do assinante:

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    

    Quando todos os campos de atraso mostram zero, a replicação está atualizada e o banco de dados está pronto para uma alternância.

    O resultado será assim:

    -[ RECORD 1 ]----+------------------------------
    application_name | test_sub_1
    state            | streaming
    sync_state       | async
    client_addr      | 10.45.0.80
    client_hostname  | 
    sent_lag         | 0
    receiving_lag    | 0
    replay_lag       | 0
    total_lag        | 0
    reply_delay      | 00:00:26.203433
    
  2. Converta o banco de dados de assinantes em um banco de dados de provedores:

    1. Interrompa a assinatura do assinante.
    2. Adicione o conjunto de replicação, se necessário.
    3. Adicione as tabelas necessárias ao conjunto de replicação.
    4. Crie uma nova assinatura no novo banco de dados de assinantes.
    5. Redirecione os aplicativos para o novo provedor.
  3. Interrompa a assinatura no banco de dados de assinantes atual, que se torna o novo provedor:

    SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
    
  4. (Opcional) Crie um conjunto de replicação que corresponda à definição do banco de dados do provedor original. Isso não é necessário se você estiver usando os conjuntos de replicação padrão:

    SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);
    
  5. Adicione tabelas a esse conjunto de replicação:

    SELECT pglogical.replication_set_add_table(REPLICATION_SET_NAME, TABLE_NAME);
    

    Substitua:

    • REPLICATION_SET_NAME: o nome do conjunto de replicação.
    • TABLE_NAME: o nome da tabela de um proprietário de esquema. Por exemplo, ARRAY['public'].
  6. No novo banco de dados de assinantes, que antes era o banco de dados do provedor, crie a nova assinatura com a opção synchronize_data definida como false para impedir o carregamento inicial da tabela:

    SELECT pglogical.create_subscription (
               subscription_name := '<subscription name>',
               replication_sets := array['default'],
               synchronize_data := false,
               provider_dsn := 'host=<hostname or IP> port=5432 
               dbname=<db name> user=pglogical_replication password=<password>');
    
  7. Verifique se a assinatura está funcionando no nó do provedor:

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    
  8. Se a replicação estiver funcionando, mude as strings de conexão do aplicativo para usar o novo banco de dados do provedor e reinicie as camadas do aplicativo.

Se você mudar os dados no nó do provedor antigo depois que o assinante for interrompido, essas mudanças não serão replicadas e resultarão na perda de dados. Se houver mudanças de dados não replicadas no banco de dados do provedor original ou se o provedor original, que é o novo assinante, não estiver em um estado consistente com o novo banco de dados do provedor, que é o antigo assinante, será necessário criar o novo banco de dados do assinante completamente.

Remover o provedor e a assinatura antigos

Se você quiser a replicação unidirecional, remova a configuração antiga de provedor/assinante.

  1. Remova a assinatura antiga no novo provedor:

    SELECT pglogical.drop_subscription('<subscription name>')
    
  2. Remova o conjunto de replicação no novo assinante ou remova todas as tabelas do conjunto de replicação:

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    

Replicação bidirecional

Para fazer a troca sem incorrer em inatividade ou garantir que nenhum dado seja perdido devido a mudanças não planejadas, use a replicação bidirecional. Ao implementar a replicação bidirecional, considere a resolução de conflitos, a menos que controles rígidos estejam em vigor para impedir o acesso de gravação aos dois nós ao mesmo tempo.

É possível definir a resolução de conflitos usando as seguintes configurações pglogical.conflict_resolution:

  • error: o assinante é interrompido quando um conflito é detectado.
  • apply_remote: sempre aplique as mudanças recebidas, independentemente dos dados no banco de dados de assinantes. Esta é a configuração padrão.
  • keep_local: sempre ignore os dados de entrada em conflito e descarte a mudança em conflito.
  • last_update_wins: a versão dos dados com o carimbo de data/hora de confirmação mais recente são os dados confirmados.
  • first_update_wins: a versão dos dados com o carimbo de data/hora mais antigo é a que é confirmada.

Para configurar a replicação bidirecional, configure o provedor e o assinante para que a replicação aconteça nos dois sentidos. O assinante original também se torna um provedor com o mesmo conjunto de replicação do provedor original. Consulte Criar uma tabela e adicioná-la ao conjunto de replicação padrão no Google Cloud banco de dados do provedor do AlloyDB para criar um conjunto de replicação que duplique o conjunto de replicação original no banco de dados do provedor inicial.

No provedor original, adicione um novo assinante. Consulte Criar um nó e uma assinatura no banco de dados de assinantes do AlloyDB Omni para criar um novo assinante e garantir que o parâmetro synchronize_data do comando pglogical.create_subscription seja definido como false. Isso evita a cópia inicial da tabela dos dados.

Failover com replicação pglogical

O failover ocorre quando o banco de dados do provedor fica indisponível por qualquer motivo e é necessário mudar o aplicativo para usar o banco de dados do assinante.

Para evitar que dados duplicados sejam aplicados acidentalmente ao banco de dados de failover do assinante, desative a assinatura. Isso garante que as mudanças de um provedor restaurado não sejam aplicadas por engano quando o provedor ficar disponível novamente.

  1. Pare o inscrito, test_sub_1:

    SELECT pglogical.alter_subscription_disable(`test_sub_1`);
    
  2. Verifique se o status está definido como disabled:

    SELECT pglogical.show_subscription_status('test_sub_1');
    

    O resultado será assim:

    show_subscription_status                                                                           
    ----------------------------------------------------------------------------
    (test_sub1,disabled,subscriber,"host=10.45.0.108 port=5432 dbname=my_test_db user=pglogical_replication",subscriber,{failover_set},{all})
    
  3. Verifique a palavra-chave desativada na saída de status.

  4. Crie uma nova configuração de provedor/assinante para manter a alta disponibilidade e a capacidade de recuperação de desastres.

  5. Crie um novo conjunto de replicação que contenha todas as tabelas que foram replicadas originalmente para que um novo assinante seja criado quando o banco de dados do provedor antigo for recuperado e convertido em um novo ou quando um novo assinante for criado.

  6. Configurar o assinante.

  7. Configure esse banco de dados como o novo assinante se você conseguir recuperar o banco de dados do provedor antigo no momento da falha. Use as mesmas etapas para criar uma assinatura e defina o parâmetro synchronize_data do comando pglogical.create_subscription como false para evitar a cópia inicial da tabela.

  8. Remova a configuração antiga do provedor no nó recuperado para evitar o acúmulo de arquivos WAL.

  9. Se você estiver usando o banco de dados antigo do provedor, exclua o conjunto de replicação completo ou remova todas as tabelas do conjunto de replicação uma por uma:

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    
  10. Mude o aplicativo para gravar no novo nó.

A seguir