Switchover e failover con la replica pglogical

Questa pagina fornisce informazioni su come eseguire lo switchover e il failover con la replicapglogical.

Prima di iniziare

Dopo aver configurato la replica pglogical e aver verificato la presenza di una soluzione di alta disponibilità (HA) e di ripristino di emergenza (RE) valida, nonché la consapevolezza che la replica logica non fornisce true e la replica completa di tutti gli oggetti del database, devi testare questa configurazione prima di iniziare a utilizzarla.

Per ulteriori informazioni sull'estensione pglogical, consulta Informazioni su pglogical.

Per informazioni sulla replica dei dati utilizzando pglogical, consulta Replicare i dati tra Google Cloud AlloyDB e AlloyDB Omni e Replicare i dati tra AlloyDB Omni e altri database.

Passaggio con la replica pglogical

Il passaggio è un processo controllato utilizzato per cambiare i ruoli tra i database del fornitore e degli abbonati. Quando esegui uno switchover, i ruoli dei due database, provider e subscriber, vengono invertiti. Il fornitore diventa l'abbonato e l'abbonato diventa il fornitore.

Questa funzionalità di passaggio è importante per gli upgrade del sistema operativo, gli upgrade di PostgreSQL o i test di failover.

Per farlo nelle configurazioni di replica unidirezionale, devi configurare un nuovo rapporto fornitore/abbonato e rimuovere il vecchio rapporto fornitore/abbonato.

