Réplication par Streaming PostgreSQL

PostgreSQLBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez à configurer la réplication en flux (streaming replication) de PostgreSQL. Cette fonctionnalité puissante vous permet de maintenir une copie en direct et en lecture seule de votre base de données primaire sur un serveur secondaire, appelé réplique. La réplique reçoit et applique continuellement les modifications de données de la primaire, ce qui la rend utile pour la haute disponibilité, l'équilibrage de charge des requêtes de lecture et les sauvegardes.

Vous parcourrez l'ensemble du processus, en commençant par la configuration du serveur primaire pour autoriser la réplication. Ensuite, vous créerez un serveur réplique en effectuant une sauvegarde de base (base backup). Enfin, vous démarrerez la réplique, testerez le flux de données entre les deux serveurs et verrez comment la réplique reste synchronisée avec la primaire.

Configurer le Serveur Primaire pour la Réplication

Dans cette première étape, vous allez configurer le serveur PostgreSQL primaire pour le préparer à la réplication. Cela implique de modifier ses fichiers de configuration pour autoriser les connexions réseau, d'activer le niveau nécessaire de Write-Ahead Log (WAL), et de créer un utilisateur spécial pour la réplication.

1. Modifier le Fichier de Configuration PostgreSQL

Pour vous préparer à la réplication, vous devez modifier le fichier de configuration principal, postgresql.conf. L'édition manuelle de ce fichier volumineux avec un éditeur de texte comme nano peut être difficile et sujette aux erreurs en raison du grand nombre d'options. Une méthode plus efficace et fiable consiste à utiliser des outils en ligne de commande pour visualiser et mettre à jour les paramètres spécifiques que vous devez modifier. Cela évite d'avoir à parcourir des centaines de lignes et prévient les erreurs accidentelles.

Tout d'abord, vérifions les valeurs actuelles des paramètres que nous devons modifier : listen_addresses, wal_level, et max_wal_senders.

CONF_FILE="/etc/postgresql/14/main/postgresql.conf"
echo "--- Current Settings ---"
sudo grep -E "^#?\s*(listen_addresses|wal_level|max_wal_senders)" $CONF_FILE

Vous verrez probablement ces lignes commentées avec un #.

Maintenant, mettons à jour ces paramètres automatiquement. Les commandes suivantes sauvegarderont le fichier de configuration, puis mettront à jour chaque paramètre requis.

CONF_FILE="/etc/postgresql/14/main/postgresql.conf"
## Create a backup before making changes
sudo cp $CONF_FILE ${CONF_FILE}.bak.$(date +%s)

## Set listen_addresses to allow connections from any IP address
sudo sed -i -E "s/^[#\s]*listen_addresses\s*=.*/listen_addresses = '*'/" "$CONF_FILE"

## Set wal_level to 'replica' to enable replication logs
sudo sed -i -E "s/^[#\s]*wal_level\s*=.*/wal_level = replica/" "$CONF_FILE"

## Set the maximum number of concurrent replication connections
sudo sed -i -E "s/^[#\s]*max_wal_senders\s*=.*/max_wal_senders = 10/" "$CONF_FILE"

Enfin, vérifions que les modifications ont été appliquées correctement. La commande ci-dessous affichera les nouvelles valeurs, en filtrant les lignes commentées.

echo "--- Verified Settings ---"
sudo grep -E "^(listen_addresses|wal_level|max_wal_senders)" $CONF_FILE

La sortie devrait afficher la configuration mise à jour et active :

listen_addresses = '*'
wal_level = replica
max_wal_senders = 10

Avec ces paramètres confirmés, le serveur est correctement configuré pour les étapes suivantes.

2. Créer un Utilisateur de Réplication Dédié

Il est recommandé d'utiliser un utilisateur dédié pour la réplication plutôt qu'un superutilisateur. Créons un rôle nommé replicator.

Connectez-vous à PostgreSQL en utilisant le client en ligne de commande psql :

sudo -u postgres psql

