PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Switchover/Switchback in Slony-I durante l'aggiornamento delle versioni principali di PostgreSQL 8.4.x/9.3.x

Ogni nuova versione di PostgreSQL include una serie di interessanti funzionalità. Per beneficiare delle nuove funzionalità, è necessario aggiornare il server di database. La scelta di percorsi di aggiornamento tradizionali come pg_dump/pg_restore o pg_upgrade richiede un notevole tempo di inattività dell'applicazione. Oggi, se stai cercando un percorso di aggiornamento minimo per i tempi di inattività tra le principali versioni di PostgreSQL con un piano di rollback perfetto, sarà realizzato dalla replica Slony-I asincrona. Poiché Slony-I (saperne di più qui) ha la capacità di replicare facilmente tra diverse versioni di PostgreSQL, sistemi operativi e architetture bit, quindi gli aggiornamenti sono fattibili senza richiedere tempi di inattività sostanziali. Inoltre, ha una funzionalità coerente di switchover e switchback nel suo design.

IMO, mentre si eseguono gli aggiornamenti delle versioni principali, dovrebbe esserci un piano di ripiego adeguato perché nel caso in cui l'applicazione si riveli difettosa o non funzioni bene con la versione aggiornata, dovremmo essere in grado di ripristinare immediatamente la versione precedente. Slony-I fornisce tale funzionalità in termini di ritorno. Questo post mostra l'aggiornamento minimo dei tempi di inattività, inclusi i passaggi di passaggio/ritorno.

Prima di passare alla demo, un passaggio importante da notare, prima della versione PG 9.0.x le colonne del tipo di dati bytea utilizzano per memorizzare i dati in formato ESCAPE e la versione successiva è in formato HEX. Durante l'esecuzione del passaggio (dalla versione più recente alla versione precedente), questo tipo di differenze di formato bytea non sono supportate da Slony-I, quindi il formato ESCAPE deve essere mantenuto per tutta la durata dell'aggiornamento, altrimenti potresti riscontrare un errore:

ERROR  remoteWorkerThread_1_1: error at end of COPY IN: ERROR:  invalid input syntax for type bytea
CONTEXT: COPY sl_log_1, line 1: "1 991380 1 100001 public foo I 0 {id,500003,name,"A ",b,"\\x41"}"
ERROR remoteWorkerThread_1: SYNC aborted

Per correggere, non sono richieste modifiche su PG 8.4.x ma su PG 9.3.5 il parametro byte_output deve essere impostato da HEX a ESCAPE come mostrato. Possiamo impostarlo a livello di cluster ($PGDATA/postgresql.conf) o a livello di utente (ALTER TABLE...SET), ho preferito andare con le modifiche a livello di utente.

slavedb=# alter user postgres set bytea_output to escape;
ALTER ROLE

Procediamo con i passaggi di aggiornamento. Di seguito sono riportati i dettagli del mio server di due versioni utilizzati in questa demo, modificalo di conseguenza in base alla configurazione del server se stai provando:

Origin Node (Master/Primary are called as Origin)                     Subscriber Node (Slave/Secondary are called as Subscriber)
------------------------------------------------- ----------------------------------------------------------
Host IP : 192.168.22.130 192.168.22.131
OS Version : RHEL 6.5 64 bit RHEL 6.5 64 bit
PG Version : 8.4.22 (5432 Port) 9.3.5 (5432 Port)
Slony Vers. : 2.2.2 2.2.2
PG Binaries : /usr/local/pg84/bin /opt/PostgreSQL/9.3/
Database : masterdb slavedb
PK Table : foo(id int primary key, name char(20), image bytea) ...restore PK tables structure from Origin...

Per una semplice comprensione e una facile implementazione, ho diviso la demo in tre sezioni

1. Compilazione di binari Slony-I rispetto alle versioni di PostgreSQL
2. Creazione di script di replica ed esecuzione
3. Test di commutazione/commutazione.

1. Compilazione per binari Slony-I rispetto alla versione PostgreSQL
Scarica i sorgenti Slony-I da qui ed esegui l'installazione dei sorgenti sui binari PostgreSQL sui nodi Origin e Subscriber.

On Origin Node:
# tar -xvf slony1-2.2.2.tar.bz2
# cd slony1-2.2.2
./configure --with-pgbindir=/usr/local/pg84/bin
--with-pglibdir=/usr/local/pg84/lib
--with-pgincludedir=/usr/local/pg84/include
--with-pgpkglibdir=/usr/local/pg84/lib/postgresql
--with-pgincludeserverdir=/usr/local/pg84/include/postgresql/
make
make install

On Subscriber Node: (assuming PG 9.3.5 installed)
# tar -xvf slony1-2.2.2.tar.bz2
# cd slony1-2.2.2
./configure --with-pgconfigdir=/opt/PostgreSQL/9.3/bin
--with-pgbindir=/opt/PostgreSQL/9.3/bin
--with-pglibdir=/opt/PostgreSQL/9.3/lib
--with-pgincludedir=/opt/PostgreSQL/9.3/include
--with-pgpkglibdir=/opt/PostgreSQL/9.3/lib/postgresql
--with-pgincludeserverdir=/opt/PostgreSQL/9.3/include/postgresql/server/
--with-pgsharedir=/opt/PostgreSQL/9.3/share
make
make install

2. Creazione di script di replica ed esecuzione
Per configurare la replica, abbiamo bisogno di creare alcuni script che si occupino della replica, incluso il passaggio/ritorno.

1. initialize.slonik – Questo script contiene le informazioni sulla connessione dei nodi Origin/Subscriber.
2. create_set.slonik – Questo script contiene tutte le tabelle PK di origine che si replicano nel nodo sottoscrittore.
3. subscribe_set.slonik – Questo script avvia la replica dei dati dei set su Subscriber Node.
4. switchover.slonik – Questo script aiuta a spostare il controllo da Origin a Subscriber.
5. switchback.slonik – Questo script aiuta a eseguire il fallback del controllo da Abbonato a Origin.

Infine, altri due script di avvio “start_OriginNode.sh” e "start_SubscriberNode.sh" che avvia i processi slon in base ai binari compilati su Origin/Subscriber Nodes.

Scarica tutti gli script da qui.

Ecco i dati di esempio su Origin Node(8.4.22) in Foo Table con una colonna di tipo di dati bytea, che replicheremo su Subscriber Node(9.3.5) con l'aiuto degli script creati.

masterdb=# select * from foo;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
(3 rows)

Consente di chiamare gli script uno per uno per impostare la replica. RICORDA TUTTI GLI SCRIPT DI SLONIK DEVONO ESSERE ESEGUITI SOLO SU ORIGIN NODE, ECCETTO “start_OriginNode.sh” E “start_SubscriberNode.sh” CHE DEVONO ESSERE ESEGUITI INDIVIDUALMENTE.

-bash-4.1$ slonik initalize.slonik
-bash-4.1$ slonik create_set.slonik
create_set.slonik:13: Set 1 ...created
create_set.slonik:16: PKey table *** public.foo *** added.
-bash-4.1$ sh start_OriginNode.sh
-bash-4.1$ sh start_SubscriberNode.sh //ON SUBSCRIBER NODE
-bash-4.1$ slonik subscribe_set.slonik

Dopo aver eseguito correttamente lo script sopra, puoi notare che i dati su Origin(masterdb) sono stati replicati su Subscriber(slavedb). Inoltre, non consente alcuna operazione DML sul nodo Abbonato:

slavedb=# select * from foo;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
(3 rows)

slavedb=# insert into foo values (4,'PG-Experts','Image2');
ERROR: Slony-I: Table foo is replicated and cannot be modified on a subscriber node - role=0

Fantastico... Abbiamo spostato i dati nella versione più recente di PostgreSQL 9.3.5. A questo punto, se ritieni che tutti i dati siano stati replicati su Subscriber Node, puoi eseguire il passaggio.

3. Test di commutazione/ritorno.

Passiamo all'ultima versione con lo script e proviamo a inserire i dati sui nodi Subscriber/Origin.

-bash-4.1$ slonik switchover.slonik
switchover.slonik:8: Set 1 has been moved from Node 1 to Node 2

slavedb=# insert into foo values (4,'PG-Experts','Image2');
INSERT 0 1

masterdb=# select * from foo ;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
4 | PG-Experts | Image2
(4 rows)

masterdb=# insert into foo values (5,'PG-Experts','Image3');
ERROR: Slony-I: Table foo is replicated and cannot be modified on a subscriber node - role=0

Perfetto... Questo è ciò che stiamo cercando, ora slavedb(Subscriber Node) esegue la versione PG 9.3.5 che accetta dati e masterdb(Origin Node) riceve i dati slavedb. Inoltre rifiuta i DML eseguiti su masterdb.

