🐘 4) Réglages OS & FS
Objectif : adapter le noyau Linux, le système de fichiers et le réseau pour que PostgreSQL ne soit pas pénalisé par THP, by défaut, ou par un scheduler I/O inadapté.
Kernel & mémoire
THP off, HugePages si gros shared_buffers, vm.swappiness bas, vm.dirty_ratio adaptés.
I/O & filesystems
Scheduler mq-deadline/none sur SSD/NVMe, noatime, discard (ou TRIM), alignement RAID.
Réseau
MTU cohérente (9001 si bout-en-bout), somaxconn augmenté (poolers), buffers TCP si réplication distante.
Objectif
Donner à PostgreSQL un noyau prévisible (pas de THP), une mémoire qui ne swap pas, et des paramètres vm.* cohérents avec la volumétrie WAL/IO.
THP & HugePages
| Élément | Recommandation |
|---|---|
| THP | désactiver : latence, stalls, allocations imprévisibles |
| HugePages | OUI si shared_buffers ≥ 8–16 Go → moins d’entrées TLB |
| NUMA | PG n’est pas NUMA-aware → interleave ou pinning systemd |
# désactiver THP (immédiat) echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
Swappiness & dirty pages
vm.swappiness = 1à10: serveur DB dédiévm.dirty_ratio = 15;vm.dirty_background_ratio = 5sur HDD → évite gros flushs- sur SSD/NVMe récents : valeurs par défaut (Ubuntu 22+/24+) souvent correctes
Exemple de profil sysctl
# /etc/sysctl.d/99-postgresql.conf vm.swappiness = 5 vm.dirty_ratio = 15 vm.dirty_background_ratio = 5 vm.overcommit_memory = 1 vm.overcommit_ratio = 90 # open files / backlog fs.file-max = 1000000
Overcommit
| vm.overcommit_memory | Quand ? |
|---|---|
| 0 | défaut, bon compromis |
| 1 | beaucoup de process légers (poolers, scripts) → OK |
| 2 | clusters multi-locataires → plus restrictif |
Pinning PostgreSQL (optionnel)
Si NUMA, on peut épingler le service pour éviter des migrations mémoire :
numactl --cpunodebind=0 --membind=0 \ /usr/lib/postgresql/16/bin/postgres -D /var/lib/postgresql/16/main
⚠️ à ne faire que si tu maîtrises le placement mémoire.
Choix FS
| FS | Pourquoi |
|---|---|
| XFS | très bon par défaut, stable, répandu en prod |
| ext4 | OK, connu, nécessite parfois un peu de tuning (noatime...) |
| ZFS | puissant (snap, checksums) mais attention RAM + recordsize |
Options de montage
noatime→ évite les écritures de lecturediscardsi SSD (ou timerfstrimhebdo)- vérifier
barrierselon contrôleur RAID/BBU
# /etc/fstab (exemple) UUID=... /var/lib/postgresql xfs defaults,noatime 0 2 UUID=... /pgwal xfs defaults,noatime 0 2
Scheduler I/O
Sur Linux récents :
- NVMe : none ou mq-deadline
- SAS/SATA : mq-deadline
cat /sys/block/nvme0n1/queue/scheduler echo mq-deadline | sudo tee /sys/block/nvme0n1/queue/scheduler
Layout conseillé (rappel)
| Zone | Média | Notes |
|---|---|---|
| DATA | RAID10 SSD / SAS rapide | latence régulière |
| WAL | NVMe dédié / RAID1 rapide | écrire vite, flush sûr |
| TEMP | NVMe / SSD | tri, hash, ANALYZE lourd |
Tests I/O rapides
# séquentiel fio --name=seqwrite --rw=write --bs=1M --size=2G --numjobs=1 --runtime=30 --group_reporting # aléatoire 4k fio --name=randrw --rw=randrw --bs=4k --size=2G --iodepth=32 --numjobs=4 --runtime=60 --group_reporting
Surveillance
iostat -x 1→ latence, %utilpidstat -d→ process bavardspg_stat_io(PG ≥ 15)
Paramètres de base
| Clé | Valeur |
|---|---|
| net.core.somaxconn | 1024–4096 (poolers) |
| net.core.netdev_max_backlog | 2000–5000 |
| net.ipv4.tcp_fin_timeout | défaut OK |
# /etc/sysctl.d/99-net-postgresql.conf net.core.somaxconn = 2048 net.core.netdev_max_backlog = 4096
MTU / jumbo frames
Passer en 9000/9001 seulement si tous les segments (VM → host → switch → firewall → DB) le supportent.
ip link set dev eth0 mtu 9001
Réplication distante / réplication logique
Si tu répliques vers un autre DC ou vers un subscriber logique rapide, tu peux ouvrir les buffers TCP :
net.core.rmem_max = 134217728 net.core.wmem_max = 134217728 net.ipv4.tcp_rmem = 4096 87380 134217728 net.ipv4.tcp_wmem = 4096 65536 134217728
Checks rapides
# latence ping -c 4 pg-primary # débit iperf3 -c pg-primary -t 10 # tables pour voir si le réseau limite la réplication SELECT * FROM pg_stat_wal_receiver;
Si tu vois un lag WAL alors que la DB n’est pas saturée → regarder réseau (MTU, gigue, buffers).