Exécutez maintenant la commande SQL suivante pour créer l'utilisateur avec les privilèges de réplication et un mot de passe :

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replicapass';

Vous devriez voir la sortie CREATE ROLE. Maintenant, quittez le client psql :

\q

3. Autoriser la Connexion de Réplication

Ensuite, vous devez configurer le serveur pour permettre à l'utilisateur replicator de se connecter depuis le serveur réplique. Vous le ferez en modifiant le fichier pg_hba.conf.

Ouvrez le fichier avec nano :

sudo nano /etc/postgresql/14/main/pg_hba.conf

Ajoutez la ligne suivante à la fin du fichier. Cette règle spécifie que l'utilisateur replicator est autorisé à se connecter à la pseudo-base de données replication depuis n'importe quelle adresse IP (0.0.0.0/0). Pour ce laboratoire, nous utilisons 127.0.0.1/32 car les deux serveurs sont sur la même machine.

host    replication     replicator      127.0.0.1/32            md5

Appuyez sur Ctrl+X, Y, puis Entrée pour sauvegarder et quitter.

4. Redémarrer le Serveur Primaire

Pour appliquer toutes ces modifications de configuration, vous devez redémarrer le service PostgreSQL.

sudo service postgresql restart

Le serveur primaire est maintenant prêt à accepter les connexions de réplication.

Créer la Réplique à partir d'une Sauvegarde de Base

Le serveur primaire étant configuré, l'étape suivante consiste à créer la réplique. La méthode standard pour ce faire est de prendre une "sauvegarde de base" (base backup) du serveur primaire. Cela crée une copie identique du répertoire de données du primaire, qui servira de point de départ pour la réplique.

1. Créer un Répertoire de Données pour la Réplique

Tout d'abord, créez un nouveau répertoire où seront stockées les données de la réplique. Il est recommandé de le créer dans un emplacement système, et non dans le répertoire personnel d'un utilisateur, afin d'éviter les problèmes de permissions. Nous allons le créer en tant qu'utilisateur postgres dans le répertoire standard de PostgreSQL.

sudo -u postgres mkdir -p /var/lib/postgresql/14/replica

2. Effectuer la Sauvegarde de Base

Maintenant, utilisez l'utilitaire pg_basebackup pour copier les données du serveur primaire. Cette commande se connectera au primaire en tant qu'utilisateur replicator et diffusera les données vers le nouveau répertoire de la réplique. Comme vous avez créé le répertoire en tant qu'utilisateur postgres, il n'y a pas de problèmes de permissions à résoudre.

Exécutez la commande suivante. Vous serez invité à saisir le mot de passe de l'utilisateur replicator, qui est replicapass.

sudo -u postgres pg_basebackup -h localhost -p 5432 -U replicator -D /var/lib/postgresql/14/replica -P -v -R

Décomposons cette commande :

  • sudo -u postgres: Exécute la commande en tant qu'utilisateur système postgres, qui possède les permissions nécessaires.
  • pg_basebackup: L'utilitaire pour effectuer les sauvegardes de base.
  • -h localhost -p 5432: Spécifie l'hôte et le port du serveur primaire.
  • -U replicator: Le nom d'utilisateur à utiliser pour la connexion.
  • -D /var/lib/postgresql/14/replica: Le répertoire cible pour la sauvegarde.
  • -P: Affiche un rapport de progression.
  • -v: Active le mode verbeux.
  • -R: C'est une option très utile. Elle crée un fichier standby.signal et ajoute les paramètres de connexion au fichier postgresql.auto.conf dans le répertoire cible, ce qui configure automatiquement le nouveau répertoire de données comme une réplique.

3. Copier les Fichiers de Configuration

La sauvegarde de base copie les fichiers de données principaux, mais sur de nombreux systèmes basés sur Debian (comme cet environnement Ubuntu), les fichiers de configuration (pg_hba.conf et pg_ident.conf) sont stockés séparément dans /etc/postgresql/ et ne sont pas inclus dans la sauvegarde. Vous devez les copier manuellement dans le répertoire de données de la réplique. Après la copie, vous devez également vous assurer qu'ils appartiennent à l'utilisateur postgres afin que le processus serveur puisse les lire.

