Remarque :
- Ce tutoriel nécessite l'accès à Oracle Cloud. Pour vous inscrire à un compte gratuit, reportez-vous à Introduction à Oracle Cloud Infrastructure Free Tier.
- Il utilise des exemples de valeur pour les informations d'identification Oracle Cloud Infrastructure, la location et les compartiments. A la fin de votre atelier, remplacez ces valeurs par celles propres à votre environnement cloud.
Déployer un cluster Postgres hautement disponible sur Oracle Cloud Infrastructure
Introduction
Ce tutoriel décrit la conception et l'implémentation de Postgres dans une configuration HA à l'aide de Patroni et d'autres composants. PostgreSQL ne dispose pas du basculement automatique intégré et du mécanisme automatique permettant d'ajouter le maître défaillant au cluster. Patroni est la nouvelle solution haute disponibilité (HA) d'âge pour PostgreSQL avec des fonctionnalités cloud natives et des options avancées pour le basculement/la permutation, ainsi que la configuration automatisée des processus d'initialisation et des répliques.
Patroni est un modèle qui vous permet de créer votre propre solution HA personnalisée à l'aide de Python et pour une accessibilité maximale, un magasin de configuration distribué comme etcd.
Voici quelques limitations avec la réplication Postgres native et sa solution avec Patroni :
Limites relatives à la réplication Postgres native | Solutions basées sur Patroni |
---|---|
Le mécanisme de réplication par défaut ne prend pas en charge le basculement automatique. | Patroni assure le basculement automatique. |
L'utilisation d'outils externes pour le basculement peut nécessiter des efforts supplémentaires pour les maintenir opérationnels. | Patroni se charge du basculement. |
La surveillance des postes peut également être un défi. | Patroni dispose d'un mécanisme intégré qui surveille le service Postgres. |
L'ajout automatique du noeud défaillant au cluster nécessite des compétences de génération de scripts avancées. | Patroni dispose d'une automatisation intégrée permettant de ramener un noeud défaillant dans le cluster. |
Impossible de gérer les scénarios Split Brain. | Patroni avec l'aide de l'ETCD sera en mesure d'élire un nouveau leader. |
Les autres solutions PostgreSQL HA incluent :
- responsable commercial
- PostgreSQL Basculement automatique (PAF)
- pglookout
- pgPool-II
Toutefois, l'utilisation de Patroni avec l'implémentation Postgres simplifie considérablement le cycle de vie global de gestion de cluster.
-
ETCD est utilisé en tant que magasin de configuration distribué (DCS). Il stocke l'état du cluster PostgreSQL. En cas de modification de l'état d'un noeud PostgreSQL, Patroni met à jour la modification d'état dans la banque clé-valeur ETCD. ETCD utilise ces informations pour élire le noeud maître et maintenir le cluster en fonctionnement.
-
pgBackrest est une solution simple et fiable pour les sauvegardes automatiques. Avantages de Pgbackrest :
- Il s'agit d'un outil de sauvegarde physique. Vous pouvez effectuer des sauvegardes différentielles, incrémentielles et complètes.
- Des travaux parallèles peuvent être configurés pour effectuer des sauvegardes
- La sauvegarde peut être effectuée à partir des serveurs de secours
- WAL asynchrone (journaux d'archive d'écriture anticipée) transmission et extraction
- Plusieurs référentiels peuvent être configurés
- Options de sauvegarde cloud vers OCI/GCP/S3/Azure
-
L'équilibreur de charge réseau OCI est utilisé pour communiquer avec le noeud Leader au lieu d'un HAProxy. L'équilibreur de charge réseau Oracle Cloud Infrastructure (OCI) en tant que service géré est facilement intégré à cette configuration.
Objectif
Ce tutoriel répertorie une solution fiable hautes performances avec des alternatives potentielles pour les clients qui souhaitent migrer des bases de données Postgres (d'AWS ou d'autres fournisseurs cloud) vers OCI. Les principales exigences en matière de haute disponibilité et de migration des données en temps réel.
Architecture
L'architecture suivante se compose de 3 serveurs ETCD, 3 (Postgres + Patroni + Pgbackrest), du bucket Object Storage et de l'équilibreur de charge réseau.
Recommandations
- Pour la haute disponibilité : utilisez 3 serveurs ETCD, 3 noeuds pour PostgreSQL et placez-les dans différents domaines de disponibilité.
- Pour un meilleur débit, créez des volumes de blocs distincts pour les fichiers de données, temporaires, noyaux et journaux.
- Définissez tous les paramètres personnalisés dans la section bootstrap
patroni.yaml
au moment de la création du cluster.
Configurer et installer les composants HA PostgreSQL
La configuration est divisée en deux parties :
- Provisionnement d'infrastructure
- Installation et configuration du logiciel
Tâche 1 : provisionner l'infrastructure
-
Créer des machines virtuelles de calcul :
- 3 serveurs ETCD
- 3 serveurs pour Postgres + Patroni (1 leader et 2 réplique)
-
Créez un bucket Object Storage pour le stockage des sauvegardes.
-
Créez un utilisateur de location OCI avec un accès READ/WRITE sur le bucket de banque d'objets ci-dessus.
Tâche 2 : installer et configurer le logiciel
-
Configurer ETCD.
-
Installez ETCD sur 3 serveurs.
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
-
Configurez et démarrez ETCD sur les 3 serveurs.
Voici les détails du serveur 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 |
Remarque : modifiez les adresses IP conformément aux exigences.
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"
-
Ajoutez des membres à 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
-
Exécutez la commande suivante pour afficher la liste des membres.
etcdctl member list
-
Créez un service.
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
-
-
Installez Postgres sur tous les noeuds. Exécutez le script suivant pour installer Postgres :
-
Script d'installation Postgres
Remarque : pour la réplique, arrêtez postgresql et supprimez le répertoire de données car il sera copié à partir du leader une fois la configuration Patroni terminée.
/opt/pgsql/bin/pg_ctl -D /opt/pgsql/data/$MAJORVERSION stop cd /opt/pgsql/data/ rm *
-
-
Installer les extensions : pg_squeeze et pgaudit.
-
Installer 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
-
Installer 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
-
-
Installez Patroni sur tous les noeuds.
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
-
Installez et configurez pgBackrest sur tous les noeuds.
-
Installer 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
-
Configurer Pgbackrest sur tous les noeuds
/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
-
Créer un fichier bootstrap sur tous les noeuds
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
-
-
Configurez Patroni sur tous les noeuds.
Nom d'hôte Adresse IP Domaine de 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 Remarque : modifiez les adresses IP conformément aux exigences.
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: false
Remarque : modifiez l'adresse IP de chaque noeud, respectivement.
chmod 640 /etc/patroni/patroni.yml chown postgres:postgres -R /etc/patroni/patroni.yml
- Créer un service Patroni sur tous les noeuds
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 patroni
Remarque : sur les noeuds de réplique, configurez Patroni, mais ne démarrez pas les services.
-
Exécutez la commande suivante pour voir le statut du cluster Patroni sur le maître.
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 | | +--------------+-------------+---------+---------+----+-----------+
-
Créez Stanza et effectuez une sauvegarde complète.
pgbackrest --stanza=<stanza-name> stanza-create pgbackrest --type=full --stanza= pgha --process-max=10 backup pgbackrest info
-
Démarrez Patroni sur les noeuds de réplique et commencez à effectuer un rattrapage automatique à partir du leader.
sudo systemctl start patroni sudo systemctl status patroni
- Exécutez la commande suivante pour afficher le statut du cluster :
patronictl -c /etc/patroni/patroni.yml list
Le statut doit être le suivant :
[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 | +--------------+-------------+---------+---------+----+-----------+
-
Enfin, configurez les travaux cron pour le nettoyage des journaux, les sauvegardes, etc.
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
Commandes Patroni supplémentaires
-
Membres de la liste
patronictl -c /etc/patroni/patroni.yml list
-
Basculement/Redémarrage/Basculement
patronictl -c /etc/patroni/patroni.yml failover patronictl -c /etc/patroni/patroni.yml restart patronictl -c /etc/patroni/patroni.yml switchover
-
Mettre à jour le paramètre
patronictl -c /etc/patroni/patroni.yml edit-config -p log_directory='/opt/pgsql/log/' patronictl -c /etc/patroni/patroni.yml show-config
-
Recharger
patronictl -c /etc/patroni/patroni.yml reload <cluster_name>
Liens connexes
- Création d'une instance Linux
- Présentation du bucket Object Storage
- Création d'utilisateurs IAM
- Procédure de création d'un équilibreur de charge réseau
- Utiliser la clé client
- PostgreSQL Télécharger
- PostgresSQL Installations
- Patroni
- Installer Etcd
Accusés de réception
- Authors : Deepika Nayak, Shreyas Rane, Divya Das
Ressources de formation supplémentaires
Explorez d'autres exercices sur docs.oracle.com/learn ou accédez à davantage de contenu de formation gratuit sur le canal Oracle Learning YouTube. En outre, accédez à education.oracle.com/learning-explorer pour devenir explorateur Oracle Learning.
Pour consulter la documentation du produit, consultez Oracle Help Center.
Deploy a highly available Postgres cluster on Oracle Cloud Infrastructure
F74179-01
November 2022
Copyright © 2022, Oracle and/or its affiliates.