PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 10.19 » Administration du serveur » Haute disponibilité, répartition de charge et réplication » Comparaison de différentes solutions

26.1. Comparaison de différentes solutions

Failover sur disque partagé

Le failover (ou bascule sur incident) sur disque partagé élimine la surcharge de synchronisation par l'existence d'une seule copie de la base de données. Il utilise un seul ensemble de disques partagé par plusieurs serveurs. Si le serveur principal échoue, le serveur en attente est capable de monter et démarrer la base comme s'il récupérait d'un arrêt brutal. Cela permet un failover rapide sans perte de données.

La fonctionnalité de matériel partagé est commune aux périphériques de stockage en réseau. Il est également possible d'utiliser un système de fichiers réseau bien qu'il faille porter une grande attention au système de fichiers pour s'assurer qu'il a un comportement POSIX complet (voir Section 18.2.2). Cette méthode comporte une limitation significative : si les disques ont un problème ou sont corrompus, le serveur primaire et le serveur en attente sont tous les deux non fonctionnels. Un autre problème est que le serveur en attente ne devra jamais accéder au stockage partagé tant que le serveur principal est en cours d'exécution.

Réplication de système de fichiers (périphérique bloc)

Il est aussi possible d'utiliser cette fonctionnalité d'une autre façon avec une réplication du système de fichiers, où toutes les modifications d'un système de fichiers sont renvoyées sur un système de fichiers situé sur un autre ordinateur. La seule restriction est que ce miroir doit être construit de telle sorte que le serveur en attente dispose d'une version cohérente du système de fichiers -- spécifiquement, les écritures sur le serveur en attente doivent être réalisées dans le même ordre que celles sur le primaire. DRBD est une solution populaire de réplication de systèmes de fichiers pour Linux.

Envoi des journaux de transactions

Les serveurs warm et hot standby (voir Section 26.2) peuvent conserver leur cohérence en lisant un flux d'enregistrements de WAL. Si le serveur principal échoue, le serveur standby contient pratiquement toutes les données du serveur principal et peut rapidement devenir le nouveau serveur primaire. Ça peut être synchrone mais ça ne peut se faire que pour le serveur de bases complet.

Un serveur de standby peut être implémenté en utilisant la recopie de journaux par fichier (Section 26.2) ou la streaming replication (réplication en continu, voir Section 26.2.5), ou une combinaison des deux. Pour des informations sur le hot standby, voyez Section 26.5..

Logical Replication

La réplication logique autorise un serveur de bases de données d'envoyer un flux de modifications de données à un autre serveur. La réplication logique de PostgreSQL construit un flux de modifications logiques de données à partir des journaux de transactions. La réplication logique permet la réplication des modifications de données de tables individuelles. La réplication logique ne requiert pas qu'un serveur particulier soit désigné comme serveur primaire ou secondaire, mais autorise le flux de données dans plusieurs directions. Pour plus d'informations sur la réplication logique, voir Chapitre 31. Au travers de l'interface de décodage logique (Chapitre 48), les extensions tierces peuvent aussi fournir des fonctionnalitées similaires.

Réplication primaire/secondaire basé sur des triggers

Une configuration de réplication primaire/secondaire envoie toutes les requêtes de modification de données au serveur primaire. Ce serveur envoie les modifications de données de façon asynchrone au serveur secondaire. Le secondaire peut répondre aux requêtes en lecture seule alors que le serveur primaire est en cours d'exécution. Le serveur secondaire est idéal pour les requêtes vers un entrepôt de données.

Slony-I est un exemple de ce type de réplication, avec une granularité par table et un support des secondaires multiples. Comme il met à jour le serveur secondaire de façon asynchrone (par lots), il existe une possibilité de perte de données pendant un failover.

Middleware de réplication basé sur les instructions

Avec les middleware de réplication basés sur les instructions, un programme intercepte chaque requête SQL et l'envoie à un ou tous les serveurs. Chaque serveur opère indépendamment. Les requêtes en lecture/écriture doivent être envoyées à tous les serveurs pour que chaque serveur reçoive les modifications. Les requêtes en lecture seule ne peuvent être envoyées qu'à un seul serveur, ce qui permet de distribuer la charge de lecture.

Si les requêtes sont envoyées sans modification, les fonctions comme random(), CURRENT_TIMESTAMP ainsi que les séquences ont des valeurs différentes sur les différents serveurs. Cela parce que chaque serveur opère indépendamment alors que les requêtes SQL sont diffusées (et non les données modifiées). Si cette solution est inacceptable, le middleware ou l'application doivent demander ces valeurs à un seul serveur, et les utiliser dans des requêtes d'écriture. Une autre solution est d'utiliser cette solution de réplication avec une configuration primaire-secondaire traditionnelle, c'est à dire que les requêtes de modification de données ne sont envoyées qu'au primaire et sont propagées aux secondaires via une réplication primaire-secondaire, pas par le middleware de réplication. Il est impératif que toute transaction soit validée ou annulée sur tous les serveurs, éventuellement par validation en deux phases (PREPARE TRANSACTION et COMMIT PREPARED). Pgpool-II et Continuent Tungsten sont des exemples de ce type de réplication.