sudo cp /etc/postgresql/14/main/pg_hba.conf /var/lib/postgresql/14/replica/
sudo cp /etc/postgresql/14/main/pg_ident.conf /var/lib/postgresql/14/replica/
sudo chown postgres:postgres /var/lib/postgresql/14/replica/pg_hba.conf
sudo chown postgres:postgres /var/lib/postgresql/14/replica/pg_ident.conf

Avec les fichiers de données et la configuration en place, le répertoire de la réplique est prêt pour les dernières étapes de configuration.

Configurer et Démarrer le Serveur Réplique

La sauvegarde de base a préparé le répertoire de données de la réplique. Cependant, comme vous exécutez les serveurs primaire et réplique sur la même machine, ils ne peuvent pas utiliser le même port réseau (le port par défaut est 5432). Dans cette étape, vous allez configurer la réplique pour utiliser un port différent, puis la démarrer.

1. Configurer le Port de la Réplique

Modifiez le fichier postgresql.conf situé dans le répertoire de données de la réplique pour changer son port d'écoute. Notez que vous avez besoin de sudo car ce fichier appartient désormais à l'utilisateur postgres.

sudo nano /var/lib/postgresql/14/replica/postgresql.conf

Ajoutez la ligne suivante à la fin du fichier pour définir le port sur 5433 :

port = 5433

Appuyez sur Ctrl+X, Y, puis Entrée pour sauvegarder et quitter.

2. Définir les Permissions du Répertoire de Données

Par mesure de sécurité, PostgreSQL exige que son répertoire de données ne soit pas accessible par d'autres utilisateurs. Vous devez définir ses permissions sur 700, ce qui accorde les permissions de lecture, d'écriture et d'exécution uniquement au propriétaire (postgres).

sudo chmod 0700 /var/lib/postgresql/14/replica

3. Démarrer le Serveur Réplique

Vous pouvez maintenant démarrer le serveur réplique. Vous utiliserez pg_ctl, un utilitaire standard de PostgreSQL pour contrôler un serveur de base de données.

Exécutez la commande suivante pour démarrer la réplique. Vous devez utiliser le chemin complet vers pg_ctl car la commande sudo pourrait ne pas savoir où le trouver autrement. Nous allons également spécifier un fichier journal dans /tmp pour faciliter la vérification de l'état du serveur.

sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /var/lib/postgresql/14/replica -l /tmp/replica.log start
  • pg_ctl: L'utilitaire de contrôle du serveur.
  • -D /var/lib/postgresql/14/replica: Spécifie le répertoire de données pour cette instance de serveur.
  • -l /tmp/replica.log: Spécifie le fichier journal.
  • start: L'action à effectuer.

Vous devriez voir le message :

waiting for server to start.... done
server started

4. Vérifier le Fichier Journal de la Réplique

Pour confirmer que la réplique a démarré correctement et s'est connectée au primaire, consultez son fichier journal avec sudo car il appartient à l'utilisateur postgres :

sudo cat /tmp/replica.log

Recherchez les lignes indiquant que le système de base de données est prêt à accepter des connexions en lecture seule et qu'il a commencé à streamer le WAL depuis le primaire. Vous devriez voir quelque chose de similaire à ceci :

...
LOG:  database system is ready to accept read-only connections
LOG:  started streaming WAL from primary at 0/4000000 on timeline 1
...

Cela confirme que votre serveur réplique est opérationnel, en cours d'exécution et connecté avec succès au primaire.

Tester la Réplication

Maintenant que les deux serveurs sont en cours d'exécution, il est temps de tester si la réplication fonctionne comme prévu. Vous allez créer une table sur le serveur primaire et vérifier qu'elle apparaît sur la réplique. Vous confirmerez également que la réplique est en lecture seule.

1. Vérifier le Statut de la Réplication sur le Primaire

Tout d'abord, connectez-vous au serveur primaire (sur le port 5432) et vérifiez la vue pg_stat_replication. Cette vue fournit des informations de surveillance sur les répliques connectées.

