13 commentaires
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.
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.
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
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.
Laisser une réponse
Vous devez être connecté pour poster un message !
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 ?