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` ?
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`.
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.
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.
`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.
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.
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` ?
`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.
`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`
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`.
`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
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`.
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.
Vous devez être connecté pour poster un message !
Recevoir les derniers articles gratuitement en créant un compte !
S'inscrire
anais56
Membre depuis le 09/04/2025actif
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 ?