PostgreSQL peut fonctionner séparément sur plusieurs machines avec la même structure de données, rendant la couche de persistance de l'application plus résiliente et préparée à un événement inattendu qui pourrait compromettre la continuité du service.
L'idée sous-jacente est d'améliorer le temps de réponse du système en répartissant les requêtes dans un réseau "Round Robin" où chaque nœud présent est un cluster. Dans ce type de configuration, il n'est pas important de savoir à laquelle les demandes seront envoyées pour être traitées, car la réponse serait toujours la même.
Dans ce blog, nous expliquerons comment répliquer un cluster PostgreSQL en utilisant les outils fournis dans l'installation du programme. La version utilisée est PostgreSQL 11.5, la version actuelle stable et généralement disponible pour le système d'exploitation Debian Buster. Pour les exemples de ce blog, il est supposé que vous êtes déjà familiarisé avec Linux.
Programmes PostgreSQL
Dans le répertoire /usr/bin/ se trouve le programme responsable de la gestion du cluster.
# 1. Lists the files contained in the directory
# 2. Filters the elements that contain 'pg_' in the name
ls /usr/bin/ | grep pg_
Les activités menées par le biais de ces programmes peuvent être exécutées séquentiellement, ou même en combinaison avec d'autres programmes. L'exécution d'un bloc de ces activités via une seule commande est possible grâce à un programme Linux situé dans le même répertoire, appelé make.
Pour lister les clusters présents, utilisez le programme pg_lsclusters. Vous pouvez également utiliser make pour l'exécuter. Son travail dépend d'un fichier nommé Makefile, qui doit se trouver dans le même répertoire où la commande sera exécutée.
# 1. The current directory is checked
pwd
# 2. Creates a directory
mkdir ~/Documents/Severalnines/
# 3. Enroute to the chosen directory
cd ~/Documents/Severalnines/
# 4. Create the file Makefile
touch Makefile
# 5. Open the file for editing
La définition d'un bloc est présentée ci-dessous, ayant pour nom ls, et un seul programme à exécuter, pg_lsclusters.
# 1. Block name
ls:
# 2. Program to be executed
pg_lsclusters
Le fichier Makefile peut contenir plusieurs blocs, et chacun peut exécuter autant de programmes que nécessaire, et même recevoir des paramètres. Il est impératif que les lignes appartenant à un bloc d'exécution soient correctes, en utilisant des tabulations pour l'indentation au lieu d'espaces.
L'utilisation de make pour exécuter le programme pg_lsclusters est accomplie en utilisant la commande make ls.
# 1. Executes pg_lsclusters
make ls
Le résultat obtenu lors d'une installation récente de PostgreSQL apporte un seul cluster appelé main, alloué sur le port 5432 du système d'exploitation. Lorsque le programme pg_createcluster est utilisé, un nouveau port est alloué au nouveau cluster créé, ayant la valeur 5432 comme point de départ, jusqu'à ce qu'un autre soit trouvé dans l'ordre croissant.
Write Ahead Logging (WAL)
Cette procédure de réplication consiste à faire une sauvegarde d'un cluster fonctionnel qui continue à recevoir des mises à jour. Cependant, si cela est fait sur la même machine, de nombreux avantages apportés par cette technique sont perdus.
La mise à l'échelle horizontale d'un système garantit une plus grande disponibilité du service, car si des problèmes matériels se produisaient, cela ne ferait pas beaucoup de différence car il existe d'autres machines prêtes à prendre en charge la charge de travail.
WAL est le terme utilisé pour représenter un algorithme complexe interne à PostgreSQL qui garantit l'intégrité des transactions effectuées sur le système. Cependant, un seul cluster doit avoir la responsabilité d'y accéder avec une autorisation en écriture.
L'architecture dispose désormais de trois types de clusters distincts :
- Un primaire chargé d'écrire à WAL ;
- Une réplique prête à reprendre le poste principal ;
- Divers autres répliques avec devoir de lecture WAL.
Les opérations d'écriture sont toutes les activités destinées à modifier la structure des données, soit en entrant de nouveaux éléments, soit en mettant à jour et en supprimant des enregistrements existants.
Configuration du cluster PostgreSQL
Chaque cluster possède deux répertoires, un contenant ses fichiers de configuration et un autre avec les journaux de transactions. Ils se trouvent respectivement dans /etc/postgresql/11/$(cluster) et /var/lib/postgresql/11/$(cluster) (où $(cluster) est le nom du cluster).
Le fichier postgresql.conf est créé immédiatement après la création du cluster en exécutant le programme pg_createcluster, et les propriétés peuvent être modifiées pour la personnalisation d'un cluster.
La modification directe de ce fichier n'est pas recommandée car il contient presque toutes les propriétés. Leurs valeurs ont été commentées, avec le symbole # au début de chaque ligne, et plusieurs autres lignes commentées contenant des instructions pour modifier les valeurs des propriétés.
L'ajout d'un autre fichier contenant les modifications souhaitées est possible, modifiez simplement une seule propriété nommée include, en remplaçant la valeur par défaut #include ='' par include ='postgresql.replication.conf'.
Avant de démarrer le cluster, vous avez besoin de la présence du fichier postgresql.replication.conf dans le même répertoire où vous trouvez le fichier de configuration d'origine, appelé postgresql.conf.
# 1. Block name
create:
# 2. Creates the cluster
pg_createcluster 11 $(cluster) -- --data-checksums
# 3. Copies the file to the directory
cp postgresql.replication.conf /etc/postgresql/11/$(cluster)/
# 4. A value is assigned to the property
sed -i "s|^#include = ''|include = 'postgresql.replication.conf'|g" /etc/postgresql/11/$(cluster)/postgresql.conf
L'utilisation de --data-checksums dans la création du cluster ajoute un plus grand niveau d'intégrité aux données, coûtant un peu de performance mais étant très important afin d'éviter la corruption des fichiers lorsque transféré d'un cluster à un autre.
Les procédures décrites ci-dessus peuvent être réutilisées pour d'autres clusters, en passant simplement une valeur à $(cluster) comme paramètre dans l'exécution du programme make.
# 1. Executes the block 'create' by passing a parameter
sudo make create cluster=primary
Maintenant qu'une brève automatisation des tâches a été établie, il reste à définir le fichier postgresql.replication.conf en fonction du besoin de chaque cluster.
Réplication sur PostgreSQL
Deux manières de répliquer un cluster sont possibles, l'une étant complète, l'autre impliquant l'ensemble du cluster (appelée Streaming Replication) et une autre pouvant être partielle ou complète (appelée Logical Replication).
Les paramètres qui doivent être spécifiés pour un cluster se répartissent en quatre catégories principales :
- Serveur maître
- Serveurs de secours
- Serveurs d'envoi
- Abonnés
Comme nous l'avons vu précédemment, WAL est un fichier qui contient les transactions qui sont effectuées sur le cluster, et la réplication est la transmission de ces fichiers d'un cluster à un autre.
Dans les paramètres présents dans le fichier postgresql.conf, nous pouvons voir les propriétés qui définissent le comportement du cluster par rapport aux fichiers WAL, comme la taille de ces fichiers.
# default values
max_wal_size = 1GB
min_wal_size = 80MB
Une autre propriété importante appelée max_wal_senders. Appartenir à un cluster avec des serveurs d'envoi caractéristiques, est le nombre de processus chargés d'envoyer ces fichiers à d'autres clusters, ayant toujours une valeur supérieure au nombre de clusters qui dépendent de leur réception.
Les fichiers WAL peuvent être stockés pour être transmis à un cluster qui se connecte tardivement, ou qui a eu des problèmes pour le recevoir, et qui a besoin de fichiers précédents par rapport à l'heure actuelle, ayant la propriété wal_keep_segments comme spécification pour combien de segments de fichiers WAL doivent être maintenus par un cluster.
Un emplacement de réplication est une fonctionnalité qui permet au cluster de stocker les fichiers WAL nécessaires pour fournir à un autre cluster tous les enregistrements, ayant l'option max_replication_slots comme propriété.
# default values
max_wal_senders = 10
wal_keep_segments = 0
max_replication_slots = 10
Lorsque l'intention est d'externaliser le stockage de ces fichiers WAL, une autre méthode de traitement de ces fichiers peut être utilisée, appelée Archivage Continu.
Archivage continu
Ce concept vous permet de diriger les fichiers WAL vers un emplacement spécifique, en utilisant un programme Linux, et deux variables représentant le chemin du fichier, et son nom, comme %p, et %f, respectivement.
Cette propriété est désactivée par défaut, mais son utilisation peut être facilement mise en œuvre en retirant la responsabilité d'un cluster de stocker des fichiers aussi importants, et peut être ajoutée au fichier postgresql.replication.conf.
# 1. Creates a directory
mkdir ~/Documents/Severalnines/Archiving
# 2. Implementation on postgresql.replication.conf
archive_mode = on
archive_command = 'cp %p ~/Documents/Severalnines/Archiving/%f'
# 3. Starts the cluster
sudo systemctl start [email protected]
Après l'initialisation du cluster, certaines propriétés peuvent devoir être modifiées et un redémarrage du cluster peut être nécessaire. Cependant, certaines propriétés peuvent uniquement être rechargées, sans qu'il soit nécessaire de redémarrer complètement un cluster.
Des informations sur ces sujets peuvent être obtenues via les commentaires présents dans le fichier postgresql.conf, apparaissant sous la forme # (note :la modification nécessite un redémarrage).
Si tel est le cas, une solution simple consiste à utiliser le programme Linux systemctl, utilisé précédemment pour démarrer le cluster, en n'ayant qu'à remplacer l'option de redémarrage.
Lorsqu'un redémarrage complet n'est pas requis, le cluster lui-même peut réaffecter ses propriétés via une requête exécutée en lui-même, cependant, si plusieurs clusters s'exécutent sur la même machine, il sera nécessaire de transmettre un paramètre contenant la valeur du port alloué au cluster sur le système d'exploitation.
# Reload without restarting
sudo -H -u postgres psql -c ‘SELECT pg_reload_conf();’ -p 5433
Dans l'exemple ci-dessus, la propriété archive_mode nécessite un redémarrage, contrairement à archive_command. Après cette brève introduction à ce sujet, regardons comment un cluster de répliques peut sauvegarder ces fichiers WAL archivés, en utilisant Point In Time Recovery (PITR).
Récupération ponctuelle de la réplication PostgreSQL
Ce nom évocateur permet à un cluster de revenir à son état à partir d'un certain laps de temps. Cela se fait via une propriété appelée recovery_target_timeline, qui s'attend à recevoir une valeur au format de date, telle que 2019-08-22 12:05 GMT, ou la dernière affectation, informant de la nécessité d'une récupération jusqu'au dernier enregistrement existant.
Le programme pg_basebackup lorsqu'il s'exécute, fait une copie d'un répertoire contenant les données d'un cluster vers un autre emplacement. Ce programme a tendance à recevoir plusieurs paramètres, dont l'un -R, qui crée un fichier nommé recovery.conf dans le répertoire copié, qui à son tour n'est pas le même que celui contenant les autres fichiers de configuration vus précédemment, tels que postgresql.conf .
Le fichier recovery.conf stocke les paramètres passés à l'exécution du programme pg_basebackup, et son existence est essentielle à la mise en place de la Streaming Replication, car c'est en son sein que l'opération inverse à l'Archivage Continu peut être effectuée.
# 1. Block name
replicate:
# 2. Removes the current data directory
rm -rf /var/lib/postgresql/11/$(replica)
# 3. Connects to primary cluster as user postgres
# 4. Copies the entire data directory
# 5. Creates the file recovery.conf
pg_basebackup -U postgres -d postgresql://localhost:$(primaryPort) -D /var/lib/postgresql/11/$(replica) -P -R
# 6. Inserts the restore_command property and its value
echo "restore_command = 'cp ~/Documents/Severalnines/Archiving/%f %p'" >> /var/lib/postgresql/11/$(replica)/recovery.conf
# 7. The same is done with recovery_target_timeline
echo "recovery_target_timeline = 'latest'" >> /var/lib/postgresql/11/$(replica)/recovery.conf
Ce bloc répliqué spécifié ci-dessus doit être exécuté par l'utilisateur postgres du système d'exploitation, afin d'éviter les conflits potentiels avec qui est le propriétaire des données du cluster, postgres ou l'utilisateur root.
Le cluster de répliques est toujours debout, l'arrosant pour démarrer avec succès la réplication, le processus de cluster de répliques appelé pg_walreceiver interagissant avec le cluster principal appelé pg_walsender via une connexion TCP.
# 1. Executes the block ‘replicate’ by passing two parameters
sudo -H -u postgres make replicate replica=replica primaryPort=5433
# 2. Starts the cluster replica
sudo systemctl start [email protected]
La vérification de l'intégrité de ce modèle de réplication, appelé Streaming Replication, est effectuée par une requête exécutée sur le cluster principal.
# 1. Checks the Streaming Replication created
sudo -H -u postgres psql -x -c ‘select * from pg_stat_replication;’ -p 5433
Conclusion
Dans ce blog, nous avons montré comment configurer la réplication en continu asynchrone entre deux clusters PostgreSQL. Rappelez-vous cependant que des vulnérabilités existent dans le code ci-dessus, par exemple, l'utilisation de l'utilisateur postgres pour effectuer une telle tâche n'est pas recommandée.
La réplication d'un cluster offre plusieurs avantages lorsqu'il est utilisé correctement et a un accès facile aux API qui viennent interagir avec les clusters.