Slony-I Logs mostra i movimenti dell'ID del nodo di origine/sottoscrittore al momento del passaggio:

2014-12-12 04:55:06 PST CONFIG moveSet: set_id=1 old_origin=1 new_origin=2
2014-12-12 04:55:06 PST CONFIG storeListen: li_origin=1 li_receiver=2 li_provider=1
2014-12-12 04:55:06 PST CONFIG remoteWorkerThread_1: update provider configuration
2014-12-12 04:55:06 PST CONFIG remoteWorkerThread_1: helper thread for provider 1 terminated
2014-12-12 04:55:06 PST CONFIG remoteWorkerThread_1: disconnecting from data provider 1
...
...
2014-12-12 04:55:11 PST INFO start processing ACCEPT_SET
2014-12-12 04:55:11 PST INFO ACCEPT: set=1
2014-12-12 04:55:11 PST INFO ACCEPT: old origin=1
2014-12-12 04:55:11 PST INFO ACCEPT: new origin=2
2014-12-12 04:55:11 PST INFO ACCEPT: move set seq=5000006393
2014-12-12 04:55:11 PST INFO got parms ACCEPT_SET

Se riscontri problemi in questa fase, puoi tornare alla versione precedente. Dopo il ritorno, puoi continuare con la versione precedente fino a quando l'applicazione o altri problemi non sono stati risolti. Questo è il piano di rollback perfetto senza perdere molto tempo in caso di problemi dopo il passaggio.

-bash-4.1$ slonik switchback.slonik
switchback.slonik:8: Set 1 has been moved from Node 2 to Node 1

slavedb=# insert into foo values (5,'PG-Experts','Image3');
ERROR: Slony-I: Table foo is replicated and cannot be modified on a subscriber node - role=0

masterdb=# insert into foo values (5,'PG-Experts','Image3');
INSERT 0 1

slavedb=# select * from foo ;
id | name | image
----+----------------------+-------
1 | Raghav | test1
2 | Rao | test2
3 | Rags | test3
4 | PG-Experts | Image2
5 | PG-Experts | Image3
(5 rows)

Molto bello…!!! Non è questo il rollback esatto con tempi di fermo minimi? Sì, è un passaggio perfetto tra i nodi senza perdere una transazione.

Registri che mostrano il passaggio da Abbonato a Origin Node:

2014-12-12 04:58:45 PST CONFIG moveSet: set_id=1 old_origin=2 new_origin=1
2014-12-12 04:58:45 PST CONFIG storeListen: li_origin=2 li_receiver=1 li_provider=2
2014-12-12 04:58:45 PST CONFIG remoteWorkerThread_2: update provider configuration
2014-12-12 04:58:45 PST CONFIG remoteWorkerThread_2: helper thread for provider 2 terminated
2014-12-12 04:58:45 PST CONFIG remoteWorkerThread_2: disconnecting from data provider 2
2014-12-12 04:58:46 PST CONFIG storeListen: li_origin=2 li_receiver=1 li_provider=2
...
...
2014-12-12 04:58:47 PST INFO start processing ACCEPT_SET
2014-12-12 04:58:47 PST INFO ACCEPT: set=1
2014-12-12 04:58:47 PST INFO ACCEPT: old origin=2
2014-12-12 04:58:47 PST INFO ACCEPT: new origin=1
2014-12-12 04:58:47 PST INFO ACCEPT: move set seq=5000006403
2014-12-12 04:58:47 PST INFO got parms ACCEPT_SET
2014-12-12 04:58:48 PST CONFIG moveSet: set_id=1 old_origin=2 new_origin=1

A questo punto potresti aver notato che nessuna delle transazioni viene persa durante l'operazione di passaggio tra le versioni di PostgreSQL. L'unico tempo di inattività potrebbe essere l'avvio/arresto dell'applicazione per la connessione ai nodi Origin e Subscriber, ma mentre i nodi Origin/Subscriber non vengono mai rimossi, sono solo attivi e funzionanti.

Ricorda, il metodo mostrato qui non è utile solo per gli aggiornamenti, ma è lo stesso metodo in Slony-I per spostarsi tra i nodi.

Grazie per la vostra pazienza :). Spero che questo post ti aiuti ad aggiornare PostgreSQL con tempi di inattività minimi utilizzando Slony-I, incluso un piano di rollback adeguato.