Crea la nuova configurazione del fornitore/dell'abbonato

  1. Interrompi la scrittura dell'applicazione nel sistema del provider per evitare ulteriori modifiche al database e controlla il ritardo di replica per assicurarti che tutte le transazioni vengano riprodotte sul nodo sottoscrittore:

    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 tutti i campi di ritardo mostrano zero, la replica è aggiornata e il database è pronto per il passaggio.

    L'output è simile al seguente:

    -[ 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. Converti il database degli abbonati in un database del fornitore:

    1. Interrompi l'abbonamento esistente dell'abbonato.
    2. Aggiungi il set di replica, se necessario.
    3. Aggiungi le tabelle necessarie al set di replica.
    4. Crea un nuovo abbonamento nel nuovo database degli abbonati.
    5. Reindirizza le applicazioni al nuovo fornitore.
  3. Interrompi l'abbonamento nel database esistente degli abbonati, che diventa il nuovo fornitore:

    SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
    
  4. (Facoltativo) Crea un set di replica corrispondente alla definizione del database del fornitore originale. Questo passaggio non è necessario se utilizzi i set di replica predefinite:

    SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);
    
  5. Aggiungi tabelle al set di replica:

    SELECT pglogical.replication_set_add_table(REPLICATION_SET_NAME, TABLE_NAME);
    

    Sostituisci quanto segue:

    • REPLICATION_SET_NAME: il nome del set di replica.
    • TABLE_NAME: il nome della tabella di un proprietario dello schema. Ad esempio, ARRAY['public'].`
  6. Nel nuovo database degli abbonati, che in precedenza era il database del fornitore, crea il nuovo abbonamento con l'opzione synchronize_data impostata su false per impedire il caricamento iniziale della tabella:

    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. Controlla se l'abbonamento funziona sul nodo del provider:

    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 la replica funziona, modifica le stringhe di connessione dell'applicazione in modo da utilizzare il nuovo database del provider e riavvia i livelli dell'applicazione.

Se modifichi i dati sul vecchio nodo del provider dopo l'interruzione dell'abbonamento, queste modifiche non vengono replicate e si verifica una perdita di dati. Se sono presenti modifiche ai dati non replicati nel database del fornitore originale o se il fornitore originale, ovvero il nuovo abbonato, non è in uno stato coerente con il database del nuovo fornitore, ovvero il vecchio abbonato, devi creare completamente il database del nuovo abbonato.

Rimuovi il vecchio provider e l'abbonamento

Se vuoi la replica unidirezionale, devi rimuovere la vecchia configurazione del fornitore/abbonato.

  1. Rimuovi l'abbonamento precedente sul nuovo provider:

    SELECT pglogical.drop_subscription('<subscription name>')
    
  2. Rimuovi il set di replica sul nuovo sottoscrittore o rimuovi tutte le tabelle dal set di replica:

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

Replica bidirezionale

Per eseguire il passaggio senza tempi di inattività o per assicurarti che non vengano persi dati a causa di modifiche impreviste, devi utilizzare la replica bidirezionale. Quando implementi la replica bidirezionale, valuta la risoluzione dei conflitti, a meno che non siano stati implementati controlli rigorosi per impedire l'accesso in scrittura a entrambi i nodi contemporaneamente.

Puoi configurare la risoluzione dei conflitti utilizzando le seguenti impostazionipglogical.conflict_resolution:

  • error: l'abbonato si interrompe quando viene rilevato un conflitto.
  • apply_remote: applica sempre le modifiche in arrivo indipendentemente dai dati nel database degli abbonati. Questa è l'impostazione predefinita.
  • keep_local: ignora sempre i dati in arrivo in conflitto e elimina la modifica in conflitto.
  • last_update_wins: la versione dei dati con il timestamp del commit più recente è quella che viene committata
  • first_update_wins: la versione dei dati con il timestamp più antico è quella che viene committata

Per configurare la replica bidirezionale, configura il provider e l'abbonato in modo che la replica avvenga in entrambe le direzioni. Anche l'abbonato originale diventa un fornitore con lo stesso insieme di replica del fornitore originale. Consulta Creare una tabella e aggiungerla al set di replica predefinito nel database del provider AlloyDB di Google Cloud per creare un set di replica che duplichi il set di replica originale nel database del provider iniziale.

Sul fornitore originale, devi aggiungere un nuovo abbonato. Consulta Creare un nodo e un abbonamento nel database degli abbonati AlloyDB Omni per creare un nuovo abbonato assicurandoti che il parametro synchronize_data per il comando pglogical.create_subscription sia impostato su false. In questo modo viene evitata la copia iniziale della tabella dei dati.

Failover con la replica pglogical

Il failover si verifica quando il database del fornitore non è disponibile per qualsiasi motivo e devi impostare l'applicazione in modo che utilizzi il database degli abbonati.

Per evitare che dati duplicati vengano applicati accidentalmente al database degli abbonati sottoposto a failover, devi disattivare l'abbonamento. In questo modo, le modifiche di un provider ripristinato non vengono applicate per errore quando il provider diventa di nuovo disponibile.

  1. Interrompi l'abbonato test_sub_1:

    SELECT pglogical.alter_subscription_disable(`test_sub_1`);
    
  2. Verifica che lo stato sia impostato su disabled:

    SELECT pglogical.show_subscription_status('test_sub_1');
    

    L'output è simile al seguente:

    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. Controlla la parola chiave disattivata nell'output dello stato.

  4. Crea una nuova configurazione di provider/abbonati per mantenere l'alta disponibilità e la capacità di ripristino di emergenza.

  5. Crea un nuovo set di replica contenente tutte le tabelle replicate inizialmente in modo da creare un nuovo abbonato quando il vecchio database del provider viene recuperato e convertito in un nuovo abbonato o viene creato un nuovo abbonato.

  6. Configura l'abbonato.

  7. Configura questo database come nuovo abbonato se riesci a recuperare il database del vecchio fornitore al momento dell'errore. Segui gli stessi passaggi per creare un abbonamento e imposta il parametro synchronize_data per il comando pglogical.create_subscription su false per evitare la copia iniziale della tabella.

  8. Rimuovi la vecchia configurazione del provider sul nodo recuperato per evitare un accumulo di file WAL.

  9. Se utilizzi il vecchio database del provider, elimina l'intero insieme di replica o rimuovi una per volta tutte le tabelle dall'insieme di replica:

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    
  10. Imposta l'applicazione in modo che scriva nel nuovo nodo.

Passaggi successivi