Continuità operativa per i database
La continuità operativa per i database significa che i database devono essere continuamente operativi anche durante i disastri. È fondamentale garantire che i database di produzione siano sempre disponibili per le applicazioni anche durante i disastri, altrimenti potrebbe rivelarsi un affare costoso. I DBA, gli architetti dovrebbero garantire che gli ambienti di database possano sostenere disastri e siano conformi agli SLA per il ripristino di emergenza. Per garantire che i disastri non influiscano sulla disponibilità del database, i database devono essere configurati per la continuità aziendale.
La configurazione dei database per la continuità aziendale richiede molte attività di architettura, pianificazione, progettazione e test. Quando si tratta di progettare e implementare un'efficace strategia di ripristino di emergenza per i database, vengono presi in considerazione molti fattori come i data center e i loro territori geografici, inclusa la progettazione dell'infrastruttura. Ciò spiega il fatto che "Business Continuity =Evitare interruzioni durante i disastri ”.
Per garantire che i database di produzione sopravvivano a un'emergenza, è necessario configurare un sito di Disaster Recovery (DR). I siti di produzione e DR devono far parte di due Data Center geograficamente distanti. Ciò significa che è necessario configurare un database di standby nel sito di ripristino di emergenza per ogni database di produzione in modo che le modifiche ai dati che si verificano nel database di produzione vengano immediatamente sincronizzate con il database di standby tramite i registri delle transazioni. Ciò può essere ottenuto tramite la funzionalità "Streaming Replication" in PostgreSQL.
Cosa deve succedere se il disastro colpisce il database di produzione (o primario)?
Quando il database di produzione (primario) si arresta in modo anomalo o non risponde, il database standby deve essere promosso a primario e le applicazioni devono essere indirizzate al database standby appena promosso (nuovo primario) e tutto ciò deve avvenire automaticamente all'interno dello SLA di interruzione designato. Questo processo è definito failover.
Configurazione di PostgreSQL per l'alta disponibilità
Come detto in precedenza, per garantire che PostgreSQL sia conforme al ripristino di emergenza, deve essere prima configurato con Streaming Replication (database master + standby) e con funzionalità di promozione/failover standby automatico. Diamo un'occhiata a come configurare prima la replica in streaming e poi il processo di "failover".
Configurazione del database in standby (replica streaming)
La replica in streaming è la funzionalità integrata di PostgreSQL che garantisce che i dati vengano replicati dal database primario a quello di standby tramite record WAL e supporta i metodi di replica sia asincrona che sincrona. Questo modo di replica è abbastanza affidabile e adatto ad ambienti che richiedono una replica in tempo reale e ad alte prestazioni.
La configurazione dello streaming standby è piuttosto semplice. Il primo passaggio consiste nel garantire che le configurazioni del database primario siano le seguenti:
Configurazioni obbligatorie del database primario
Assicurati che i seguenti parametri siano configurati in postgresql.conf sul database primario. L'esecuzione delle seguenti modifiche richiederebbe il riavvio del database.
wal_level=logical
Il parametro wal_level garantisce che le informazioni richieste per la replica vengano scritte nei file WAL.
max_wal_senders=1 (or any number more than 0)
I record WAL vengono spediti dal processo wal sender dal database primario al database di standby. Pertanto, il parametro sopra deve essere configurato su minimo 1. È richiesto più di un valore di 1 quando sono richiesti più mittenti wal.
Abilita archiviazione WAL
Non vi è alcuna dipendenza dall'archiviazione WAL per la replica in streaming. Tuttavia, si consiglia vivamente di configurare l'archiviazione WAL perché, se lo standby è in ritardo e se i file WAL richiesti vengono rimossi dalla directory pg_xlog (o pg_wal), allora i file di archivio saranno necessari per sincronizzare lo standby con il file primario in caso contrario, lo standby deve essere ricostruito da zero.
archive_mode=on
archive_command=<archive location>
Il database primario deve essere configurato per accettare connessioni dallo standby.
La configurazione di seguito deve essere presente in pg_hba.conf
host replication postgres <standby-database-host-ip>/32 trust
Ora, esegui un backup del database primario e ripristina lo stesso sul sito di ripristino di emergenza. Una volta terminato il ripristino, costruisci il file recovery.conf nella directory dei dati con i seguenti contenuti:
standby_mode=’on’
primary_conninfo=’host=<master-database-host-ip>, port=<master-database-port>, user=<replication-user>’
restore_command=’cp /database/wal_restore/%f %p’
trigger_file=’/database/promote_trigfile’
recovery_target_timeline=’latest’
Ora avvia il database di standby. La replica in streaming deve essere abilitata. Il messaggio seguente nel file di registro postgresql del database di standby conferma che la replica in streaming funziona correttamente:
2018-01-13 00:22:44 AEDT [4432]: [1] user=,db=,app=,client= LOG: started streaming WAL from primary at 127/CD000000 on timeline 1
2018-01-13 00:22:44 AEDT [4268]: [5] user=,db=,app=,client= LOG: redo starts at 127/CD380170
Ciò conclude che è in atto una replica dello streaming completamente funzionale. Passaggio successivo per installare/configurare repmgr. Prima di ciò, cerchiamo di comprendere il processo di failover.
Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri cosa devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaperCos'è il failover?
Il failover si verifica quando il database primario diventa completamente non disponibile a causa di un'emergenza. Durante il processo di failover, il database Standby verrà promosso a diventare un nuovo database primario in modo che le applicazioni possano continuare le operazioni aziendali.
Failover automatico
L'intero processo di failover deve avvenire automaticamente per garantire un'effettiva continuità aziendale e ciò può essere ottenuto solo con alcuni strumenti middleware. L'idea è di evitare un intervento manuale di DBA, sviluppatori.
Uno di questi strumenti che aiuta a eseguire il failover automatico è "repmgr".
Diamo un'occhiata a repmgr e alle sue capacità.
Repmgr
Repmgr è uno strumento opensource sviluppato da 2nd Quadrant. Questo strumento consente di eseguire varie attività amministrative del database come la creazione e il monitoraggio della replica PostgreSQL, inclusa l'esecuzione di attività di failover automatizzate in caso di emergenza, e aiuta anche a eseguire operazioni di passaggio.
Repmgr è uno strumento facile da installare e anche le configurazioni non sono complesse. Diamo prima un'occhiata all'installazione:
Installazione di repmgr
Scarica lo strumento da qui.
Decomprimi il tarball ed esegui l'installazione come mostrato di seguito:
Ho installato repmgr-4.2.0 su un host CentOS 7 e ho installato repmgr contro PostgreSQL-11.1.Prima dell'installazione, assicurarsi che la directory bin di PostgreSQL faccia parte di $PATH e che la directory lib di PostgreSQL faccia parte di $LD_LIBRARY_PATH. Per capire che repmgr è installato su PostgreSQL-11.1, visualizzo l'output "make install" di seguito:
[[email protected] repmgr-4.2.0]# ./configure --prefix=/opt/repmgr-4.2
[[email protected] repmgr-4.2.0]# make
[[email protected] repmgr-4.2.0]# make install
Building against PostgreSQL 11
/bin/mkdir -p '/opt/pgsql-11.1/lib'
/bin/mkdir -p '/opt/pgsql-11.1/share/extension'
/bin/mkdir -p '/opt/pgsql-11.1/share/extension'
/bin/mkdir -p '/opt/pgsql-11.1/bin'
/bin/install -c -m 755 repmgr.so '/opt/pgsql-11.1/lib/repmgr.so'
/bin/install -c -m 644 .//repmgr.control '/opt/pgsql-11.1/share/extension/'
/bin/install -c -m 644 .//repmgr--unpackaged--4.0.sql .//repmgr--4.0.sql .//repmgr--4.0--4.1.sql .//repmgr--4.1.sql .//repmgr--4.1--4.2.sql .//repmgr--4.2.sql '/opt/pgsql-11.1/share/extension/'
/bin/install -c -m 755 repmgr repmgrd '/opt/pgsql-11.1/bin/'
Configurazione di repmgr per il failover automatico
Prima di esaminare la configurazione di "repmgr", i database devono essere configurati con la replica in streaming che abbiamo visto in precedenza. Per cominciare, entrambi i database (primario e standby) devono essere configurati con il seguente parametro in postgresql.conf:
Primary
[[email protected] log]$ grep "shared_preload" /data/pgdata11/postgresql.conf
shared_preload_libraries = 'repmgr' # (change requires restart)
Standby
[[email protected] log]$ grep "shared_preload" /data/pgdata-standby11/postgresql.conf
shared_preload_libraries = 'repmgr' # (change requires restart)
Il parametro sopra serve per abilitare il demone “repmgrd” che, continuamente eseguito in background, monitora la replica in streaming. Senza questo parametro, non è possibile eseguire il failover automatico. La modifica di questo parametro richiede il riavvio del database.
Successivamente, crea il file di configurazione repmgr (ad esempio con il nome repmgr.conf) per entrambi i database. Il database primario deve avere un file di configurazione con i seguenti contenuti:
node_id=1
node_name=node1
conninfo='host=xxx.xxx.xx.xx user=postgres dbname=postgres connect_timeout=2'
data_directory='/data/pgdata11'
Posiziona il file nella directory dei dati, in questo caso è “/data/pgdata11”.
Il file di configurazione del database in standby deve avere i seguenti contenuti:
node_id=2
node_name=node2
conninfo='host=xxx.xxx.xx.xx user=postgres dbname=postgres port=6432 connect_timeout=2'
data_directory='/data/pgdata-standby11'
failover=automatic
promote_command='repmgr standby promote -f /data/pgdata-standby11/repmgr.conf'
follow_command='repmgr standby follow -f /data/pgdata-standby11/repmgr.conf --upstream-node-id=%n'
monitoring_history=yes
monitor_interval_secs=5
log_file='/data/pgdata-standby11/repmgr_logs/repmgr.log'
log_status_interval=5
log_level=DEBUG
promote_check_timeout=5
promote_check_interval=1
master_response_timeout=5
reconnect_attempts=5
reconnect_interval=10
Entrambi i database devono essere registrati con repmgr.
Registra database primario
[[email protected] pgdata-standby11]$ repmgr -f /data/pgdata11/repmgr.conf primary register
INFO: connecting to primary database...
NOTICE: attempting to install extension "repmgr"
NOTICE: "repmgr" extension successfully installed
NOTICE: primary node record (id: 1) registered
Registra il database di standby
[[email protected] pgdata-standby11]$ repmgr -f /data/pgdata-standby11/repmgr.conf standby register --upstream-node-id=1
INFO: connecting to local node "node2" (ID: 2)
INFO: connecting to primary database
INFO: standby registration complete
NOTICE: standby node "node2" (id: 2) successfully registered
Esegui il comando seguente per assicurarti che la registrazione di repmgr funzioni.
[[email protected] ~]$ repmgrd -f /data/pgdata-standby11/repmgr.conf --verbose --monitoring-history
[2019-02-16 16:31:26] [NOTICE] using provided configuration file "/data/pgdata-standby11/repmgr.conf"
[2019-02-16 16:31:26] [WARNING] master_response_timeout/5: unknown name/value pair provided; ignoring
[2019-02-16 16:31:26] [NOTICE] redirecting logging output to "/data/pgdata-standby11/repmgr_logs/repmgr.log"
Se puoi osservare, ho configurato log_level su DEBUG per generare una registrazione dettagliata nel file repmgr.conf dello standby. Controlla i log per lo stato della replica.
Verifica se la replica funziona come previsto utilizzando repmgr:
[[email protected] pgdata-standby11]$ repmgr -f /data/pgdata-standby11/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Connection string
----+-------+---------+-----------+----------+----------+-------------------------------------------------------------------------------
1 | node1 | primary | * running | | default | host=xxx.xxx.xx.xx user=postgres dbname=postgres connect_timeout=2
2 | node2 | standby | running | node1 | default | host=xxx.xxx.xx.xx user=postgres dbname=postgres port=6432 connect_timeout=2
Il messaggio precedente conferma che la replica sta funzionando correttamente.
Ora, se spengo il database primario, il demone repmgrd dovrebbe rilevare l'errore del database primario e dovrebbe promuovere il database standby. Vediamo se ciò accade -Il database primario è fermo:
[[email protected] ~]$ pg_ctl -D /data/pgdata-standby11 stop
waiting for server to shut down.... done
server stopped
Il database di standby deve essere promosso automaticamente. I log di repmgr mostrerebbero lo stesso:
fallback_application_name=repmgr is 2
[2019-02-14 17:09:23] [WARNING] unable to reconnect to node 1 after 5 attempts
[2019-02-14 17:09:23] [DEBUG] is_server_available(): ping status for host=xxx.xxx.xx.xx user=postgres dbname=postgres port=6432 connect_timeout=2 is 0
[2019-02-14 17:09:23] [DEBUG] do_election(): electoral term is 1
[2019-02-14 17:09:23] [DEBUG] get_active_sibling_node_records():
SELECT n.node_id, n.type, n.upstream_node_id, n.node_name, n.conninfo, n.repluser, n.slot_name, n.location, n.priority, n.active, n.config_file, '' AS upstream_node_name FROM repmgr.nodes n WHERE n.upstream_node_id = 1 AND n.node_id != 2 AND n.active IS TRUE ORDER BY n.node_id
[2019-02-14 17:09:23] [DEBUG] clear_node_info_list() - closing open connections
[2019-02-14 17:09:23] [DEBUG] clear_node_info_list() - unlinking
[2019-02-14 17:09:23] [DEBUG] do_election(): primary location is "default", standby location is "default"
[2019-02-14 17:09:23] [DEBUG] no other nodes - we win by default
[2019-02-14 17:09:23] [DEBUG] election result: WON
[2019-02-14 17:09:23] [NOTICE] this node is the only available candidate and will now promote itself
[2019-02-14 17:09:23] [DEBUG] get_node_record():
SELECT n.node_id, n.type, n.upstream_node_id, n.node_name, n.conninfo, n.repluser, n.slot_name, n.location, n.priority, n.active, n.config_file, '' AS upstream_node_name FROM repmgr.nodes n WHERE n.node_id = 1
[2019-02-14 17:09:23] [INFO] promote_command is:
"repmgr standby promote -f /data/pgdata-standby11/repmgr.conf"
WARNING: master_response_timeout/5: unknown name/value pair provided; ignoring
DEBUG: connecting to: "user=postgres connect_timeout=2 dbname=postgres host=xxx.xxx.xx.xx port=6432 fallback_application_name=repmgr"
DEBUG: connecting to: "user=postgres connect_timeout=2 dbname=postgres host=xxx.xxx.xx.xx fallback_application_name=repmgr"
DEBUG: connecting to: "user=postgres connect_timeout=2 dbname=postgres host=xxx.xxx.xx.xx port=6432 fallback_application_name=repmgr"
NOTICE: promoting standby to primary
DETAIL: promoting server "node2" (ID: 2) using "pg_ctl -w -D '/data/pgdata-standby11' promote"
DETAIL: waiting up to 5 seconds (parameter "promote_check_timeout") for promotion to complete
DEBUG: setting node 2 as primary and marking existing primary as failed
NOTICE: STANDBY PROMOTE successful
DETAIL: server "node2" (ID: 2) was successfully promoted to primary
Quanto sopra significa precisamente che repmgr non è stato in grado di connettersi al database primario e dopo 5 tentativi non riusciti, lo standby viene promosso al nuovo database primario. Di seguito è riportato ciò che mostra i registri del database di standby promossi (nuovi primari):
2019-02-14 17:09:21 AEDT [20789]: [1] user=,db=,app=,client= FATAL: could not connect to the primary server: could not connect to server: Connection refused
Is the server running on host "xxx.xxx.xx.xx" and accepting
TCP/IP connections on port 5432?
2019-02-14 17:09:23 AEDT [20506]: [7] user=,db=,app=,client= LOG: received promote request
2019-02-14 17:09:23 AEDT [20506]: [8] user=,db=,app=,client= LOG: redo done at 10F/5A335FF0
2019-02-14 17:09:23 AEDT [20506]: [9] user=,db=,app=,client= LOG: last completed transaction was at log time 2019-02-14 17:08:38.350695+11
2019-02-14 17:09:23 AEDT [20506]: [10] user=,db=,app=,client= LOG: selected new timeline ID: 2
2019-02-14 17:09:23 AEDT [20506]: [11] user=,db=,app=,client= LOG: archive recovery complete
2019-02-14 17:09:24 AEDT [20507]: [1] user=,db=,app=,client= LOG: checkpoint starting: force
2019-02-14 17:09:24 AEDT [20504]: [7] user=,db=,app=,client= LOG: database system is ready to accept connections
Ho menzionato solo i parametri importanti nel file di configurazione repmgr. Ci sono molti altri parametri che possono essere modificati per soddisfare vari requisiti. Gli altri parametri importanti sono i parametri replication_lag_* come mostrato di seguito:
#replication_lag_warning=300 # repmgr node check --replication-lag
#replication_lag_critical=600 #
Repmgr verificherebbe le soglie dei parametri sopra indicati prima di promuovere lo standby. Se il ritardo di replica è critico, la promozione non andrà avanti. Il che è davvero positivo perché se lo standby viene promosso quando si verifica un ritardo, ciò comporterebbe una perdita di dati.
Le applicazioni devono garantire che si riconnettano correttamente allo standby appena promosso entro il periodo di tempo previsto. I servizi di bilanciamento del carico avrebbero la capacità di deviare le connessioni dell'app quando il database primario non risponde. L'altra alternativa sarebbe l'utilizzo di strumenti middleware come PgPool-II per garantire che tutte le connessioni vengano deviate correttamente.
Per garantire che l'architettura ad alta disponibilità venga implementata in produzione, è necessario eseguire test completi end-to-end dell'intero processo. Nella mia esperienza, chiamiamo questo esercizio come DR DRILL. Ciò significa che, ogni 6 mesi circa, viene eseguita un'operazione di passaggio per garantire che lo standby venga promosso correttamente e che le connessioni dell'app si riconnettano correttamente allo standby promosso. Il primario esistente diventerà un nuovo standby. Una volta completata l'operazione di passaggio, le metriche vengono rimosse per verificare che gli SLA siano soddisfatti.
Cos'è il passaggio?
Come spiegato in precedenza, il passaggio è un'attività pianificata in cui i ruoli del database primario e di standby vengono scambiati. Significa che Standby diventerà primario e primario diventerà standby. Usando repmgr, questo può essere ottenuto. Di seguito è riportato ciò che repmgr esegue quando viene emesso il comando di passaggio.
$ repmgr -f /etc/repmgr.conf standby switchover
NOTICE: executing switchover on node "node2" (ID: 2)
INFO: searching for primary node
INFO: checking if node 1 is primary
INFO: current primary node is 1
INFO: SSH connection to host "node1" succeeded
INFO: archive mode is "off"
INFO: replication lag on this standby is 0 seconds
NOTICE: local node "node2" (ID: 2) will be promoted to primary; current primary "node1" (ID: 1) will be demoted to standby
NOTICE: stopping current primary node "node1" (ID: 1)
NOTICE: issuing CHECKPOINT
DETAIL: executing server command "pg_ctl -D '/data/pgdata11' -m fast -W stop"
INFO: checking primary status; 1 of 6 attempts
NOTICE: current primary has been cleanly shut down at location 0/0501460
NOTICE: promoting standby to primary
DETAIL: promoting server "node2" (ID: 2) using "pg_ctl -D '/data/pgdata-standby11' promote"
server promoting
NOTICE: STANDBY PROMOTE successful
DETAIL: server "node2" (ID: 2) was successfully promoted to primary
INFO: setting node 1's primary to node 2
NOTICE: starting server using "pg_ctl -D '/data/pgdata11' restart"
NOTICE: NODE REJOIN successful
DETAIL: node 1 is now attached to node 2
NOTICE: switchover was successful
DETAIL: node "node2" is now primary
NOTICE: STANDBY SWITCHOVER is complete
Cos'altro può fare repmgr?
- Repmgr può aiutare a creare i database in standby da zero
- È possibile creare più database in standby con un master in esecuzione
- È possibile creare standby a cascata, il che ritengo sia più vantaggioso rispetto alla configurazione di più standby su un database master
Cosa succede se sia Principale che Standby sono spariti?
Bene, questa è una situazione in cui le aziende pensano di avere più istanze di standby. Se sono spariti tutti, l'unica via d'uscita è ripristinare il database dai backup. Questo è il motivo per cui una buona strategia di backup è fondamentale. I backup devono essere sottoposti a ripristino di prova, convalidati regolarmente per garantire che i backup siano affidabili. La progettazione dell'infrastruttura per i backup deve essere tale che il ripristino e il ripristino dei backup non debbano richiedere molto tempo. Il processo di ripristino e ripristino dei backup deve essere completato entro lo SLA designato. Gli SLA per i backup sono progettati in termini di RTO (Recovery Time Objective) e RPO (Recovery Point Objective). Significato, RTO:il tempo necessario per ripristinare e ripristinare il backup deve rientrare nello SLA e nell'RPO:fino a che punto è stato eseguito il ripristino deve essere accettabile, in altri termini è tolleranza alla perdita di dati e generalmente le aziende dicono 0 perdita di dati tolleranza.
Conclusione
- La continuità aziendale per PostgreSQL è un requisito importante per gli ambienti di database mission-critical. Raggiungere questo richiede molta pianificazione e costi.
- Le risorse e l'infrastruttura devono essere utilizzate in modo ottimale per garantire un'efficiente strategia di ripristino di emergenza.
- Potrebbero esserci sfide dal punto di vista dei costi che devono essere affrontate
- Se il budget lo consente, assicurati che vi siano più siti di ripristino di emergenza di cui eseguire il failover
- Nel caso in cui i backup debbano essere ripristinati, assicurati che sia in atto una buona strategia di backup.