sudo -u postgres psql -p 5432

Exécutez cette requête :

SELECT client_addr, state, sync_state FROM pg_stat_replication;

La sortie devrait montrer votre réplique connectée, avec son état streaming et sync_state comme async ou sync.

 client_addr |   state   | sync_state
-------------+-----------+------------
 127.0.0.1   | streaming | async
(1 row)

2. Créer des Données sur le Primaire

Tout en étant connecté au primaire, créez une nouvelle table et insérez quelques données :

CREATE TABLE replication_test (id INT, message TEXT);
INSERT INTO replication_test VALUES (1, 'Hello from primary!');

Maintenant, interrogez la table pour confirmer que les données y sont présentes :

SELECT * FROM replication_test;

Vous devriez voir la ligne que vous venez d'insérer. Quittez le shell psql du primaire :

\q

3. Vérifier les Données sur la Réplique

Ouvrez un nouveau terminal ou utilisez celui que vous avez déjà pour vous connecter au serveur réplique sur le port 5433. Vous devrez fournir le mot de passe de l'utilisateur postgres, qui est labex.

psql -h localhost -p 5433 -U postgres -d postgres

Maintenant, interrogez la table replication_test sur la réplique :

SELECT * FROM replication_test;

Vous devriez voir exactement les mêmes données que celles que vous avez créées sur le primaire. Cela confirme que la réplication par streaming fonctionne !

 id |      message
----+---------------------
  1 | Hello from primary!
(1 row)

4. Tester la Nature Lecture Seule de la Réplique

Essayez d'insérer des données dans la table sur la réplique :

INSERT INTO replication_test VALUES (2, 'Hello from replica?');

La commande échouera avec une erreur car un serveur réplique est en mode lecture seule par défaut.

ERROR:  cannot execute INSERT in a read-only transaction

C'est un comportement attendu et une caractéristique clé d'une réplique en streaming. Quittez le shell psql de la réplique :

\q

Nettoyer l'Environnement

Dans cette dernière étape, vous allez arrêter les serveurs et supprimer les fichiers et répertoires créés pendant le laboratoire afin de ramener l'environnement à son état initial.

1. Arrêter le Serveur Réplique

Tout d'abord, arrêtez le serveur réplique en utilisant pg_ctl. N'oubliez pas d'utiliser le chemin complet de l'exécutable.

sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /var/lib/postgresql/14/replica stop

Vous verrez un message de confirmation indiquant que le serveur s'est arrêté.

waiting for server to shut down.... done
server stopped

2. Arrêter le Serveur Primaire

Ensuite, arrêtez le serveur primaire en utilisant la commande service.

sudo service postgresql stop

3. Supprimer les Données et les Journaux de la Réplique

Maintenant que les serveurs sont arrêtés, vous pouvez supprimer en toute sécurité le répertoire de données de la réplique et le fichier journal que vous avez créé. Notez que sudo est requis car ces fichiers appartiennent à l'utilisateur postgres.

sudo rm -rf /var/lib/postgresql/14/replica /tmp/replica.log

Cela achève le processus de nettoyage. Vous avez configuré, testé et démonté avec succès un environnement de réplication par streaming PostgreSQL.

Résumé

Dans ce laboratoire, vous avez configuré avec succès la réplication par streaming de PostgreSQL à partir de zéro. Vous avez appris à préparer un serveur primaire en modifiant postgresql.conf et pg_hba.conf et en créant un utilisateur de réplication dédié. Vous avez ensuite utilisé pg_basebackup pour créer une réplique et l'avez configurée pour s'exécuter sur un port séparé.

En testant la configuration, vous avez vérifié que les données écrites sur le primaire sont automatiquement répliquées sur le serveur secondaire en quasi temps réel. Vous avez également confirmé qu'un serveur réplique est en lecture seule, ce qui est un aspect fondamental de sa conception. Ces compétences sont essentielles pour gérer des déploiements PostgreSQL robustes et évolutifs.