PostgreSQL streaming replica lag et CPU élevé sur le réplica

Posté par anais56 le 25/01/2026
RÉSOLU

anais56

Membre depuis le 09/04/2025

actif

Salut à tous.

On a un setup PostgreSQL 14 en streaming replication et depuis quelques jours on observe un lag de réplication qui augmente de manière intermittente sur notre réplica secondaire. Le truc bizarre c'est que le primaire est stable niveau charge CPU et IOPS, mais le réplica a des pics de CPU qui montent à 80-90% juste avant que le lag ne devienne visible. On est sur des instances EC2 avec des NVMe.

Une idée d'où je devrais commencer à chercher ?

Commentaires

marie-regnier

Membre depuis le 02/08/2019

actif secouriste

C'est la galère quand le réplica tousse. La première chose à regarder c'est ce que fait le réplica au moment des lags. Va voir `pg_stat_wal_receiver` et `pg_stat_replication` sur ton réplica. Quels sont les `replay_lag` et `sync_state` ?

frederic-gaillard

Membre depuis le 24/07/2024

actif

En parallèle des stats PG, il faut voir ce que fait l'OS. Un `iostat -x 5` sur le réplica peut montrer si ton problème est I/O bound. Regarde en particulier les colonnes `r/s` et `w/s` sur le volume des WAL, et le `%util`.

anais56

Membre depuis le 09/04/2025

actif

Ok j'ai ça.

SELECT replay_lag, sync_state FROM pg_stat_wal_receiver;

Le `replay_lag` monte jusqu'à 30 secondes parfois, et `sync_state` est `async`. L'iostat sur le volume WAL montre un `r/s` très élevé pendant les pics, genre 5000-6000 lectures par seconde, avec un `%util` à 100%. Des écritures normales.

marie-regnier

Membre depuis le 02/08/2019

actif secouriste

5000 lectures par seconde sur le volume WAL d'un réplica ? C'est énorme. Un réplica ne devrait faire que des écritures et des lectures séquentielles pour la relecture des WAL. Ça sent les `full_page_writes` ou un problème de checkpoint.

Vérifie `SHOW full_page_writes;` et `SHOW checkpoint_completion_target;` sur le primaire et le réplica.

anais56

Membre depuis le 09/04/2025

actif

`full_page_writes` est à `on` sur les deux, ce qui est le setting par défaut et recommandé. `checkpoint_completion_target` est à 0.9. La taille des WAL est 1GB.

frederic-gaillard

Membre depuis le 24/07/2024

actif

FPW `on` est la bonne pratique, mais ça génère plus de WAL et donc plus de travail pour le réplica. Le CPU élevé en `system` mode avec beaucoup de `r/s` pourrait indiquer que le kernel galère avec le `fsync` ou que l'IO scheduler est pas optimal pour la charge de relecture. Ou même la décompression si `wal_compression` est actif.

anais56

Membre depuis le 09/04/2025

actif

J'ai vérifié, `wal_compression` est à `off`. Le CPU est bien en `system` sur l'OS. Donc pas de décompression. Ça pointe vers un souci kernel/IO.

Quelle est la valeur de `effective_io_concurrency` sur ton réplica ? Et le `wal_sync_method` ?

marie-regnier

Membre depuis le 02/08/2019

actif secouriste

`effective_io_concurrency` est à 1. `wal_sync_method` est `fdatasync`. Je sais que 1 c'est pas terrible mais nos NVMe sont censés être rapides.

frederic-gaillard

Membre depuis le 24/07/2024

actif

`effective_io_concurrency=1` avec des NVMe c'est un crime. Tu donnes une seule requête d'IO au kernel à la fois. Monte ça à 256 ou même 512, et même plus si ton NVMe supporte un queue depth très élevé. Le kernel peut mieux paralléliser les relectures (même si c'est surtout pour les lectures data, ça peut impacter la latence générale du système).

Pense aussi à ton I/O scheduler. Quel est-il ? `cat /sys/block/nvme0n1/queue/scheduler`

anais56

Membre depuis le 09/04/2025

actif

Je viens de passer `effective_io_concurrency` à 256 sur le réplica. J'ai redémarré PG. Le `replay_lag` est moins fréquent mais les pics de CPU `system` et de `r/s` sont toujours là. Le scheduler est `mq-deadline`.

marie-regnier

Membre depuis le 02/08/2019

actif secouriste

`mq-deadline` est généralement bon mais pas toujours pour des workloads spécifiques comme la relecture WAL. Pour des NVMe modernes qui gèrent eux-mêmes l'ordonnancement, `noop` est souvent la meilleure option. Ça réduit l'overhead kernel et laisse le contrôleur NVMe faire son boulot.

Essaie de changer le scheduler en `noop` pour ton device NVMe sur le réplica. Ça se fait à chaud pour tester, mais pour la persistance c'est dans GRUB ou udev rules.

echo noop > /sys/block/nvme0n1/queue/scheduler

frederic-gaillard

Membre depuis le 24/07/2024

actif

Oui le `noop` est le classique pour les NVMe. Si ça persiste après ça, on peut regarder les options de montage de ton système de fichiers. Par défaut ext4 ou xfs peuvent avoir des overheads.

Les `dirty_ratio` et `dirty_background_ratio` du kernel peuvent aussi jouer si le kernel passe son temps à flusher des pages sale. Mais ce serait plus en `w/s` qu'en `r/s`.

anais56

Membre depuis le 09/04/2025

actif

J'ai basculé le scheduler en `noop` sur le réplica. La différence est flagrante. Le `replay_lag` est stable, zéro pic de CPU en `system` mode, et le `r/s` sur le volume WAL est retombé à des niveaux normaux (moins de 100). C'était bien le `mq-deadline` qui créait des frictions avec la relecture des WAL sur le NVMe.

Merci à vous deux pour le diagnostic chirurgical ! Ça m'a sauvé un week-end.

Laisser une réponse

Vous devez être connecté pour poster un message !

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire