PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Mécanismes de réplication physique dans PostgreSQL

Postgres est livré avec des fonctionnalités de réplication physique et logique. Lisez la suite pour en savoir plus sur les différents aspects de la réplication physique.

Réplication physique

Les méthodes de réplication physique sont utilisées pour conserver une copie complète de toutes les données d'un seul cluster (dans Postgres, un cluster est un ensemble de bases de données gérées par un seul processus de serveur principal Postgres appelé postmaster ), généralement sur une autre machine. La machine source est appelée principale dans le jargon Postgres, et la destination est appelée standby .

Veilles Chaud, Chaud et "Froid"

Un serveur de secours qui est maintenu aussi à jour que possible avec le serveur principal en temps réel et qui permet aux clients d'exécuter des transactions en lecture seule est appelé unchaud veille, ou plus communément un réplica en lecture . Les hot standbys ont été ajoutés à Postgres dans la version 9, avant laquelle il n'y avait que warm veilles. Un warmstandby est similaire à un hot standby, sauf qu'il ne permet pas aux clients de s'y connecter.

(À part :les serveurs de secours ne peuvent pas exécuter de requêtes qui créent des tables temporaires. Il s'agit d'une limitation de Postgres.)

Un serveur de secours "froid" (terme non officiel) est généralement un serveur de secours qui ne démarre qu'après un basculement. Étant donné que le serveur de secours à froid n'est pas opérationnel, il est possible qu'au démarrage, il doive d'abord appliquer les modifications en attente avant de pouvoir commencer à accepter les connexions client.

Fichiers WAL

Dans le cours normal des opérations, un serveur PostgreSQL génère une série ordonnée d'enregistrements WAL (write ahead log). Il s'agit essentiellement d'un journal des modifications, similaire à l'AOF de Redis ou au binlog de MySQL. À la base, la réplication physique consiste à transporter ces enregistrements sur une autre machine et à faire en sorte que l'autre postmaster qui s'y exécute accepte et applique ces enregistrements dans sa base de données locale.

Les enregistrements WAL sont regroupés en fichiers de taille égale (généralement 16 Mo) appelés segments WAL ou simplement des fichiers WAL . Ces fichiers sont créés dans un répertoire appelé pg_wal sous le répertoire de données du cluster (pg_wal s'appelait pg_xlog dans les versions Postgres antérieures à 10). Les anciens fichiers WAL sont supprimés lorsqu'ils ne sont plus nécessaires (et également en fonction de quelques paramètres de configuration).

Mode de récupération

Le postmaster peut être démarré dans un mode appelé mode de récupération , en plaçant un fichier de configuration valide appelé recovery.conf dans le répertoire de données du cluster. En mode de récupération, Postgres n'importera et n'appliquera que les fichiers WAL générés par un serveur primaire et ne générera par lui-même aucun fichier WAL. Les serveurs chauds et de secours fonctionnent en mode de récupération.

Lorsqu'il est démarré en mode de récupération, Postgres essaiera d'abord d'importer tous les fichiers WAL disponibles dans une archive (plus de ceci ci-dessous). Lorsque l'archive n'a plus de fichiers WAL à offrir, elle essaie d'importer tous les fichiers se trouvant autour du pg_wal d'init annuaire. Lorsque ceux-ci sont également terminés, si une connexion principale est configurée et que le mode veille est défini sur on dans recovery.conf, Postgres se connectera au primaire et extraira et appliquera les nouveaux enregistrements WAL au fur et à mesure qu'ils seront créés au primaire.

Envoi de journaux

Imaginez avoir un déclencheur qui sera invoqué sur le serveur principal chaque fois qu'un nouveau fichier WAL est créé. Ce déclencheur peut ensuite copier le nouveau fichier WAL sur une autre machine en utilisant, par exemple, rsync , et placez-le dans le pg_wal répertoire d'un postmaster tournant en mode recovery. Pouvez-vous faire une mise en veille comme celle-ci ?

La réponse est oui, et c'était en effet la pratique courante avant l'ajout de la réplication en continu dans Postgres v9. Cette pratique s'appelle l'envoi de journaux .

Le déclencheur est un script shell, qui peut être configuré à l'aide de archive_command. Le nom et le chemin du fichier WAL peuvent être passés au script.

Archivage WAL

Au lieu de rsynchroniser sur le fichier WAL, disons que nous le copions dans un compartiment S3 ou un répertoire monté NFS qui est également accessible depuis la machine de secours. Cet emplacement partagé contiendra désormais tous les fichiers WAL générés par le primaire. devient une archive , et le processus de stockage des fichiers WAL dans l'archive est appelé archivage continu ou simplement archivage WAL .

L'inverse de cette opération - récupérer les fichiers WAL de l'archive dans un Postgres en mode de récupération - peut être configuré en utilisantrestore_command. Similaire à archive_command , c'est aussi le chemin vers un script shell. Le postmaster qui s'exécute en mode de récupération sait quel fichier WAL il veut. Le nom du fichier peut être passé au script.

À titre d'exemple, voici les commandes d'archivage et de restauration pour stocker et récupérer des fichiers WAL vers et depuis un compartiment S3 :

archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf

Lors du démarrage en mode recovery, si restore_command est configuré, Postgres essaiera d'abord de récupérer les fichiers WAL de l'archive.

pg_standby

En mode de récupération, Postgres ne sait pas et ne peut pas savoir à l'avance combien de fichiers WAL ont été générés jusqu'à présent. Si restore_command est configuré, Postgres l'invoquera à plusieurs reprises avec des noms de fichiers WAL progressifs (les noms sont dans une séquence prévisible) jusqu'à ce que la commande renvoie une erreur.

Par exemple, la commande restore a pu satisfaire les demandes de fichiers WAL000000010000000000000001 via 00000001000000000000001A mais échoue pour 00000001000000000000001B car il n'a pas été trouvé dans l'emplacement de l'archive. n'a pas encore été généré par le primaire et terminera la récupération après l'application de 00000001000000000000001A .

Considérez ce qui se passe si la commande de restauration devait attendre le fichier00000001000000000000001B être disponible, plutôt que de sortir avec une erreur car il n'a pas été trouvé. Postgres continuera d'attendre la commande de restauration et continuera donc d'être en mode de récupération.

Il s'agit d'une configuration valide et d'un moyen valide de configurer une attente à chaud.

Postgres est livré avec une commande appelée pg_standby, qui peut être utilisée pour configurer une attente à chaud de cette manière, tant que l'archive est un répertoire.pg_standby attendra qu'un fichier soit disponible, s'il est introuvable.

Les commandes d'archivage et de restauration utilisant pg_standby ressembleront à ceci :

archive_command = 'cp %p /some/path/%f'         # in postgresql.conf
restore_command = 'pg_standby /some/path %f %p' # in recovery.conf

Réplication en continu

Après traitement des fichiers WAL archivés ainsi que des fichiers dans le pg_wal répertoire, Postgres peut se connecter à un serveur principal sur le réseau et récupérer et appliquer à plusieurs reprises de nouveaux fichiers WAL au fur et à mesure de leur création. Cette fonctionnalité, ajoutée dans Postgres 9, est appelée réplication en continu .

Le serveur principal auquel se connecter peut être spécifié dans le fichier recovery.conf :

# recovery.conf
standby_mode = on
primary_conninfo = 'host=10.0.1.10 user=repl password=p@ssw0rd'

Veille automatique

Par défaut, en mode de récupération, Postgres n'acceptera pas les connexions client, les rejetant avec les messages d'erreur « Le système de base de données est en mode de récupération ». En ajoutant la ligne hot_standby =on dans recovery.conf, vous pouvez créer des connexions client Postgresaccept et leur permettre d'exécuter des transactions en lecture seule :

# recovery.conf
hot_standby = on

Il n'y a généralement aucune raison de désactiver hot_standby.

La documentation PostgreSQL contient plus d'informations sur la configuration et l'exécution d'un standby en mode "hot standby".

Emplacements de réplication

Les slots de réplication ont été introduits dans Postgres 9.4. Il s'agit d'un mécanisme permettant de suivre précisément et durablement le retard d'un standby par rapport au primaire. Cela permet au primaire de s'assurer que les fichiers WAL encore nécessaires au rattrapage du standby ne sont pas supprimés.

Avant les slots de réplication, il n'était pas possible pour le primaire de déterminer cela, et vous vous retrouviez dans des situations où un standby restait bloqué parce qu'un fichier WAL dont il avait besoin avait été supprimé par le primaire. Bien sûr, les archives WAL peuvent résoudre ce problème. Sans archive WAL, cependant, la seule option était de reconstruire le standby à partir d'une nouvelle sauvegarde.

Vous pouvez en savoir plus sur les slots de réplicationici.

Étapes pour configurer une redondance d'UC

Examinons les étapes nécessaires pour configurer un serveur de secours pour un serveur principal existant.

1. Créer un utilisateur de réplication

Tout d'abord, nous avons besoin d'un utilisateur pour le standby pour se connecter en tant que :

$ psql -p 6000
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.

postgres=# CREATE USER repluser REPLICATION PASSWORD 'p@ssw0rd';
CREATE USER

Et les modifications correspondantes dans pg_hba.conf :

# TYPE  DATABASE        USER          ADDRESS        METHOD
host    replication     repluser      standby-ip/32  md5
# (replace standby-ip)

Vous pouvez bien sûr utiliser n'importe quel mécanisme d'authentification standard de PostgreSQL. L'utilisateur doit disposer de privilèges de réplication et de connexion et n'a pas besoin d'accéder à une base de données spécifique.

Assurez-vous de recharger le serveur principal pour que les modifications apportées à pg_hba.conf prennent effet.

2. Faire une sauvegarde

Le serveur de secours doit démarrer à partir d'une sauvegarde du serveur principal. Vous pouvez et devriez le faire en utilisant pg_basebackup avec un nouveau slot de réplication :

pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby

Cela se connecte au primaire à primary-ip:6000 avec l'utilisateur que nous venons de créer et en fait une sauvegarde dans le répertoire standby . Un nouveau slot de réplicationslot_standby1 est créé.

3. Ajouter recovery.conf en veille

Nous utiliserons cet emplacement comme emplacement de réplication de secours, afin qu'il y ait continuité à partir de la sauvegarde.

Nous avions demandé pg_basebackup pour créer un recovery.conf pour nous ci-dessus (option "-R"). Voyons cela :

$ cat standby/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=repluser password=''p@ssw0rd'' host=primary-ip port=6000 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_standby1'

C'est en fait assez bon, et nous n'avons pas besoin de le modifier davantage. Allumons simplement la mise en veille maintenant :

o$ pg_ctl -D standby -l log_standby -o --port=6001 start
waiting for server to start.... done
server started
postgres@stg1:/tmp/demo$ cat log_standby
2019-06-19 09:17:50.032 UTC [21733] LOG:  listening on IPv4 address "127.0.0.1", port 6001
2019-06-19 09:17:50.034 UTC [21733] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.6001"
2019-06-19 09:17:50.067 UTC [21734] LOG:  database system was interrupted; last known up at 2019-06-19 09:12:05 UTC
2019-06-19 09:17:50.111 UTC [21734] LOG:  entering standby mode
2019-06-19 09:17:50.119 UTC [21734] LOG:  redo starts at 0/2000028
2019-06-19 09:17:50.120 UTC [21734] LOG:  consistent recovery state reached at 0/20000F8
2019-06-19 09:17:50.120 UTC [21733] LOG:  database system is ready to accept read only connections
2019-06-19 09:17:50.138 UTC [21739] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1

Et c'est tout! Le fichier journal indique que la réplication en continu est en cours d'exécution. Vous devriez maintenant pouvoir vous connecter au serveur de secours au port 6001, exécuter des requêtes en lecture seule et voir les modifications être répliquées à partir du serveur principal plus ou moins en temps réel.

Étapes suivantes

Les documentations PostgreSQL sont un excellent endroit pour commencer à approfondir toutes les fonctionnalités de Postgres liées à la réplication. Vous voudrez peut-être vous pencher sur des sujets tels que la réplication différée, la réplication en cascade, les veilles synchrones, etc.

Bien que Postgres soit livré avec un ensemble impressionnant de fonctionnalités, il existe encore des cas d'utilisation qui ne sont pas pris en charge. Cette page wiki Postgres contient une liste d'outils tiers qui fournissent des fonctionnalités supplémentaires liées à la réplication.