Switchover e failover con la replica pglogical

Seleziona una versione della documentazione:

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

Prima di iniziare

Dopo aver configurato la replica pglogical e aver implementato una soluzione di alta disponibilità (HA) e ripristino di emergenza (RE) praticabile, e tenendo presente che la replica logica non fornisce una replica true e 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 AlloyDB per PostgreSQL e AlloyDB Omni e Replicare i dati tra AlloyDB Omni e altri database.

Switchover con la replica pglogical

Lo switchover è un processo controllato utilizzato per scambiare i ruoli tra i database del fornitore e dell'abbonato. Quando esegui uno switchover, i ruoli dei due database, fornitore e abbonato, vengono invertiti. Il fornitore diventa l'abbonato e l'abbonato diventa il fornitore.

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

Per ottenere questo risultato nelle configurazioni di replica unidirezionale, devi configurare una nuova relazione fornitore/abbonato e rimuovere la vecchia relazione fornitore/abbonato.

Crea la nuova configurazione fornitore/abbonato

  1. Impedisci all'applicazione di scrivere nel sistema del fornitore per evitare ulteriori modifiche al database e controlla il ritardo di replica per assicurarti che tutte le transazioni vengano riprodotte sul nodo dell'abbonato:

    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 uno switchover.

    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 dell'abbonato in un database del fornitore:

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

    SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
    
  4. (Facoltativo) Crea un set di replica che corrisponda alla definizione del database del fornitore originale. Questa operazione non è necessaria se utilizzi i set di replica predefiniti:

    SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);
    
  5. Aggiungi le tabelle a questo 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 dell'abbonato, 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 fornitore:

    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 che utilizzino il nuovo database del fornitore e riavvia i livelli dell'applicazione.

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

Rimuovi il vecchio fornitore e l'abbonamento

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

  1. Rimuovi il vecchio abbonamento sul nuovo fornitore:

    SELECT pglogical.drop_subscription('<subscription name>')
    
  2. Rimuovi il set di replica sul nuovo abbonato 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 lo switchover senza causare tempi di inattività o per assicurarti che non vengano persi dati a causa di modifiche non pianificate, devi utilizzare la replica bidirezionale. Quando implementi la replica bidirezionale, prendi in considerazione la risoluzione dei conflitti, a meno che non siano in vigore controlli rigorosi per impedire l'accesso in scrittura a entrambi i nodi contemporaneamente.

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

  • error: l'abbonato si interrompe quando viene rilevato un conflitto.
  • apply_remote: applica sempre le modifiche in entrata indipendentemente dai dati nel database dell'abbonato. Questa è l'impostazione predefinita.
  • keep_local: ignora sempre i dati in entrata in conflitto e scarta la modifica in conflitto.
  • last_update_wins: la versione dei dati con il timestamp di commit più recente è quella di cui viene eseguito il commit
  • first_update_wins: la versione dei dati con il timestamp più vecchio è quella di cui viene eseguito il commit

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

Nel fornitore originale, devi aggiungere un nuovo abbonato. Consulta Creare un nodo e un abbonamento nel database dell'abbonato 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 si evita 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 passare all'applicazione per utilizzare il database dell'abbonato.

Per evitare che i dati duplicati vengano applicati accidentalmente al database dell'abbonato di cui è stato eseguito il failover, devi disattivare l'abbonamento. In questo modo, le modifiche di un fornitore ripristinato non vengono applicate per errore quando il fornitore torna 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 disabled nell'output dello stato.

  4. Crea una nuova configurazione fornitore/abbonato per mantenere la capacità di alta affidabilità e ripristino di emergenza.

  5. Crea un nuovo set di replica contenente tutte le tabelle replicate originariamente in modo che venga creato un nuovo abbonato quando il vecchio database del fornitore 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 puoi recuperare il vecchio database del 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 fornitore sul nodo recuperato per evitare l'accumulo di file WAL.

  9. Se utilizzi il vecchio database del fornitore, elimina l'intero set di replica o rimuovi tutte le tabelle dal set di replica una alla volta:

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    
  10. Passa all'applicazione per scrivere nel nuovo nodo.

Passaggi successivi