Nota:
- Questa esercitazione richiede l'accesso a Oracle Cloud. Per iscriverti a un account gratuito, consulta Inizia a utilizzare Oracle Cloud Infrastructure Free Tier.
- Utilizza valori di esempio per le credenziali, la tenancy e i compartimenti di Oracle Cloud Infrastructure. Al termine del laboratorio, sostituire questi valori con quelli specifici del tuo ambiente cloud.
Distribuire un cluster Postgres ad alta disponibilità su Oracle Cloud Infrastructure
Introduzione
Questa esercitazione descrive la progettazione e l'implementazione di Postgres in una configurazione HA utilizzando Patroni e altri componenti. PostgreSQL non dispone di un failover automatico incorporato e di un meccanismo automatico per aggiungere di nuovo il master non riuscito al cluster. Patroni è la nuova soluzione HA (High Availability) per PostgreSQL con funzioni cloud native e opzioni avanzate per la configurazione di failover/switchover e bootstrap automatici e replica.
Patroni è un modello per creare la tua soluzione HA personalizzata utilizzando Python e per la massima accessibilità, un'area di memorizzazione della configurazione distribuita come etcd.
Di seguito sono riportate alcune limitazioni con la replica nativa di Postgres e la sua soluzione con Patroni:
| Limitazioni nella replica Postgres nativa | Soluzioni basate su patroni |
|---|---|
| Il meccanismo di replica predefinito non supporta il failover automatico. | Patroni fornisce il failover automatico. |
| L'utilizzo di strumenti esterni per il failover potrebbe richiedere ulteriori interventi per garantirne l'operatività. | Patroni si prende cura del failover. |
| I Postgres di monitoraggio possono anche essere una sfida. | Patroni dispone di un meccanismo integrato che monitora il servizio Postgres. |
| L'aggiunta automatica del nodo non riuscito al cluster richiede competenze di script avanzati. | Patroni ha l'automazione integrata per il ripristino di un nodo non riuscito nel cluster. |
| Impossibile gestire gli scenari Split Brain. | Patroni con l'aiuto di ETCD sarà in grado di eleggere un nuovo Leader. |
Altre soluzioni per HA di PostgreSQL includono:
- Responsabile rep.
- PostgreSQL Failover automatico (PAF)
- pglookout
- pgPool-II
Tuttavia, l'utilizzo di Patroni con l'implementazione Postgres semplifica in modo significativo il ciclo di vita complessivo della gestione dei cluster.
-
ETCD viene utilizzato come area di memorizzazione della configurazione distribuita (DCS). Memorizza lo stato del cluster PostgreSQL. Quando vengono apportate modifiche allo stato di qualsiasi nodo PostgreSQL, Patroni aggiorna la modifica dello stato nel keystore ETCD. ETCD utilizza queste informazioni per selezionare il nodo principale e mantenere il cluster attivo e in esecuzione.
-
pgBackrest è una soluzione semplice e affidabile per i backup automatici. Vantaggi di Pgbackrest:
- Si tratta di uno strumento di backup fisico che consente di eseguire backup differenziali, incrementali e completi
- È possibile configurare job paralleli per eseguire i backup
- È possibile eseguire il backup dai server in standby
- Push e pull WAL asincrono (Scrivi log di archivio in avanti)
- È possibile configurare più repository
- Opzioni di backup del cloud per OCI/GCP/S3/Azure
-
OCI Network Load Balancer viene utilizzato per comunicare con il nodo Leader anziché con un HAProxy. Con questa impostazione, il load balancer di rete Oracle Cloud Infrastructure (OCI) è un servizio gestito che viene facilmente integrato.
Obiettivo
Questa esercitazione descrive una soluzione redditizia a elevate prestazioni con potenziali alternative ai clienti per eseguire la migrazione dei database Postgres (da AWS o da altri fornitori di servizi cloud) a OCI. I requisiti chiave sono: HA e migrazione dei dati in tempo reale.
Architettura
La seguente architettura è composta da 3 server ETCD, 3 server (Postgres + Patroni + Pgbackrest), bucket di storage degli oggetti e load balancer di rete.

Suggerimenti
- Per l'alta disponibilità: utilizzare 3 server ETCD, 3 nodi per PostgreSQL e posizionarli in domini di disponibilità diversi.
- Per ottenere un throughput migliore, creare volumi a blocchi separati per i file di dati, temporanei, portafogli e log.
- Definire tutti i parametri personalizzati nella sezione bootstrap
patroni.yamlal momento della creazione del cluster.
Configurare e installare i componenti HA PostgreSQL
L'installazione è suddivisa in due parti:
- Provisioning dell'infrastruttura
- Installazione e configurazione del software
Task 1: Provisioning dell'infrastruttura
-
Crea VM di computazione:
- 3 server ETCD
- 3 Server per Postgres + Patroni (1 Leader e 2 Replica)
-
Creare un bucket di storage degli oggetti per memorizzare i backup.
-
Crea un utente della tenancy OCI con accesso in lettura/scrittura sul bucket dell'area di memorizzazione degli oggetti in alto.
Task 2: Installazione e configurazione del software
-
Configurare ETCD.
-
Installare ETCD su 3 server.
cd /tmp wget https://github.com/etcd-io/etcd/releases/download/v3.5.2/etcd-v3.5.2-linux-amd64.tar.gz tar xzvf /tmp/etcd-v3.5.2-linux-amd64.tar.gz cd etcd-v3.5.2-linux-amd64 cp etcdutl etcdctl etcd /usr/local/bin/ mkdir -p /etc/etcd mkdir -p /var/lib/etcd groupadd -f -g 1501 etcd useradd -c "etcd user" -d /var/lib/etcd -s /bin/false -g etcd -u 1501 etcd chown -R etcd:etcd /var/lib/etcd -
Configura e avvia ETCD su tutti i 3 server.
Di seguito sono riportati i dettagli del server ETCD:
| Hostname | IP Address | Availability Domain | | --- | --- | --- | | pg-etcd-01 | 192.0.2.4 | AD1 | | pg-etcd-02 | 192.0.2.5 | AD2 | | pg-etcd-03 | 192.0.2.6 | AD3 |Nota: modificare gli IP in base al requisito.
pg-etcd-01
vi /etc/etcd/etcd.conf ###Node1 ##192.0.2.4 ETCD_NAME="pg-etcd-01" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.4:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.4:2379" ETCD_LISTEN_PEER_URLS="http://192.0.2.4:2380,http://127.0.0.1:7001" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.4:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"pg-etcd-02
vi /etc/etcd/etcd.conf ##Node2 ##192.0.2.5 ETCD_NAME=" pg-etcd-02" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.5:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.5:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.5:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.5:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"pg-etcd-03
vi /etc/etcd/etcd.conf ##Node3 ##192.0.2.6 ETCD_NAME="pg-etcd-03" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380,pg-etcd-03=http://192.0.2.6:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.6:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.6:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.6:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.6:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true" -
Aggiungere membri a pg-etcd-01.
etcdctl member add pg-etcd-02 --peer-urls=http://192.0.2.5:2380 etcdctl member add pg-etcd-03 --peer-urls=http://192.0.2.6:2380 -
Eseguire il comando seguente per visualizzare la lista di membri.
etcdctl member list -
Creare un servizio.
vi /etc/systemd/system/etcd.service [Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify WorkingDirectory=/var/lib/etcd EnvironmentFile=-/etc/etcd/etcd.conf User=etcd # set GOMAXPROCS to number of processors ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/local/bin/etcd" Restart=on-failure LimitNOFILE=65536 IOSchedulingClass=best-effort IOSchedulingPriority=0 [Install] WantedBy=multi-user.target systemctl daemon-reload systemctl enable etcd
-
-
Installa Postgres su tutti i nodi. Eseguire lo script seguente per installare Postgres:
-
Script di installazione Postgres
Nota: per Replica, arrestare postgresql ed eliminare la directory dati in quanto verrà copiata dal leader una volta completata la configurazione Patroni.
/opt/pgsql/bin/pg_ctl -D /opt/pgsql/data/$MAJORVERSION stop cd /opt/pgsql/data/ rm *
-
-
Installare le estensioni: pg_squeeze e pgaudit.
-
Installa PGAUDIT
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/pgaudit/pgaudit/archive/refs/heads/REL_12_STABLE.zip unzip REL_12_STABLE.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config -
Installa PG_SQUEEZE
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/cybertec-postgresql/pg_squeeze/archive/refs/heads/master.zip unzip master.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config
-
-
Installare Patroni su tutti i nodi.
yum update –y yum -y install epel-release yum -y install python3 yum install -y python3-devel yum install -y psutils yum install -y gcc yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install python3-psycopg2 pip3 install python-etcd pip3 install patroni -
Installare e configurare pgBackrest su tutti i nodi.
-
Installa Pgbackrest
yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install pgbackrest -y -
Configura Pgbackrest in tutti i nodi
/etc/pgbackrest.conf [global] repo1-type=s3 repo1-path=/backup repo1-s3-uri-style=path repo1-s3-region=us-ashburn-1 repo1-s3-endpoint=https://xxxxx0011.compat.objectstorage.us-ashburn-1.oraclecloud.com repo1-s3-key=0000000a90d57eddexxxxxa3dc7c4f700000ed2e6 repo1-s3-key-secret=1UhXj69xxxx1e6OyF+00000cccccyyyuuu= repo1-s3-bucket=pg_backup repo1-retention-full=10 log-level-console=info log-level-file=debug log-path=/var/log/pgbackrest/ [stanza-name] pg1-path=/opt/pgsql/data pg1-user=Postgres -
Creare un file di bootstrap su tutti i nodi
vi /etc/patroni/boot_pgbackrest.sh #!/ usr / bin /env bash while getopts ": -:" optchar ; do [[ "${ optchar }" == "-" ]] || continue case "${ OPTARG }" in datadir =* ) DATA_DIR =${ OPTARG #*=} ;; scope =* ) SCOPE =${ OPTARG #*=} ;; esac done /bin/pgbackrest --stanza=$SCOPE --link-all restore
-
-
Configurare Patroni su tutti i nodi.
Nome host Indirizzo IP Dominio di disponibilità pg-db-01 192.0.2.1 AD1 pg-db-02 192.0.2.2 AD2 pg-db-03 192.0.2.3 AD3 Nota: modificare gli IP in base al requisito.
mkdir -p /etc/patroni mkdir -p /opt/pgsql/patroni chown postgres:postgres -R /opt/pgsql/patroni chmod 700 /opt/pgsql/patroni vi /etc/patroni/patroni.yml scope:pg-ha-cluster name:pg-db-01 namespace:/opt/pgsql/patroni/ ### restapi: listen: "192.0.2.1:8008" connect_address: "192.0.2.1:8008" ###ETCD Configuration etcd: hosts: "192.0.2.4:2379,192.0.2.5:2379, 192.0.2.6:2379" ###Bootstrap bootstrap: dcs: ttl: 120 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true use_slots: true parameters: archive_command: "pgbackrest --stanza=<stanza-name> archive-push %p" archive_mode: on archive_timeout: 900s log_file_mode: "0640" log_filename: postgresql-%u.log log_rotation_age: 1d log_truncate_on_rotation: "on" logging_collector: "on" max_connections: 2000 max_replication_slots: 10 max_wal_senders: 10 max_wal_size: 5GB max_worker_processes: 40 min_wal_size: 1GB wal_level: "replica" password_encryption: scram-sha-256 superuser_reserved_connections: 200 create_replica_methods: - pgbackrest pgbackrest: command: "/usr/bin/pgbackrest --stanza=<stanza-name> restore --delta --link-all" keep_data: True no_params: True recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' method: pgbackrest pgbackrest: command: /etc/patroni/boot_pgbackrest.sh keep_existing_recovery_conf: False recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' initdb: - encoding: UTF8 - data-checksums pg_hba: - host replication replicator 127.0.0.1/32 md5 - host replication replicator 192.0.2.1/32 md5 - host replication replicator 192.0.2.2/32 md5 - host replication replicator 192.0.2.3/32 md5 - host all all x.x.x.0/0 md5 users: admin: password: admin options: - createrole - createdb #####Local Postgresql Parameters postgresql: listen: "192.0.2.1:5432" connect_address: "192.0.2.1:5432" data_dir: /opt/pgsql/data pgpass: /opt/pgsql/patroni/pgpass authentication: replication: username: replicator password: password superuser: username: postgres password: password # rewind: # username: replicator # password: password parameters: unix_socket_directories: "/var/run/postgresql, /tmp" ###Any Tags tags: nofailover: false noloadbalance: false clonefrom: false nosync: falseNota: modificare rispettivamente l'IP per ogni nodo.
chmod 640 /etc/patroni/patroni.yml chown postgres:postgres -R /etc/patroni/patroni.yml- Crea servizio Patroni su tutti i nodi
vi /etc/systemd/system/patroni.service [Unit] Description=Runners to orchestrate a high-availability PostgreSQL - patroni After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres # Read in configuration file if it exists, otherwise proceed EnvironmentFile=-/etc/patroni_env.conf WorkingDirectory=~ # Where to send early-startup messages from the server # This is normally controlled by the global default set by systemd # StandardOutput=syslog# Pre-commands to start watchdog device # Uncomment if watchdog is part of your patroni setup #ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog # Start the patroni process ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml # Send HUP to reload from patroni.yml ExecReload=/bin/kill -s HUP $MAINPID # Only kill the patroni process, not its children, so it will gracefully stop postgres KillMode=process # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=60 # Do not restart the service if it crashes, we want to manually inspect database on failure Restart=no [Install] WantedBy=multi-user.target sudo systemctl daemon-reload sudo systemctl enable patroni sudo systemctl start patroni sudo systemctl status patroniNota: sui nodi di replica, configurare Patroni, ma non avviare i servizi.
-
Eseguire il comando seguente per visualizzare lo stato del cluster Patroni sul master.
patronictl -c /etc/patroni/patroni.yml list [root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 1 | | +--------------+-------------+---------+---------+----+-----------+
-
Crea Stanza e esegui il backup completo.
pgbackrest --stanza=<stanza-name> stanza-create pgbackrest --type=full --stanza= pgha --process-max=10 backup pgbackrest info -
Avviare Patroni sui nodi Replica e iniziare a recuperare automaticamente dal Leader.
sudo systemctl start patroni sudo systemctl status patroni- Eseguire il comando seguente per visualizzare lo stato del cluster:
patronictl -c /etc/patroni/patroni.yml listLo stato deve essere il seguente:
[root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 2 | | | pg-db-02 | 192.0.2.2 | Replica | running |2 | 0 | | pg-db-03 | 192.0.2.3 | Replica | running | 2 | 0 | +--------------+-------------+---------+---------+----+-----------+ -
Impostare infine i job cron per il cleanup dei log, i backup e così via.
crontab –e #Pgbackrest FULL Backup on Sunday @1AM 00 01 * * 0 postgres pgbackrest --type=full --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Pgbackrest INC Backup on Mon-Sat @1AM 00 01 * * 1-6 postgres pgbackrest --type=diff --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Delete PostgreSQL logs 08 * * * find /opt/pgsql/log/* -mtime +15 -exec rm {} \; &>/dev/null
Comandi Patroni aggiuntivi
-
Membri della lista
patronictl -c /etc/patroni/patroni.yml list -
Failover/Riavvia/Switchover
patronictl -c /etc/patroni/patroni.yml failover patronictl -c /etc/patroni/patroni.yml restart patronictl -c /etc/patroni/patroni.yml switchover -
Aggiorna parametro
patronictl -c /etc/patroni/patroni.yml edit-config -p log_directory='/opt/pgsql/log/' patronictl -c /etc/patroni/patroni.yml show-config -
Ricarica
patronictl -c /etc/patroni/patroni.yml reload <cluster_name>
Collegamenti correlati
- Come creare un'istanza Linux
- Panoramica del bucket di storage degli oggetti
- Creazione di utenti IAM
- Come creare un load balancer di rete
- Utilizzo della chiave cliente
- PostgreSQL Scarica
- PostgresSQL Installazioni
- Patroni
- Installa Etcd
Conferme
- Autori: Deepika Nayak, Shreyas Rane, Divya Das
Altre risorse di apprendimento
Esplora altri laboratori all'indirizzo docs.oracle.com/learn o accedi ad altri contenuti per la formazione gratuita sul canale YouTube di Oracle Learning. Inoltre, visitare education.oracle.com/learning-explorer per diventare Oracle Learning Explorer.
Per la documentazione sul prodotto, visitare Oracle Help Center.
Deploy a highly available Postgres cluster on Oracle Cloud Infrastructure
F74179-01
November 2022
Copyright © 2022, Oracle and/or its affiliates.