Réplication de Base de Données
← Retour au Guide des Opérations
Table des Matières
- Aperçu
- Comment Cela Fonctionne
- Architectures de Déploiement
- Référence de Configuration
- Gestion des Pairs
- Surveillance
- Dépannage
Aperçu
OmniHSS utilise PostgreSQL avec réplication logique bidirectionnelle pour des déploiements multi-sites à haute disponibilité. Chaque site fonctionne comme un primaire en lecture/écriture indépendant — il n'y a pas de maître unique ou de répliques en lecture seule.
Caractéristiques Clés
- Les Deux Sites en Lecture/Écriture : Chaque site a une base de données primaire complète. Les écritures locales sont instantanées, quelle que soit la qualité du lien inter-site
- Réplication Asynchrone : Les modifications se répliquent via le Write-Ahead Log (WAL) de PostgreSQL. Aucune écriture n'est bloquée en attendant qu'un site distant accuse réception
- Tolérant aux Partitions : Si le lien inter-site tombe, les deux sites continuent de fonctionner indépendamment. Les segments WAL s'accumulent localement et se rejouent automatiquement lorsque le lien se rétablit
- Pas de Quorum Requis : Contrairement aux approches de cluster synchrones, il n'y a pas de concept de quorum. Un déploiement sur un seul site fonctionne de la même manière qu'un déploiement multi-sites
- Clés Primaires UUID : Tous les enregistrements utilisent des clés primaires UUIDv4, éliminant les collisions d'ID entre les sites sans coordination
Comment Cela Diffère de la Réplication Synchrone
| Synchrone | Réplication Logique Asynchrone | |
|---|---|---|
| Latence d'écriture | Bloquée par le nœud le plus lent | Local uniquement — sous-millisecondes |
| Échec du lien | Le site minoritaire devient en lecture seule | Les deux sites continuent en lecture/écriture |
| Quorum nécessaire | Oui (majorité des nœuds) | Non |
| Cohérence des données | Forte (tous les nœuds identiques) | Éventuelle (brève latence de réplication) |
| Adapté aux liens satellites | Non (la latence nuit à la performance d'écriture) | Oui (les files d'attente WAL se rattrapent) |
Comment Cela Fonctionne
Flux de Réplication Logique
Modèle de Publication / Abonnement
Chaque site a :
- Une publication qui diffuse tous les changements de table (sauf
schema_migrations) - Une abonnement à la publication de chaque site pair
Mise en File d'Attente WAL Pendant une Panne de Lien
Lorsque le lien inter-site n'est pas disponible :
- Les écritures locales continuent sans interruption
- Les segments WAL s'accumulent du côté de la publication
- Le slot de réplication suit où chaque abonné s'est arrêté
- Lorsque le lien se rétablit, le WAL en file d'attente se rejoue depuis la dernière position reconnue
- Les deux sites convergent vers un état identique
La rétention WAL est limitée par max_slot_wal_keep_size pour éviter une croissance illimitée du disque pendant des pannes prolongées.
Prévention des Conflits
Les clés primaires UUID éliminent la principale source de conflits dans la réplication bidirectionnelle. Étant donné que chaque site génère des identifiants uniques globalement de manière indépendante, les opérations INSERT ne se chevauchent jamais.
L'option d'abonnement origin = none empêche les boucles de réplication — les changements arrivés par réplication ne sont pas republés à d'autres abonnés.
La table schema_migrations est exclue des publications car les deux sites exécutent des migrations identiques de manière indépendante.
Dernière Écriture Gagne pour l'État Dynamique
Les tables d'état dynamique (subscriber_state, pdn_session, lte_call) sont mises à jour fréquemment par le signalement Diameter — chaque ULR met à jour le MME de service, chaque CCR met à jour la session PGW, chaque AAR met à jour l'appel actif.
Dans un déploiement multi-sites, un abonné est servi par un site à la fois. Lorsque l'abonné se déplace entre les sites, les deux sites peuvent avoir des mises à jour de la même ligne subscriber_state à des moments différents. Sans résolution de conflit, l'ordre de réplication déterminerait quelle valeur survit — potentiellement en écrasant le MME de service actuel avec une valeur obsolète.
OmniHSS utilise des triggers Last-Write-Wins (LWW) sur les tables d'état dynamique :
CREATE TRIGGER lww_subscriber_state_trigger
BEFORE UPDATE ON subscriber_state
FOR EACH ROW
EXECUTE FUNCTION lww_subscriber_state();
Le trigger compare le timestamp updated_at de la mise à jour répliquée entrante avec la ligne existante. Si la ligne existante est plus récente, la mise à jour est silencieusement supprimée. Cela garantit :
- Lorsque un abonné passe du Site A au Site B, la mise à jour plus récente du Site B l'emporte toujours
- Les mises à jour obsolètes du Site A (d'avant le déplacement de l'abonné) sont rejetées
- Les deux sites convergent vers la même valeur — la plus récente écriture
Tables avec triggers LWW :
| Table | Mis à Jour Par | Fréquence |
|---|---|---|
subscriber_state | ULR, SAR, AIR, PUR | Chaque mise à jour d'attachement/localisation |
pdn_session | CCR-I, CCR-T | Chaque création/suppression de session PDN |
lte_call | AAR, STR | Chaque configuration/démontage d'appel VoLTE |
Les données de provisionnement statiques (abonnés, profils, clés, APNs) n'ont pas besoin de LWW — celles-ci ne sont mises à jour que par l'API de provisionnement, généralement à partir d'un seul plan de gestion.
Architectures de Déploiement
Site Unique (Pas de Réplication)
Plusieurs instances d'application HSS partagent une seule base de données PostgreSQL. La réplication de streaming PostgreSQL standard peut être utilisée pour un basculement de base de données local si nécessaire.
Déploiement à Deux Sites
Les deux sites sont des primaires complets. La provisionnement des abonnés sur n'importe quel site se réplique à l'autre. Chaque MME se connecte à son HSS local — il n'y a pas de dépendance Diameter inter-site.
Déploiement Multi-Sites
Chaque site s'abonne à la publication de chaque autre site. Les pairs sont auto-découverts à partir de l'inventaire Ansible — ajouter un site nécessite seulement de l'ajouter au groupe d'inventaire hss et d'exécuter le playbook.
Exigences Réseau
| Port | Protocole | Objectif |
|---|---|---|
| 5432 | TCP | Connexions client et de réplication PostgreSQL |
Référence de Configuration
Variables Ansible
La réplication est configurée par groupe HSS dans votre inventaire :
hss:
hosts:
site-a-hss01:
ansible_host: 10.80.12.140
site-a-hss02:
ansible_host: 10.80.12.141
vars:
omnihss:
database_type: postgres
database_host: localhost
database_port: 5432
database_name: omnihss
database_username: omnihss
database_password: "secure_password"
replication:
enabled: true
Paramètres Ansible
| Paramètre | Type | Requis | Par Défaut | Description |
|---|---|---|---|---|
database_type | String | Non | postgres | Backend de base de données. Doit être postgres pour la réplication. |
database_host | String | Non | localhost | Hôte PostgreSQL. Utilisez localhost lorsque Postgres s'exécute sur le même hôte qu'OmniHSS. |
database_port | Entier | Non | 5432 | Port PostgreSQL. |
database_name | String | Non | omnihss | Nom de la base de données. |
database_username | String | Oui | - | Utilisateur PostgreSQL. Doit avoir les privilèges CREATEDB et REPLICATION. |
database_password | String | Oui | - | Mot de passe PostgreSQL. |
replication.enabled | Booléen | Non | false | Activer la réplication logique bidirectionnelle. Lorsque true, le rôle Ansible configure automatiquement les publications, abonnements et entrées pg_hba.conf. |
Découverte des Pairs
Les pairs sont découverts automatiquement à partir de deux sources :
- Groupe d'inventaire local : Tous les autres hôtes dans le groupe Ansible
hss - Sites distants : Entrées dans
connected_sites.hssà partir deprod_master_peers.yml
Aucune configuration de pair par hôte n'est requise. Ajouter un hôte au groupe hss ou à connected_sites.hss et exécuter le playbook est suffisant.
Pairs de Sites Distants (prod_master_peers.yml)
Pour la réplication inter-site à travers des emplacements géographiques :
# group_vars/prod_master_peers.yml
connected_sites:
hss:
- remote-site-hss01: 10.80.20.140
- remote-site-hss02: 10.80.20.141
Configuration PostgreSQL
Le rôle Ansible configure automatiquement les paramètres PostgreSQL suivants lorsque la réplication est activée :
| Paramètre | Valeur | Objectif |
|---|---|---|
wal_level | logical | Requis pour la réplication logique. Inclut les données complètes des lignes dans le WAL. |
max_wal_senders | 10 | Maximum de processus d'envoi WAL simultanés (un par abonné). |
max_replication_slots | 10 | Maximum de slots de réplication. Chaque pair utilise un slot. |
listen_addresses | * | Accepter les connexions des sites pairs. |
Le rôle ajoute également des entrées pg_hba.conf pour permettre les connexions de réplication à partir de chaque IP de pair découverte.
Gestion des Pairs
Ajout d'un Nouveau Site
- Ajoutez le(s) nouvel(s) hôte(s) au groupe d'inventaire
hss, ou ajoutez-le àconnected_sites.hssdansprod_master_peers.yml - Exécutez le playbook OmniHSS
Le rôle va :
- Installer PostgreSQL et OmniHSS sur le nouvel hôte
- Exécuter les migrations de base de données
- Créer une publication pour le nouveau site
- Créer des abonnements à tous les pairs existants
- Mettre à jour
pg_hba.confsur tous les pairs existants pour permettre le nouveau site - Créer des abonnements des pairs existants vers le nouveau site
Suppression d'un Site
ansible-playbook -i hosts site.yml --tags hss-remove-peer \
-e "peer_name=sydney confirm_remove=yes"
Le paramètre confirm_remove=yes est requis comme mesure de sécurité. Sans cela, le playbook refuse de continuer et affiche ce qui se passerait.
La suppression d'un pair :
- Supprime l'abonnement (arrête la réplication entrante de ce pair)
- Supprime l'IP du pair de
pg_hba.conf - Les données déjà répliquées du pair restent dans la base de données locale
- L'abonnement du site pair à ce site doit être supprimé séparément sur le pair
Ajout d'un Pair Ad-Hoc
Pour les cas où vous devez ajouter un pair en dehors du flux standard du playbook :
ansible-playbook -i hosts site.yml --tags hss-add-peer \
-e "peer_name=sydney peer_host=10.80.20.140"
Surveillance
Métriques Prometheus
Le service postgres_exporter s'exécute sur chaque hôte HSS sur le port 9187, exposant les métriques PostgreSQL à Prometheus.
Métriques de Réplication
| Métrique | Type | Description |
|---|---|---|
pg_replication_slots_active | Gauge | 1 si le slot de réplication est actif (pair connecté), 0 si inactif |
pg_replication_slots_pg_wal_lsn_diff | Gauge | Latence de réplication en octets. Distance entre la position WAL actuelle et la dernière position confirmée du pair |
pg_stat_replication_pg_current_wal_lsn_bytes | Gauge | Position WAL actuelle sur ce nœud |
Exemples de Requêtes Prometheus
# Slot de réplication actif (1 = connecté, 0 = déconnecté)
pg_replication_slots_active{slot_name=~"sub_from_.*"}
# Latence de réplication en mégaoctets
pg_replication_slots_pg_wal_lsn_diff / 1048576
# Alerte : slot de réplication inactif pendant plus de 60 secondes
pg_replication_slots_active == 0
Alertes Recommandées
| Alerte | Condition | Sévérité | Description |
|---|---|---|---|
| Slot de Réplication Inactif | pg_replication_slots_active == 0 pendant 60s | Critique | Le pair est déconnecté. Le WAL s'accumule. |
| Latence WAL Excessive | pg_replication_slots_pg_wal_lsn_diff > 104857600 pendant 5m | Avertissement | La latence de réplication dépasse 100 Mo. Le pair peut être lent ou le lien dégradé. |
| Slot WAL Perdu | Le statut WAL est lost | Critique | Le slot a été invalidé. Le pair nécessite un re-seeding complet. |
Validation Ansible
Le playbook OmniHSS valide la santé de la réplication à la fin de chaque exécution. Il vérifie :
- Tous les travailleurs d'abonnement sont en vie
- Tous les slots de réplication sont actifs
- La latence WAL est dans le seuil (100 Mo par défaut)
- Le statut du slot WAL est
reservedouextended(paslost)
Si une assertion échoue, le playbook échoue avec un message d'erreur clair identifiant le problème.
Validation Manuelle
# Vérifiez que les travailleurs d'abonnement sont en vie
sudo -u postgres psql -d omnihss -c \
"SELECT subname, pid IS NOT NULL as worker_alive FROM pg_stat_subscription;"
# Vérifiez les slots de réplication et la latence
sudo -u postgres psql -d omnihss -c \
"SELECT slot_name, active,
pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn) as lag_bytes,
wal_status
FROM pg_replication_slots WHERE slot_type = 'logical';"
# Comparez les comptes d'abonnés entre les sites
sudo -u postgres psql -d omnihss -c "SELECT count(*) FROM subscriber;"
Dépannage
Travailleur d'Abonnement Mort
Symptômes : pg_stat_subscription montre pid IS NULL pour un abonnement. La validation Ansible échoue avec "Travailleurs morts."
Causes Courantes :
- La table existe sur le publieur mais pas sur l'abonné (incompatibilité DDL)
- Conflit de clé dupliquée d'un enregistrement inséré manuellement
- Pair injoignable pendant une période prolongée causant l'invalidation du slot WAL
Résolution :
- Vérifiez les journaux PostgreSQL pour l'erreur spécifique :
journalctl -u postgresql | grep "logical replication" | tail -20 - Si incompatibilité DDL : appliquez la migration manquante sur ce site, puis le travailleur redémarrera automatiquement
- Si clé dupliquée : résolvez le conflit manuellement, puis réactivez l'abonnement :
ALTER SUBSCRIPTION sub_from_<pair> ENABLE;
Slot de Réplication Inactif
Symptômes : pg_replication_slots montre active = false. L'alerte Prometheus se déclenche.
Causes Courantes :
- Problème de connectivité réseau entre les sites
- PostgreSQL sur le site pair est arrêté
- Pare-feu bloquant le port 5432 depuis l'IP du pair
Résolution :
- Vérifiez la connectivité réseau avec le pair :
pg_isready -h <peer_ip> -U <db_user> -d omnihss - Vérifiez que PostgreSQL sur le site pair est en cours d'exécution
- Vérifiez que les règles de pare-feu autorisent le port 5432 depuis l'IP de ce site
Le travailleur d'abonnement se reconnectera automatiquement lorsque le pair redeviendra joignable.
Slot WAL Perdu
Symptômes : pg_replication_slots montre wal_status = 'lost'. La validation Ansible échoue avec "WAL SLOT CRITIQUE."
Cause : Le pair a été déconnecté si longtemps que le WAL conservé a dépassé max_slot_wal_keep_size et a été nettoyé.
Résolution : Le pair nécessite un re-seeding complet :
- Supprimez l'abonnement cassé sur ce site :
DROP SUBSCRIPTION sub_from_<pair>; - Supprimez le slot cassé sur le site pair :
SELECT pg_drop_replication_slot('sub_from_<this_site>'); - Réexécutez le playbook OmniHSS — il recréera l'abonnement avec
copy_data = truepour effectuer une synchronisation initiale.
Latence WAL Excessive
Symptômes : pg_replication_slots_pg_wal_lsn_diff est grand et en croissance. L'alerte Prometheus se déclenche.
Causes Courantes :
- Lien inter-site à haute latence ou congestionné
- Site pair sous forte charge (le travailleur d'application ne peut pas suivre)
- Grande opération en bloc (par exemple, provisionnement de masse) générant un volume WAL significatif
Résolution :
- Vérifiez si la latence est en croissance ou stable :
SELECT slot_name,
pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn) as lag_bytes
FROM pg_replication_slots WHERE slot_type = 'logical'; - Si stable : le pair applique des changements mais est en retard. Il rattrapera.
- Si en croissance : enquêtez sur le lien réseau ou la charge du site pair.
- Pour les opérations en bloc : la latence pendant l'opération est attendue et se résoudra après la fin de l'opération.
Coordination des Migrations de Schéma
Important : Les changements de schéma de base de données (migrations) ne se répliquent pas via la réplication logique. Lors du déploiement d'une nouvelle version d'OmniHSS qui inclut des changements de schéma :
- Appliquez la migration sur tous les sites avant de déployer le code de l'application qui dépend des nouvelles colonnes/tables
- Le playbook Ansible gère cela automatiquement — il exécute des migrations sur chaque hôte
- Si vous déployez manuellement, exécutez les migrations sur tous les sites d'abord :
/opt/omnihss/bin/hss rpc "Hss.Command.Database.migrate()"