Réplication asynchrone multi-primaires

Pour les serveurs qui ne sont pas connectés en permanence ou qui ont des liens de communication lents, comme les ordinateurs portables ou les serveurs distants, conserver la cohérence des données entre les serveurs est un challenge. L'utilisation de la réplication asynchrone multi-primaires permet à chaque serveur de fonctionner indépendamment. Il communique alors périodiquement avec les autres serveurs pour identifier les transactions conflictuelles. La gestion des conflits est alors confiée aux utilisateurs ou à un système de règles de résolution. Bucardo est un exemple de ce type de réplication.

Réplication synchrone multi-primaires

Dans les réplications synchrones multi-primaires, tous les serveurs acceptent les requêtes en écriture. Les données modifiées sont transmises du serveur d'origine à tous les autres serveurs avant toute validation de transaction.

Une activité importante en écriture peut être la cause d'un verrouillage excessif et de délai dans la validation des transactions, ce qui peut conduire à un effondrement des performances. Dans les faits, les performances en écriture sont souvent pis que celles d'un simple serveur.

Tous les serveurs acceptent les requêtes en lecture.

Certaines implantations utilisent les disques partagés pour réduire la surcharge de communication.

Les performances de la réplication synchrone multi-primaires sont meilleures lorsque les opérations de lecture représentent l'essentiel de la charge, alors que son gros avantage est l'acceptation des requêtes d'écriture par tous les serveurs -- il n'est pas nécessaire de répartir la charge entre les serveurs primaires et secondaires et, parce que les modifications de données sont envoyées d'un serveur à l'autre, les fonctions non déterministes, comme random(), ne posent aucun problème.

PostgreSQL n'offre pas ce type de réplication, mais la validation en deux phases de PostgreSQL (PREPARE TRANSACTION et COMMIT PREPARED) autorise son intégration dans une application ou un middleware.

Solutions commerciales

Parce que PostgreSQL est libre et facilement extensible, certaines sociétés utilisent PostgreSQL dans des solutions commerciales fermées (closed-source) proposant des fonctionnalités de bascule sur incident (failover), réplication et répartition de charge.

La Tableau 26.1 résume les possibilités des différentes solutions listées plus-haut.

Tableau 26.1. Matrice de fonctionnalités : haute disponibilité, répartition de charge et réplication

FonctionnalitéBascule par disques partagés (Shared Disk Failover)Réplication par système de fichiersEnvoi des journaux de transactionsRéplication logiqueRéplication primaire/secondaire basé sur les triggersMiddleware de réplication sur instructionsRéplication asynchrone multi-primairesRéplication synchrone multi-primaires
Exemple d'implémentationsNASDRBDréplication en flux interneréplication logique interne, pglogicalLondiste, Slonypgpool-IIBucardo 
Méthode de communicationDisque partagéBlocs disqueWALdécodage logiqueLignes de tablesSQLLignes de tablesLignes de tables et verrous de ligne
Ne requiert aucun matériel spécial 
Autorise plusieurs serveurs primaires    
Pas de surcharge sur le serveur primaire    
Pas d'attente entre serveurs with sync offwith sync off  
Pas de perte de données en cas de panne du primairewith sync onwith sync on  
Les secondaires acceptent les requêtes en lecture seule  avec un hot standby
Granularité de niveau table    
Ne nécessite pas de résolution de conflit  

Certaines solutions n'entrent pas dans les catégories ci-dessus :

Partitionnement de données

Le partitionnement des données divise les tables en ensembles de données. Chaque ensemble ne peut être modifié que par un seul serveur. Les données peuvent ainsi être partitionnées par bureau, Londres et Paris, par exemple, avec un serveur dans chaque bureau. Si certaines requêtes doivent combiner des données de Londres et Paris, il est possible d'utiliser une application qui requête les deux serveurs ou d'implanter une réplication primaire/secondaire pour conserver sur chaque serveur une copie en lecture seule des données de l'autre bureau.

Exécution de requêtes en parallèle sur plusieurs serveurs

La plupart des solutions ci-dessus permettent à plusieurs serveurs de répondre à des requêtes multiples, mais aucune ne permet à une seule requête d'être exécutée sur plusieurs serveurs pour se terminer plus rapidement. Cette solution autorisent plusieurs serveurs à travailler ensemble sur une seule requête. Ceci s'accomplit habituellement en répartissant les données entre les serveurs, chaque serveur exécutant une partie de la requête pour renvoyer les résultats à un serveur central qui les combine et les renvoie à l'utilisateur. Cela peut également se faire en utilisant PL/Proxy.