Cloud
Azure PostgreSQL : diagnostiquer le lag d'une read replica avant promotion
Un runbook de production pour qualifier le lag d'une read replica Azure Database for PostgreSQL, prouver le RPO atteignable et choisir réparation, switchover planifié ou promotion forcée.
Une read replica interrégion est prête pour la reprise d’activité, mais son retard augmente alors que le primaire accepte toujours les écritures. Le réflexe est souvent de la promouvoir rapidement, de la scaler ou de la recréer. Ces actions ne corrigent pas le même problème. Une promotion forcée peut rendre un serveur inscriptible plus vite, mais toute transaction absente de la replica matérialise une perte de données.
Le cas d’usage est un serveur Azure Database for PostgreSQL Flexible Server répliqué de façon asynchrone pour le reporting ou la reprise régionale. Ce runbook qualifie le chemin de réplication, prouve le point de reprise réellement disponible et aboutit à une décision explicite : attendre le rattrapage, corriger la pression, effectuer un switchover planifié, forcer la promotion avec un RPO accepté ou reconstruire la replica sans la promouvoir.
Figer le contrat de promotion
Ne commencez pas par le bouton Promote. Notez la topologie et ce que l’application doit trouver après l’opération. Promouvoir vers un serveur autonome et inverser les rôles primaire-replica sont deux changements différents.
incident:
started_at_utc: 2026-08-30T05:40:00Z
primary_server: pg-orders-prod-we
candidate_replica: pg-orders-dr-ne
primary_region: westeurope
replica_region: northeurope
workload: orders-api
role: reporting-and-disaster-recovery
observed:
replica_lag_seconds: <measured-value>
max_physical_lag_bytes: <measured-value>
primary_transaction_log_storage: <measured-value>
primary_write_available: true-or-false
replica_read_available: true-or-false
replication_state: <state>
promotion_contract:
mode: switchover-or-standalone
option: planned-or-forced
maximum_accepted_rpo: <seconds-and-business-marker>
maximum_accepted_rto: <minutes>
writer_virtual_endpoint: <fqdn-or-none>
reader_virtual_endpoint: <fqdn-or-none>
decision_owner: <role>
application_validation: <probe>
stop_conditions:
- replication evidence is unavailable
- replica data point is older than accepted RPO
- target authentication or network policy is untested
- client connection target after promotion is ambiguous La promotion ne réussit pas simplement parce que la cible devient inscriptible. Application, identités, DNS ou virtual endpoints, règles réseau, paramètres et supervision doivent tous désigner un primaire cohérent.
Lire le lag en secondes et en octets
Azure expose Read Replica Lag sur la replica en secondes et Max Physical Replication Lag sur le primaire en octets. Ces signaux répondent à des questions différentes. Les secondes estiment l’ancienneté de la dernière transaction rejouée. Les octets mesurent la distance WAL avec la replica connectée la plus en retard.
Une base calme peut afficher un temps croissant depuis la dernière transaction rejouée alors qu’aucune nouvelle donnée n’attend. À l’inverse, un flux d’écriture soutenu produit rapidement un écart important en octets. Lisez les deux dimensions avec le débit d’écriture et l’état de réplication.
PRIMARY_ID="<primary-resource-id>"
REPLICA_ID="<replica-resource-id>"
START="2026-08-30T05:30:00Z"
END="2026-08-30T06:30:00Z"
az monitor metrics list --resource "$REPLICA_ID" --metric physical_replication_delay_in_seconds --interval PT1M --start-time "$START" --end-time "$END" --aggregation Maximum Average --output json
az monitor metrics list --resource "$PRIMARY_ID" --metric physical_replication_delay_in_bytes storage_percent --interval PT1M --start-time "$START" --end-time "$END" --aggregation Maximum Average --output json Conservez aussi Transaction Log Storage Used, CPU, IOPS et bande passante disque sur la même fenêtre. Un écart en octets qui progresse avec des I/O saturées sur la replica indique une limite de replay. Une empreinte WAL croissante sur le primaire montre que l’attente a un coût même si les requêtes y réussissent encore.
Vérifier l’état de réplication dans PostgreSQL
Les métriques de plateforme donnent la tendance. Les vues PostgreSQL montrent si le WAL est envoyé, reçu, flushé et rejoué. Exécutez la première requête sur le primaire avec une identité de diagnostic suffisamment autorisée.
select
application_name,
client_addr,
state,
sync_state,
sent_lsn,
write_lsn,
flush_lsn,
replay_lsn,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) as replay_gap,
write_lag,
flush_lag,
replay_lag
from pg_stat_replication
order by application_name; Sur la replica candidate, prouvez qu’elle reste en recovery et capturez ses positions de réception et de replay.
select
pg_is_in_recovery() as is_replica,
pg_last_wal_receive_lsn() as receive_lsn,
pg_last_wal_replay_lsn() as replay_lsn,
pg_size_pretty(
pg_wal_lsn_diff(
pg_last_wal_receive_lsn(),
pg_last_wal_replay_lsn()
)
) as local_replay_gap,
pg_last_xact_replay_timestamp() as last_replayed_transaction,
now() - pg_last_xact_replay_timestamp() as replay_age; Les colonnes de lag peuvent être null pendant une période sans activité, et un timestamp seul ne prouve pas une perte. Corrélez les LSN avec un marqueur métier connu ou une écriture contrôlée avant de prendre une décision de RPO.
Localiser la pression avant de scaler
Séparez quatre familles de causes :
- le primaire génère soudainement plus de WAL à cause d’un batch, d’un index, d’un import massif, d’une pression de vacuum ou d’une release ;
- la replica ne reçoit ou ne rejoue pas assez vite à cause du compute, des IOPS, de la bande passante disque ou du chemin réseau ;
- les requêtes de reporting sur la replica concurrencent le recovery ou provoquent des conflits répétés ;
- le lien ou le slot de réplication est dégradé et le service utilise un mécanisme de rattrapage plus lent.
Comparez le début du lag avec les déploiements, jobs, changements de schéma et horaires de reporting. Scaler le primaire peut augmenter la production de WAL. Scaler uniquement la replica n’aide que si sa capacité de replay est le facteur limitant. N’annulez une requête de reporting que si les preuves la relient à la pression et si son owner accepte l’interruption.
Ne réduisez pas de paramètres sur une replica en retard. La dérive de configuration entre primaire et replica compte aussi pour la promotion : mode d’authentification et paramètres serveur ne deviennent pas corrects automatiquement lorsque les rôles changent.
Protéger le primaire du WAL retenu
Les read replicas reposent sur la rétention du WAL. Une replica durablement en retard ou inactive peut accumuler les transaction logs sur le primaire. La pression de stockage menace alors le service inscriptible que la réplication devait protéger.
L’ordre de containment est le suivant :
- arrêter ou réduire le batch ou le reporting identifié lorsque l’exploitation le permet ;
- conserver métriques, LSN, sessions actives et état de réplication ;
- augmenter la capacité de la replica uniquement si la saturation est prouvée ;
- surveiller stockage primaire et transaction logs pendant le rattrapage ;
- supprimer puis recréer une replica cassée seulement après avoir décidé que son point de reprise n’est plus utile.
Supprimer une replica libère la relation, mais la retire également des candidates à la promotion. C’est une protection du primaire, pas une réparation transparente.
Prouver le chemin de connexion cible
Un switchover planifié promeut la read replica en primaire et rétrograde l’ancien primaire. Il exige des virtual endpoints writer et reader configurés, avec la candidate comme cible reader. Une promotion standalone détache au contraire la replica et laisse à l’équipe la responsabilité de rediriger l’application.
Avant l’une ou l’autre action, testez les contrôles effectifs de la cible :
- authentification PostgreSQL et Microsoft Entra attendue par l’application ;
- firewall ou chemin réseau privé depuis les clients de production ;
- paramètres serveur nécessaires au workload ;
- extensions, rôles et bases attendus après bascule ;
- résolution des endpoints writer et reader depuis le runtime applicatif ;
- dashboards et alertes attachés au futur primaire.
Une requête read-only verte ne valide ni l’identité d’écriture, ni le comportement transactionnel, ni le pooling après promotion.
Utiliser un marqueur pour prouver le RPO atteignable
Si le primaire reste disponible, créez un marqueur sans effet métier, auditable, en passant par le chemin d’écriture normal de l’application. N’inventez pas une écriture directe en base si le contrat applicatif ne le permet pas.
marker:
id: dr-check-20260830-0615
written_through: orders-api
committed_at_utc: 2026-08-30T06:15:00Z
contains_personal_data: false
candidate_replica:
marker_visible: true-or-false
observed_at_utc: <timestamp>
replay_lsn: <lsn>
lag_seconds: <value>
lag_bytes: <value>
allow_planned_switchover_when:
- marker is visible on the replica
- byte gap converges to the accepted boundary
- both servers are Ready
- virtual endpoints target the expected servers
- write-path canary and rollback owner are ready
allow_forced_promotion_when:
- primary region is unavailable or cannot safely recover in the RTO
- last replicated business marker is known
- data loss up to the observed lag is explicitly accepted
- reconciliation procedure exists for missing writes
abort_when:
- replica continues to diverge
- primary storage reaches the incident stop threshold
- target identity or network path fails
- application owners cannot state the accepted RPO Le marqueur transforme un vague « lag faible » en point de reprise métier. Conservez son identifiant avec la promotion et utilisez-le pour réconcilier les écritures après une opération forcée.
Décider entre réparation, switchover, promotion forcée et reconstruction
Attendez le rattrapage si le primaire est sain, si l’écart en octets diminue, si le stockage reste sûr et si aucune panne n’impose une bascule immédiate. Réparez ou scalez lorsqu’un bottleneck mesuré explique le retard et qu’un canari prouve la convergence.
Utilisez le switchover planifié lorsque les deux serveurs sont Ready, que le WAL restant peut être synchronisé, que les virtual endpoints sont valides et que l’application a passé les tests cibles. Réservez la promotion forcée à une panne où la disponibilité vaut la perte mesurée. Le lag au détachement représente approximativement la limite de perte, pas une métrique cosmétique.
Après switchover, validez écritures, lectures, identités, endpoints, sens de réplication, exigences HA et supervision. L’ancien primaire devient replica ; revenir en arrière est une nouvelle promotion contrôlée, pas un bouton Undo. Après promotion standalone ou forcée, conservez l’ancienne topologie jusqu’à la réconciliation des écritures et l’attribution claire du nouvel endpoint.
Conclusion
Une read replica PostgreSQL en retard n’est pas automatiquement une cible à promouvoir. Déterminez d’abord si le lag temporel représente du WAL réellement absent, mesurez l’écart en octets et le marqueur métier, localisez la pression et protégez le stockage du primaire.
Ne promouvez que lorsque le chemin de connexion cible est prouvé et le RPO accepté explicite. Préférez un switchover planifié lorsque la synchronisation reste possible. Si une panne régionale force la décision, conservez le dernier marqueur répliqué, acceptez la limite de perte, validez le nouveau writer et traitez la réconciliation comme une partie de la reprise.