🔝 Retour au Sommaire
- Introduction à l'Audit de Configuration
- Pourquoi Auditer sa Configuration ?
- Les Fichiers de Configuration PostgreSQL
- Méthodologie d'Audit
- Paramètres de Mémoire
- Paramètres de Performance
- Configuration du WAL
- Configuration des Connexions
- Autovacuum et Maintenance
- Paramètres de Sécurité
- Configuration I/O (PostgreSQL 18)
- Logging et Observabilité
- Checklist d'Audit Complète
- Outils d'Aide à l'Audit
- Erreurs Courantes de Configuration
- Conclusion et Bonnes Pratiques
Un audit de configuration est un processus systématique qui consiste à examiner et évaluer les paramètres de configuration de votre instance PostgreSQL pour s'assurer qu'ils sont :
- Adaptés à votre cas d'usage (OLTP, OLAP, mixte)
- Optimaux pour vos ressources matérielles disponibles
- Sécurisés selon les meilleures pratiques
- Cohérents entre eux (pas de contradictions)
Cet audit est destiné à :
- Développeurs qui utilisent PostgreSQL dans leurs applications
- DevOps/SRE qui déploient et maintiennent PostgreSQL
- DBA débutants qui veulent comprendre les fondamentaux
- Toute personne responsable d'une instance PostgreSQL en production
Ce guide est conçu pour être accessible aux débutants. Nous expliquons chaque concept avant de l'auditer, et nous donnons des explications claires sur l'impact de chaque paramètre.
Une configuration PostgreSQL inadaptée peut entraîner :
-
Performances Dégradées
- Requêtes lentes
- Temps de réponse élevés
- Saturation des ressources
-
Instabilité
- Crashes ou redémarrages inopinés
- Erreurs "out of memory"
- Corruption de données (dans les cas extrêmes)
-
Problèmes de Sécurité
- Accès non autorisés
- Authentification faible
- Logs insuffisants pour détecter les intrusions
-
Coûts Inutiles
- Sur-dimensionnement du matériel
- Surconsommation de ressources cloud
- Temps de maintenance excessifs
Un audit de configuration régulier permet de :
- Optimiser les performances : Exploiter pleinement les ressources disponibles
- Prévenir les problèmes : Détecter les configurations à risque avant qu'elles ne causent des incidents
- Économiser des coûts : Dimensionner correctement les ressources
- Améliorer la sécurité : Identifier et corriger les failles de configuration
- Faciliter la maintenance : Avoir une configuration documentée et cohérente
Il est recommandé d'auditer sa configuration :
- Après l'installation initiale : Vérifier que la configuration par défaut est adaptée
- Avant la mise en production : S'assurer que tout est optimal
- Après une mise à jour majeure : PostgreSQL 17 → 18 par exemple
- Après un changement matériel : Ajout de RAM, changement de disques, etc.
- Périodiquement : Tous les 3 à 6 mois pour les systèmes critiques
- Après un incident : Comprendre si une mauvaise configuration a contribué au problème
PostgreSQL utilise principalement trois fichiers de configuration :
C'est le fichier de configuration principal de PostgreSQL.
Localisation typique :
- Linux :
/etc/postgresql/18/main/postgresql.confou/var/lib/postgresql/data/postgresql.conf - Windows :
C:\Program Files\PostgreSQL\18\data\postgresql.conf - Docker :
/var/lib/postgresql/data/postgresql.conf
Contenu :
- Paramètres de mémoire (shared_buffers, work_mem, etc.)
- Paramètres de performance
- Configuration WAL
- Logging
- Chemins de fichiers
Format :
# Commentaire
parametre = valeur
# autre_parametre = valeur_par_defaut (commenté)
Le fichier Host-Based Authentication contrôle qui peut se connecter à la base de données.
Localisation : Même répertoire que postgresql.conf
Contenu :
- Règles d'authentification par utilisateur, base de données et adresse IP
- Méthodes d'authentification (trust, md5, scram-sha-256, etc.)
Format :
# TYPE DATABASE USER ADDRESS METHOD
local all all scram-sha-256
host all all 127.0.0.1/32 scram-sha-256
Ce fichier gère le mapping entre les utilisateurs système et les utilisateurs PostgreSQL (utilisé avec l'authentification "ident").
Localisation : Même répertoire que postgresql.conf
Usage : Moins courant, principalement pour des cas d'authentification avancés.
-- Voir tous les paramètres
SHOW ALL;
-- Voir un paramètre spécifique
SHOW shared_buffers;
-- Voir d'où vient la valeur d'un paramètre
SELECT name, setting, source, sourcefile
FROM pg_settings
WHERE name = 'shared_buffers'; -- Trouver le fichier postgresql.conf
SHOW config_file;
-- Trouver le fichier pg_hba.conf
SHOW hba_file;
-- Trouver le répertoire de données
SHOW data_directory;PostgreSQL utilise une hiérarchie pour déterminer la valeur finale d'un paramètre :
- Valeur par défaut : Compilée dans PostgreSQL
- postgresql.conf : Écrase la valeur par défaut
- ALTER SYSTEM : Écrit dans
postgresql.auto.confet écrase postgresql.conf - ALTER DATABASE/ROLE : Configuration au niveau base/utilisateur
- SET : Au niveau session (temporaire)
Ordre de priorité : SET > ALTER DATABASE/ROLE > ALTER SYSTEM > postgresql.conf > défaut
Pour auditer efficacement une configuration PostgreSQL, suivez cette méthodologie en 6 étapes :
Avant de commencer, rassemblez les informations suivantes :
Sur le Matériel :
- Quantité de RAM totale
- Nombre de cœurs CPU
- Type de disques (SSD, HDD, NVMe)
- Bande passante I/O
Sur l'Usage :
- Type de charge (OLTP, OLAP, mixte)
- Nombre d'utilisateurs/connexions concurrentes
- Taille de la base de données
- Croissance prévue
Sur l'Environnement :
- Version PostgreSQL (ici : 18)
- Système d'exploitation
- Déploiement (bare metal, VM, container, cloud)
- Services partagés sur le serveur
-- Exporter toute la configuration dans un fichier
COPY (SELECT name, setting, unit, category, short_desc
FROM pg_settings
ORDER BY category, name)
TO '/tmp/pg_config_audit.csv'
WITH CSV HEADER; Ou utilisez un script shell :
psql -d postgres -c "SHOW ALL;" > config_audit.txtAnalysez chaque catégorie de paramètres selon les sections de ce guide (mémoire, performance, WAL, etc.).
Pour chaque paramètre, posez-vous ces questions :
- La valeur est-elle adaptée à mon matériel ?
- Est-elle cohérente avec mon cas d'usage ?
- Y a-t-il un risque de sécurité ?
- Est-elle documentée/justifiée ?
Classez les problèmes identifiés par :
- Critique : Risque de panne ou de perte de données
- Important : Impact significatif sur les performances
- Mineur : Optimisation possible mais impact limité
Documentez :
- Les valeurs actuelles
- Les valeurs recommandées
- Le raisonnement derrière chaque changement
- Les changements appliqués et leur date
Il n'existe pas de configuration PostgreSQL parfaite qui fonctionne pour tous les cas. La configuration doit être adaptée à :
- Votre matériel spécifique
- Votre charge de travail
- Vos contraintes de disponibilité
- Vos objectifs de performance
Ne changez jamais un paramètre sans :
- Comprendre son impact
- Mesurer les performances avant
- Tester le changement
- Mesurer les performances après
Lors de l'optimisation, modifiez un seul paramètre à la fois pour pouvoir :
- Isoler l'impact de chaque changement
- Revenir en arrière facilement si nécessaire
- Comprendre les relations entre paramètres
PostgreSQL utilise des valeurs par défaut très conservatrices (pour fonctionner sur de petites machines). Sur des serveurs modernes, ces valeurs sont presque toujours trop basses.
La mémoire est la ressource la plus critique pour les performances de PostgreSQL. Une mauvaise configuration mémoire peut diviser les performances par 10 ou plus.
Description : Mémoire partagée utilisée par PostgreSQL pour mettre en cache les données lues depuis les disques.
Rôle : C'est le "cache" principal de PostgreSQL. Toutes les lectures et écritures de pages de données passent d'abord par ce buffer.
Quand PostgreSQL a besoin d'une page de données :
- Il cherche d'abord dans
shared_buffers(très rapide) - Si absent, il lit depuis le disque (lent) et met en cache dans
shared_buffers - Les pages fréquemment utilisées restent en mémoire
shared_buffers = 128MB
Cette valeur est beaucoup trop basse pour un serveur moderne.
Formule générale :
shared_buffers = 25% de la RAM totale
Exemples :
- Serveur avec 4 GB RAM :
shared_buffers = 1GB - Serveur avec 16 GB RAM :
shared_buffers = 4GB - Serveur avec 64 GB RAM :
shared_buffers = 16GB
Limites :
- Minimum : 128 MB (valeur par défaut, trop faible)
- Maximum pratique : 8-16 GB même sur très gros serveurs
- Au-delà de 16 GB, les gains sont marginaux car le système d'exploitation gère déjà son propre cache (page cache)
Serveurs avec peu de RAM (< 2 GB) :
shared_buffers = 512MB
Serveurs cloud avec RAM limitée :
shared_buffers = 20% de la RAM
Serveurs dédiés avec beaucoup de RAM (> 64 GB) :
shared_buffers = 8GB à 16GB maximum
Si trop bas :
- PostgreSQL sollicite constamment le disque
- Performances I/O catastrophiques
- Requêtes extrêmement lentes
Si trop haut :
- RAM gaspillée (peu de bénéfice au-delà de 25%)
- Risque de compétition avec le cache OS
- Temps de démarrage/arrêt plus longs
Consultez le cache hit ratio :
SELECT
sum(heap_blks_read) as heap_read,
sum(heap_blks_hit) as heap_hit,
sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS hit_ratio
FROM pg_statio_user_tables;Interprétation :
hit_ratio > 0.99(99%) : Excellent, configuration adaptéehit_ratio 0.90-0.99: Correct, possibilité d'améliorationhit_ratio < 0.90: Mauvais,shared_buffersprobablement trop bas
Description : Mémoire allouée à chaque opération de tri ou de hash pour une requête.
Rôle : Utilisée pour les opérations comme ORDER BY, DISTINCT, jointures hash, agrégations.
- Chaque opération dans une requête (pas chaque requête) peut utiliser jusqu'à
work_mem - Une requête complexe peut avoir plusieurs opérations simultanées
- Si l'opération dépasse
work_mem, PostgreSQL écrit sur disque (très lent)
Exemple : Une requête avec un ORDER BY et une jointure hash utilise potentiellement 2 × work_mem
work_mem = 4MB
Cette valeur est beaucoup trop basse pour la plupart des cas.
Formule générale :
work_mem = RAM totale / (max_connections × 2 à 4)
Le diviseur dépend de la complexité moyenne de vos requêtes.
Exemples :
Pour un serveur avec 16 GB RAM et 100 connexions max :
work_mem = 16GB / (100 × 3) = ~50MB
Valeurs typiques par cas d'usage :
| Cas d'usage | work_mem |
|---|---|
| OLTP léger (requêtes simples) | 10-25 MB |
| OLTP standard | 25-64 MB |
| Mixte OLTP/OLAP | 64-256 MB |
| OLAP (analytics, BI) | 256 MB - 1 GB |
| Data warehouse | 1-4 GB |
Serveurs OLAP/Analytics : Avec peu de connexions mais des requêtes complexes :
work_mem = 512MB à 2GB
Environnements avec beaucoup de connexions (> 200) :
work_mem = 16MB à 32MB
max_connections = 200
Utilisez un connection pooler (PgBouncer) pour limiter les connexions réelles.
Si trop bas :
- Sorts et jointures utilisent le disque (opération "on-disk")
- Performances extrêmement dégradées
- Logs remplis de messages "temporary file: ... "
Si trop haut :
- Risque d'épuisement de la RAM
- Swapping (le pire scénario)
- Possibles erreurs "out of memory"
Mémoire maximale théorique utilisable :
max_connections × work_mem × complexité_moyenne
Cette valeur ne doit jamais dépasser la RAM disponible.
Cherchez dans les logs PostgreSQL :
grep "temporary file" /var/log/postgresql/postgresql-*.logSi vous voyez des messages comme :
LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp12345.6", size 104857600
C'est le signe que des opérations débordent sur disque.
Solution : Augmentez work_mem progressivement (doublez, testez, répétez).
Description : Mémoire allouée aux opérations de maintenance (VACUUM, CREATE INDEX, ALTER TABLE, etc.).
Rôle : Accélère les opérations de maintenance qui sont généralement gourmandes en mémoire.
maintenance_work_mem = 64MB
Valeur trop basse pour la plupart des bases de données réelles.
Formule générale :
maintenance_work_mem = 5-10% de la RAM totale
Exemples :
- Serveur avec 8 GB RAM :
maintenance_work_mem = 512MB - Serveur avec 16 GB RAM :
maintenance_work_mem = 1GB - Serveur avec 64 GB RAM :
maintenance_work_mem = 4-6GB
Limites :
- Maximum pratique : 4-8 GB
- Au-delà, les gains sont marginaux
Bases de données avec de très grandes tables :
maintenance_work_mem = 8GB
Environnements avec autovacuum parallèle :
Attention : chaque worker autovacuum peut utiliser autovacuum_work_mem (ou maintenance_work_mem si non défini).
autovacuum_work_mem = 512MB
maintenance_work_mem = 2GB
Si trop bas :
- Création d'index très lente
- VACUUM inefficace
- Opérations de maintenance qui durent des heures
Si trop haut :
- Peu de risques (utilisé uniquement pendant la maintenance)
- Mais peut causer des pics mémoire
Observez la durée des opérations de maintenance :
-- Voir la durée des VACUUM récents
SELECT schemaname, relname, last_vacuum, last_autovacuum
FROM pg_stat_user_tables
ORDER BY last_autovacuum DESC NULLS LAST
LIMIT 10; Si les VACUUM prennent trop longtemps sur de grandes tables, augmentez maintenance_work_mem.
Description : Estimation de la mémoire disponible pour le cache du système d'exploitation (OS cache) + shared_buffers.
Rôle : Ce paramètre n'alloue pas de mémoire. Il informe simplement le planificateur de requêtes de la quantité de données susceptibles d'être en cache.
Le planificateur utilise cette valeur pour estimer si :
- Les données seront probablement en mémoire (index scan préféré)
- Les données seront probablement sur disque (sequential scan préféré)
effective_cache_size = 4GB
Cette valeur est souvent sous-estimée sur des serveurs modernes.
Formule générale :
effective_cache_size = 50-75% de la RAM totale
Exemples :
- Serveur avec 8 GB RAM :
effective_cache_size = 6GB - Serveur avec 16 GB RAM :
effective_cache_size = 12GB - Serveur avec 64 GB RAM :
effective_cache_size = 48GB
Serveur dédié PostgreSQL :
effective_cache_size = 75% de la RAM
Serveur partagé (avec d'autres services) :
effective_cache_size = 25-50% de la RAM
Si trop bas :
- Le planificateur sous-estime le cache
- Préfère les sequential scans même quand un index scan serait plus rapide
- Plans de requêtes sous-optimaux
Si trop haut :
- Le planificateur surestime le cache
- Préfère les index scans même quand les données ne sont pas en cache
- Peut causer des performances dégradées sur de grandes tables
Important : Une mauvaise valeur ne cause pas d'erreur, juste des choix sous-optimaux du planificateur.
| Paramètre | Valeur par défaut | Recommandation | Formule |
|---|---|---|---|
shared_buffers |
128 MB | 25% RAM | RAM × 0.25 (max 16GB) |
work_mem |
4 MB | 25-256 MB | RAM / (max_connections × 3) |
maintenance_work_mem |
64 MB | 512 MB - 4 GB | RAM × 0.05 à 0.10 |
effective_cache_size |
4 GB | 50-75% RAM | RAM × 0.50 à 0.75 |
# Mémoire
shared_buffers = 4GB # 25% de 16GB
work_mem = 50MB # 16GB / (100 × 3)
maintenance_work_mem = 1GB # ~6% de 16GB
effective_cache_size = 12GB # 75% de 16GB
Description : Nombre maximum de connexions simultanées à PostgreSQL.
Rôle : Limite le nombre de clients pouvant se connecter en même temps.
max_connections = 100
Chaque connexion consomme :
- Environ 10 MB de RAM pour les structures internes
- Des ressources CPU pour la gestion
- Potentiellement
work_memlors de l'exécution de requêtes
Calcul approximatif :
Mémoire pour connexions = max_connections × 10MB
Avec 100 connexions : ~1 GB de RAM juste pour les connexions.
Serveur web/application OLTP :
max_connections = 100 à 200
Serveur analytics/BI (OLAP) :
max_connections = 20 à 50
Serveur avec connection pooler (PgBouncer) :
max_connections = 50 à 100
Le pooler gère les connexions applicatives et maintient peu de connexions réelles à PostgreSQL.
Au-delà de 200-300 connexions actives simultanées, PostgreSQL souffre de :
- Contention : Compétition pour les ressources partagées (locks, buffers)
- Context switching : Le CPU passe son temps à basculer entre processus
- Overhead mémoire : Plusieurs GB de RAM juste pour les connexions
Symptôme typique :
- Serveur avec 500 connexions mais performant avec seulement 50 connexions actives
- Augmenter
max_connectionsdégrade les performances
Plutôt que d'augmenter max_connections, utilisez un connection pooler comme PgBouncer.
Principe :
- Application crée 500 connexions vers PgBouncer
- PgBouncer maintient seulement 50 connexions vers PostgreSQL
- Les connexions sont réutilisées efficacement
Configuration typique avec PgBouncer :
# PostgreSQL
max_connections = 100
# PgBouncer
default_pool_size = 25
max_client_conn = 500
Si trop bas :
- Erreur "FATAL: sorry, too many clients already"
- Applications ne peuvent plus se connecter
Si trop haut :
- Consommation mémoire excessive
- Contention et dégradation des performances
- Coût par connexion augmente
-- Nombre de connexions actives
SELECT count(*) FROM pg_stat_activity;
-- Connexions par état
SELECT state, count(*)
FROM pg_stat_activity
GROUP BY state;
-- Connexions par base de données
SELECT datname, count(*)
FROM pg_stat_activity
GROUP BY datname; Description : Coûts relatifs utilisés par le planificateur de requêtes pour estimer le coût d'accès aux données.
Rôle : Coût estimé pour lire une page aléatoire depuis le disque (typiquement via un index).
Valeur par défaut :
random_page_cost = 4.0
Cette valeur a été définie à l'époque des disques durs rotatifs (HDD). Sur SSD/NVMe, elle est obsolète.
Rôle : Coût estimé pour lire une page de façon séquentielle (scan complet de table).
Valeur par défaut :
seq_page_cost = 1.0
Cette valeur sert de référence pour les autres coûts.
Le planificateur de requêtes utilise ces coûts pour décider :
- Index scan vs Sequential scan
- Quel index utiliser
- Dans quel ordre effectuer les jointures
Rapport par défaut :
random_page_cost / seq_page_cost = 4.0
Cela signifie : "Lire une page aléatoire coûte 4× plus cher qu'une page séquentielle".
SSD (Solid State Drive) :
random_page_cost = 1.1
seq_page_cost = 1.0
Sur SSD, l'accès aléatoire et séquentiel ont des performances similaires.
NVMe (Plus rapide que SSD) :
random_page_cost = 1.0
seq_page_cost = 1.0
Sur NVMe, aucune différence significative.
HDD (Disques durs rotatifs) :
random_page_cost = 4.0 # Valeur par défaut OK
seq_page_cost = 1.0
Cloud (EBS Amazon, Azure Disks) :
random_page_cost = 1.5 à 2.0
Les performances varient selon le type de stockage cloud.
random_page_cost trop élevé (ex: 4.0 sur SSD) :
- Le planificateur évite les index scans
- Préfère les sequential scans même sur petites tables
- Résultat : Requêtes lentes, index inutilisés
random_page_cost trop bas (ex: 1.0 sur HDD) :
- Le planificateur abuse des index scans
- Trop d'I/O aléatoires sur disques lents
- Résultat : Requêtes encore plus lentes
Observez les plans de requêtes :
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM ma_table WHERE colonne_indexee = 'valeur'; Si vous voyez systématiquement des Seq Scan alors que vous avez des index, vérifiez random_page_cost.
Description : Nombre de requêtes I/O simultanées que le disque peut gérer efficacement.
Rôle : Indique à PostgreSQL combien d'opérations I/O il peut lancer en parallèle (bitmap scans).
effective_io_concurrency = 1
Cette valeur est adaptée aux HDD mais sous-optimale pour SSD/NVMe.
HDD (disques durs) :
effective_io_concurrency = 2
SSD (SATA) :
effective_io_concurrency = 200
NVMe :
effective_io_concurrency = 300 à 1000
Cloud (AWS EBS, Azure Disks) :
effective_io_concurrency = 100 à 300
Dépend du type de volume (gp2, gp3, io1, io2).
Nouveau paramètre : io_method
# PostgreSQL 18
io_method = 'worker' # Nouveau : I/O asynchrone (AIO)
# Ancienne valeur : 'sync'
Le mode async peut améliorer les performances I/O de jusqu'à 3× sur des charges de travail intensives.
Si trop bas :
- PostgreSQL n'exploite pas le parallélisme I/O du disque
- Sous-utilisation des SSD/NVMe
Si trop haut :
- Peu de risques sur SSD/NVMe
- Sur HDD, peut causer de la contention
Description : Nombre maximum de workers parallèles qu'une requête peut utiliser.
Rôle : Permet la parallélisation des requêtes pour accélérer les scans et agrégations.
max_parallel_workers_per_gather = 2
Serveur avec peu de cœurs (4-8) :
max_parallel_workers_per_gather = 2
Serveur avec cœurs moyens (8-16) :
max_parallel_workers_per_gather = 4
Serveur avec beaucoup de cœurs (16+) :
max_parallel_workers_per_gather = 8
max_parallel_workers = 8 # Total de workers parallèles disponibles
max_worker_processes = 8 # Processus workers totaux (parallèles + autres)
Relation :
max_parallel_workers ≤ max_worker_processes
max_parallel_workers_per_gather ≤ max_parallel_workers
La parallélisation est utilisée pour :
- Sequential scans sur grandes tables
- Agrégations (GROUP BY, DISTINCT)
- Jointures sur grandes tables
- CREATE INDEX
Seuils par défaut :
- La table doit avoir > 8 MB (configurable avec
min_parallel_table_scan_size) - Les index doivent avoir > 512 KB (configurable avec
min_parallel_index_scan_size)
Si trop bas :
- Pas de parallélisation des requêtes
- Requêtes lentes sur grandes tables
Si trop haut :
- Contention CPU
- Peut ralentir les petites requêtes concurrentes
Le WAL (Write-Ahead Log) est le journal de transactions de PostgreSQL. C'est un composant critique pour la durabilité et la réplication.
Le WAL enregistre toutes les modifications avant qu'elles ne soient écrites dans les fichiers de données.
Principe :
- Transaction effectue une modification
- Modification écrite dans le WAL (sur disque, rapide)
- Plus tard, modification écrite dans les fichiers de données (flush asynchrone)
Avantages :
- Durabilité : En cas de crash, PostgreSQL rejoue le WAL
- Réplication : Le WAL peut être envoyé à des standby servers
- PITR : Point-In-Time Recovery via archives WAL
Description : Quantité d'informations écrites dans le WAL.
Valeurs possibles :
minimal: Minimum (pas de réplication possible)replica: Suffisant pour la réplication physique (défaut)logical: Nécessaire pour la réplication logique
wal_level = replica
C'est la valeur recommandée pour la plupart des cas.
Production avec réplication :
wal_level = replica
Production avec réplication logique :
wal_level = logical
Test/développement (sans réplication) :
wal_level = replica # Gardez replica au cas où
Ne passez jamais en minimal en production.
Description : Contrôle la taille des fichiers WAL avant déclencement d'un checkpoint.
Rôle : Taille maximale du WAL avant qu'un checkpoint soit forcé.
Valeur par défaut :
max_wal_size = 1GB
Cette valeur est trop basse pour des systèmes avec beaucoup d'écritures.
Système avec peu d'écritures (OLTP léger) :
max_wal_size = 2GB
Système avec écritures modérées :
max_wal_size = 4-8GB
Système avec écritures intensives (OLTP chargé, bulk inserts) :
max_wal_size = 16-32GB
Data warehouse (charges batch) :
max_wal_size = 64GB ou plus
Rôle : Taille minimale du WAL conservée entre checkpoints.
Valeur par défaut :
min_wal_size = 80MB
Recommandation :
min_wal_size = 25% de max_wal_size
Exemple :
max_wal_size = 8GB
min_wal_size = 2GB
max_wal_size trop bas :
- Checkpoints trop fréquents
- I/O pic lors des checkpoints
- Dégradation des performances d'écriture
- Logs remplis de "checkpoints occurring too frequently"
max_wal_size trop haut :
- Recovery plus long après un crash
- Espace disque consommé
- Mais généralement peu de risques
Surveillez les logs :
grep "checkpoints" /var/log/postgresql/postgresql-*.logSi vous voyez fréquemment :
LOG: checkpoints are occurring too frequently (X seconds apart)
HINT: Consider increasing the configuration parameter "max_wal_size".
Augmentez max_wal_size.
Description : Temps maximum entre deux checkpoints automatiques.
Rôle : Force un checkpoint même si max_wal_size n'est pas atteint.
checkpoint_timeout = 5min
Cette valeur peut être trop basse pour des systèmes avec beaucoup d'écritures.
Système OLTP léger :
checkpoint_timeout = 5min # OK
Système avec écritures modérées :
checkpoint_timeout = 10-15min
Système avec écritures intensives :
checkpoint_timeout = 30min
Balance entre :
- Recovery time (plus court = checkpoints fréquents)
- Overhead I/O (plus long = checkpoints moins fréquents)
Checkpoints fréquents :
- ✅ Recovery rapide après crash
- ❌ Overhead I/O constant
Checkpoints espacés :
- ✅ Moins d'overhead I/O
- ❌ Recovery plus long
Description : Fraction de checkpoint_timeout sur laquelle étaler l'écriture du checkpoint.
Rôle : Évite les pics d'I/O en étalant l'écriture du checkpoint.
checkpoint_completion_target = 0.9
Cette valeur est bonne et recommandée.
Avec checkpoint_timeout = 5min et checkpoint_completion_target = 0.9 :
- Le checkpoint a 5 minutes pour se terminer
- PostgreSQL étale l'écriture sur
5min × 0.9 = 4.5 minutes - Les 30 dernières secondes sont une marge
Valeur standard (recommandée) :
checkpoint_completion_target = 0.9
Ne modifiez ce paramètre que si vous rencontrez des problèmes spécifiques.
Si pics I/O trop importants :
checkpoint_completion_target = 0.95
| Paramètre | Défaut | OLTP léger | OLTP chargé | Data Warehouse |
|---|---|---|---|---|
wal_level |
replica | replica | replica | replica |
max_wal_size |
1GB | 2-4GB | 8-16GB | 32-64GB |
min_wal_size |
80MB | 500MB | 2-4GB | 8-16GB |
checkpoint_timeout |
5min | 5-10min | 15-30min | 30min |
checkpoint_completion_target |
0.9 | 0.9 | 0.9 | 0.9 |
Description : Adresses IP sur lesquelles PostgreSQL écoute les connexions.
Valeur par défaut :
listen_addresses = 'localhost'
PostgreSQL n'accepte que les connexions locales.
Développement local :
listen_addresses = 'localhost'
Production (avec réseau) :
listen_addresses = '*'
Accepte les connexions de toutes les interfaces réseau.
Production (sécurité renforcée) :
listen_addresses = '192.168.1.10' # IP spécifique du serveur
Modifier listen_addresses ne suffit pas pour la sécurité. Le fichier pg_hba.conf contrôle qui peut réellement se connecter.
Bonne pratique :
listen_addresses = '*'danspostgresql.conf- Règles strictes dans
pg_hba.conf
Description : Port TCP sur lequel PostgreSQL écoute.
Valeur par défaut :
port = 5432
Production standard :
port = 5432
Production avec sécurité par obscurité :
port = 54321 # Port non-standard
Attention : Changer le port n'apporte pas de sécurité réelle. Utilisez plutôt :
- Firewall correctement configuré
- Authentification forte (SCRAM-SHA-256)
- SSL/TLS activé
Voir section 6.1.
Description : Nombre de connexions réservées aux superutilisateurs.
Rôle : Garantit qu'un administrateur peut toujours se connecter, même si max_connections est atteint.
Valeur par défaut :
superuser_reserved_connections = 3
Production :
superuser_reserved_connections = 3 à 5
Explication :
Si max_connections = 100 et superuser_reserved_connections = 3 :
- 97 connexions disponibles pour les utilisateurs normaux
- 3 connexions réservées pour les superutilisateurs
Scénario d'urgence : Si votre application sature les 97 connexions, vous pouvez toujours vous connecter en tant que superutilisateur pour diagnostiquer.
Le VACUUM est un processus essentiel dans PostgreSQL. Il récupère l'espace des lignes supprimées et prévient des problèmes graves comme le XID wraparound.
PostgreSQL utilise MVCC (Multiversion Concurrency Control) :
- Les UPDATE et DELETE ne suppriment pas physiquement les lignes
- Ils créent de nouvelles versions
- Les anciennes versions (dead tuples) doivent être nettoyées par VACUUM
Sans VACUUM :
- La base de données grossit indéfiniment (bloat)
- Les performances se dégradent
- Risque de transaction ID wraparound (catastrophique)
Description : Active ou désactive l'autovacuum automatique.
Valeur par défaut :
autovacuum = on
Production :
autovacuum = on # NE JAMAIS DÉSACTIVER
Désactiver l'autovacuum peut causer :
- Bloat massif des tables
- Dégradation progressive des performances
- XID wraparound (perte de données possible)
Seule exception : Désactivation temporaire pendant un import massif, puis réactivation immédiate + VACUUM manuel.
Description : Nombre de processus autovacuum qui peuvent s'exécuter simultanément.
Valeur par défaut :
autovacuum_max_workers = 3
Nouveau paramètre : autovacuum_worker_slots
Permet d'augmenter dynamiquement le nombre de workers autovacuum selon la charge.
# PostgreSQL 18
autovacuum_max_workers = 5
autovacuum_worker_slots = 10 # Nouveau
Base de données avec peu de tables :
autovacuum_max_workers = 3
Base de données avec beaucoup de tables (> 100) :
autovacuum_max_workers = 5 à 8
Serveur avec beaucoup d'écritures :
autovacuum_max_workers = 8 à 16
Si trop bas :
- Autovacuum ne suit pas le rythme des modifications
- Accumulation de dead tuples
- Bloat progressif
Si trop haut :
- Contention I/O
- Peut ralentir les requêtes utilisateurs
Description : Détermine quand déclencher un autovacuum sur une table.
Un autovacuum se déclenche quand :
dead_tuples > (autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor × nb_lignes_table)
autovacuum_vacuum_scale_factor = 0.2 (20%)
autovacuum_vacuum_threshold = 50
Exemple : Table avec 1,000,000 de lignes :
Seuil = 50 + (0.2 × 1,000,000) = 200,050 dead tuples
L'autovacuum se déclenche après 200,050 lignes supprimées/modifiées.
Tables avec peu de modifications :
autovacuum_vacuum_scale_factor = 0.2 # Défaut OK
Tables avec beaucoup de modifications (OLTP chargé) :
autovacuum_vacuum_scale_factor = 0.05 à 0.1
autovacuum_vacuum_threshold = 50
Très grandes tables (> 100M lignes) :
autovacuum_vacuum_scale_factor = 0.01 à 0.02
autovacuum_vacuum_threshold = 1000
autovacuum_vacuum_max_threshold : Plafonne le nombre de dead tuples avant déclenchement (évite les attentes trop longues sur très grandes tables).
# PostgreSQL 18
autovacuum_vacuum_max_threshold = 10000000 # 10M dead tuples max
Description : Temps minimum entre deux vérifications autovacuum.
Valeur par défaut :
autovacuum_naptime = 1min
Base de données avec peu de modifications :
autovacuum_naptime = 1min # Défaut OK
Base de données avec beaucoup de modifications :
autovacuum_naptime = 30s
Serveur avec beaucoup de tables :
autovacuum_naptime = 15s à 30s
Plus la valeur est basse, plus l'autovacuum est réactif (mais plus de CPU utilisé).
Description : Mémoire utilisée par chaque processus autovacuum.
Valeur par défaut :
autovacuum_work_mem = -1 # Utilise maintenance_work_mem
Standard :
autovacuum_work_mem = -1 # Utilise maintenance_work_mem
Serveurs avec autovacuum parallèle intensif :
autovacuum_work_mem = 512MB à 1GB
maintenance_work_mem = 2GB
Cela évite que plusieurs workers consomment toute la RAM.
| Paramètre | Défaut | Peu modif. | Modif. modérées | Beaucoup modif. |
|---|---|---|---|---|
autovacuum |
on | on | on | on |
autovacuum_max_workers |
3 | 3 | 5-8 | 8-16 |
autovacuum_naptime |
1min | 1min | 30s | 15-30s |
autovacuum_vacuum_scale_factor |
0.2 | 0.2 | 0.1 | 0.05 |
autovacuum_vacuum_threshold |
50 | 50 | 50 | 50-100 |
Description : Algorithme de chiffrement des mots de passe.
Valeur par défaut (PostgreSQL 18) :
password_encryption = scram-sha-256
- PostgreSQL < 10 :
md5(déprécié, faible) - PostgreSQL 10-13 :
md5par défaut,scram-sha-256disponible - PostgreSQL 14+ :
scram-sha-256par défaut
PostgreSQL 18 :
password_encryption = scram-sha-256
Si vous migrez d'une ancienne version :
- Modifiez
postgresql.conf:
password_encryption = scram-sha-256
- Les utilisateurs doivent réinitialiser leur mot de passe :
ALTER USER mon_user PASSWORD 'nouveau_mot_de_passe';- Mettez à jour
pg_hba.conf:
# Remplacez "md5" par "scram-sha-256"
host all all 0.0.0.0/0 scram-sha-256
Description : Active le chiffrement SSL/TLS des connexions.
Activer SSL :
ssl = on
ssl_cert_file = '/etc/ssl/certs/server.crt'
ssl_key_file = '/etc/ssl/private/server.key'
ssl_ca_file = '/etc/ssl/certs/ca.crt' # Optionnel
TLS 1.3 et chiffrements FIPS :
# PostgreSQL 18
ssl_min_protocol_version = 'TLSv1.3'
ssl_tls13_ciphers = 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256'
Mode FIPS (pour conformité gouvernementale) :
ssl_library = 'fips' # Nouveau dans PG 18
Production :
ssl = on
ssl_min_protocol_version = 'TLSv1.2'
ssl_prefer_server_ciphers = on
Production haute sécurité :
ssl = on
ssl_min_protocol_version = 'TLSv1.3'
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
# Forcer SSL pour toutes les connexions réseau
hostssl all all 0.0.0.0/0 scram-sha-256
Description : Enregistre les connexions et déconnexions dans les logs.
Valeur par défaut :
log_connections = off
log_disconnections = off
Production :
log_connections = on
log_disconnections = on
Utilité :
- Audit de sécurité (qui se connecte ?)
- Détection d'activités suspectes
- Troubleshooting des problèmes de connexion
Description : Quelles requêtes SQL enregistrer dans les logs.
Valeurs possibles :
none: Aucune requêteddl: Uniquement DDL (CREATE, ALTER, DROP)mod: DDL + modifications (INSERT, UPDATE, DELETE)all: Toutes les requêtes
Valeur par défaut :
log_statement = 'none'
Production (sécurité standard) :
log_statement = 'ddl'
Enregistre les modifications de schéma (important pour l'audit).
Production (sécurité renforcée) :
log_statement = 'mod'
Enregistre toutes les modifications de données.
Debug/Troubleshooting (temporaire) :
log_statement = 'all'
log_statement = 'all' génère beaucoup de logs et peut contenir des informations sensibles (mots de passe dans les requêtes).
Nouveauté majeure : PostgreSQL 18 supporte nativement OAuth 2.0 pour l'authentification.
# Authentification via OAuth 2.0
host all all 0.0.0.0/0 oauth2 issuer=https://auth.example.com
- Intégration avec des fournisseurs d'identité (Okta, Auth0, Azure AD)
- Single Sign-On (SSO)
- Authentification moderne et sécurisée
PostgreSQL 18 introduit un nouveau sous-système I/O asynchrone qui peut améliorer considérablement les performances.
Description : Méthode d'I/O utilisée par PostgreSQL.
Nouveau dans PostgreSQL 18.
Valeurs possibles :
sync: I/O synchrone (ancien comportement)async: I/O asynchrone (nouveau, plus rapide)
Valeur par défaut (PostgreSQL 18) :
io_method = 'worker'
Le mode async peut améliorer les performances de jusqu'à 3× sur des charges I/O intensives.
PostgreSQL 18 en production :
io_method = 'worker'
Si problèmes de stabilité :
io_method = 'sync' # Retour au comportement classique
Voir section 6.3.
Avec PostgreSQL 18 et io_method = 'worker', il est recommandé d'augmenter cette valeur :
# PostgreSQL 18 avec I/O async
io_method = 'worker'
effective_io_concurrency = 300 # SSD/NVMe
Description : Où envoyer les logs.
Valeurs possibles :
stderr: Sortie d'erreur standardcsvlog: Format CSV (idéal pour l'analyse)syslog: Syslog systèmeeventlog: Event Log Windows
Valeur par défaut :
log_destination = 'stderr'
Production :
log_destination = 'stderr,csvlog'
Le format CSV facilite l'analyse avec des outils comme pgBadger.
Description : Active la collecte de logs dans des fichiers.
Valeur par défaut :
logging_collector = off
Production :
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
Description : Enregistre les requêtes qui dépassent une durée donnée.
Valeur par défaut :
log_min_duration_statement = -1 # Désactivé
Production (détection slow queries) :
log_min_duration_statement = 1000 # 1 seconde
Optimisation poussée :
log_min_duration_statement = 100 # 100 ms
Attention : Une valeur trop basse génère beaucoup de logs.
Description : Préfixe ajouté à chaque ligne de log.
Valeur par défaut :
log_line_prefix = '%m [%p] '
Production (observabilité complète) :
log_line_prefix = '%t [%p]: user=%u,db=%d,app=%a,client=%h '
Format :
%t: Timestamp%p: PID du processus%u: Utilisateur%d: Base de données%a: Nom de l'application%h: Adresse IP du client
Nouveauté : PostgreSQL 18 enrichit les statistiques disponibles.
-- Nouvelles colonnes dans pg_stat_activity (PG 18)
SELECT pid, usename, datname,
backend_type,
wal_records, -- Nouveau
wal_bytes, -- Nouveau
io_time -- Nouveau
FROM pg_stat_activity;Ces statistiques permettent de mieux identifier les backends qui génèrent beaucoup de WAL ou consomment beaucoup d'I/O.
Extension : Enregistre automatiquement les plans d'exécution des requêtes lentes.
-- Charger l'extension
ALTER SYSTEM SET shared_preload_libraries = 'auto_explain';
-- Redémarrer PostgreSQL (nécessaire)
-- Configurer auto_explain
ALTER SYSTEM SET auto_explain.log_min_duration = 1000; -- 1 sec
ALTER SYSTEM SET auto_explain.log_analyze = on;
ALTER SYSTEM SET auto_explain.log_buffers = on; - Capture automatiquement les plans des requêtes lentes
- Facilite le troubleshooting sans intervention manuelle
- Idéal pour identifier les requêtes problématiques en production
Voici une checklist complète pour auditer votre configuration PostgreSQL.
Avant de commencer l'audit, collectez :
- Version PostgreSQL (
SELECT version();) - Système d'exploitation (
uname -aouver) - RAM totale (
free -hou Task Manager) - Nombre de cœurs CPU (
lscpuou Task Manager) - Type de disques (SSD, NVMe, HDD)
- Localisation fichiers config (
SHOW config_file;)
-
shared_buffers: Est-il à ~25% de la RAM ? (max 16GB) -
work_mem: Est-il adapté àmax_connections? -
maintenance_work_mem: Est-il à 5-10% de la RAM ? -
effective_cache_size: Est-il à 50-75% de la RAM ? - Pas de risque d'épuisement RAM :
max_connections × work_mem × 3 < RAM?
Action si problème :
- Ajuster
shared_buffersà 25% RAM - Calculer
work_mem = RAM / (max_connections × 3) - Augmenter
maintenance_work_memà 1-2 GB minimum
-
random_page_cost: Adapté au type de disque (SSD = 1.1, HDD = 4.0) ? -
effective_io_concurrency: Adapté au disque (SSD = 200, NVMe = 300-1000) ? -
max_parallel_workers_per_gather: Adapté au nombre de cœurs ? -
max_parallel_workers: ≥max_parallel_workers_per_gather? -
max_worker_processes: ≥max_parallel_workers?
Action si problème :
- Ajuster
random_page_costselon le stockage - Augmenter
effective_io_concurrencypour SSD/NVMe - Activer parallélisme selon CPU disponibles
-
wal_level:replicaoulogical(pasminimal) ? -
max_wal_size: Suffisant pour éviter "checkpoints too frequently" ? -
min_wal_size: ~25% demax_wal_size? -
checkpoint_timeout: Adapté à la charge d'écriture ? -
checkpoint_completion_target: 0.9 ?
Action si problème :
- Augmenter
max_wal_sizeà 4-16 GB selon charge - Vérifier logs pour "checkpoints too frequently"
- Garder
checkpoint_completion_target = 0.9
-
max_connections: Adapté au nombre de clients ? -
superuser_reserved_connections: 3-5 ? - Connection pooling en place (PgBouncer) si > 100 connexions ?
-
listen_addresses: Configuré selon besoin réseau ? -
port: Standard (5432) ou personnalisé ?
Action si problème :
- Limiter
max_connectionsà 100-200 - Implémenter PgBouncer si beaucoup de connexions
- Configurer
listen_addressesselon architecture réseau
-
autovacuum: ON (jamais OFF) ? -
autovacuum_max_workers: Adapté au nombre de tables ? -
autovacuum_naptime: Adapté à la fréquence de modifications ? -
autovacuum_vacuum_scale_factor: Adapté à la taille des tables ? - Pas de messages "autovacuum too slow" dans les logs ?
Action si problème :
- Vérifier que
autovacuum = on - Augmenter
autovacuum_max_workersà 5-8 - Réduire
autovacuum_vacuum_scale_factorà 0.05-0.1 pour grandes tables - Surveiller bloat avec des requêtes de monitoring
-
password_encryption:scram-sha-256(pas MD5) ? -
ssl: ON en production ? -
ssl_min_protocol_version: TLSv1.2 minimum ? -
pg_hba.conf: Règles strictes (pas detrusten production) ? -
log_connections: ON ? -
log_statement: Au moinsddl?
Action si problème :
- Migrer de MD5 vers SCRAM-SHA-256
- Activer SSL avec certificats valides
- Revoir
pg_hba.confpour durcir l'authentification - Activer logs de connexions
-
io_method:workerouio_uring(nouveauté PG 18) ? -
effective_io_concurrency: Augmenté avecasync? - Checksum activés par défaut (PG 18) ?
Action si problème :
- Activer
io_method = 'worker'pour meilleures performances - Augmenter
effective_io_concurrencypour SSD
-
logging_collector: ON ? -
log_destination: Inclutcsvlog? -
log_min_duration_statement: Défini (500-1000 ms) ? -
log_line_prefix: Inclut timestamp, user, database ? - Rotation des logs configurée ?
Action si problème :
- Activer
logging_collector = on - Configurer rotation des logs (taille et âge)
- Définir
log_min_duration_statementpour capturer slow queries
- Extension
pg_stat_statementsinstallée et activée ? -
shared_preload_libraries: Inclut extensions nécessaires ? - Monitoring en place (Prometheus, pgBadger, etc.) ?
Action si problème :
-- Installer pg_stat_statements
ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';
-- Redémarrer PostgreSQL
CREATE EXTENSION pg_stat_statements;URL : https://pgtune.leopard.in.ua/
Description : Outil en ligne qui génère une configuration PostgreSQL optimisée selon vos ressources et cas d'usage.
Utilisation :
- Indiquez la version PostgreSQL (18)
- Spécifiez le type de disque (SSD, HDD, SAN)
- Choisissez le cas d'usage (Web, OLTP, Data warehouse, Desktop, Mixed)
- Indiquez les ressources (RAM, CPU, connexions)
- PGTune génère une configuration recommandée
Avantages :
- Rapide et gratuit
- Bon point de départ pour une configuration
Limites :
- Configuration générique
- Doit être ajustée selon votre charge réelle
Description : Analyseur de logs PostgreSQL qui génère des rapports détaillés.
Installation :
# Debian/Ubuntu
apt-get install pgbadger
# Ou via CPAN
cpan App::pgBadgerUtilisation :
# Analyser un fichier de logs
pgbadger /var/log/postgresql/postgresql-*.log -o rapport.html
# Ouvrir le rapport
firefox rapport.htmlCe que pgBadger vous montre :
- Requêtes les plus lentes
- Requêtes les plus fréquentes
- Erreurs et warnings
- Connexions et sessions
- Checkpoints et autovacuum
- Locks et deadlocks
Description : Extension PostgreSQL qui enregistre les statistiques d'exécution de toutes les requêtes.
Installation :
-- 1. Modifier postgresql.conf
ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';
-- 2. Redémarrer PostgreSQL
-- 3. Créer l'extension
CREATE EXTENSION pg_stat_statements;Utilisation :
-- Top 10 requêtes les plus lentes
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
-- Top 10 requêtes les plus fréquentes
SELECT query, calls, total_exec_time
FROM pg_stat_statements
ORDER BY calls DESC
LIMIT 10;
-- Réinitialiser les statistiques
SELECT pg_stat_statements_reset();Description : Commande qui affiche les options de compilation de PostgreSQL.
Utilisation :
pg_config --version
pg_config --configure
pg_config --libdir Utile pour vérifier comment PostgreSQL a été compilé et où sont les bibliothèques.
SELECT
sum(heap_blks_read) as heap_read,
sum(heap_blks_hit) as heap_hit,
sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS cache_hit_ratio
FROM pg_statio_user_tables;Objectif : > 0.99 (99%)
SELECT
schemaname,
tablename,
indexrelname,
idx_scan,
idx_tup_read,
idx_tup_fetch
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC; Recherchez : Index avec idx_scan = 0 (inutilisés)
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size,
n_live_tup,
n_dead_tup,
round(n_dead_tup * 100.0 / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY dead_pct DESC; Objectif : dead_pct < 5%
SELECT
substring(query, 1, 100) AS query_short,
calls,
round(mean_exec_time::numeric, 2) AS avg_time_ms,
round(total_exec_time::numeric, 2) AS total_time_ms
FROM pg_stat_statements
WHERE mean_exec_time > 100 -- Plus de 100 ms
ORDER BY mean_exec_time DESC
LIMIT 20; Symptôme :
- Performances I/O très faibles
- Cache hit ratio < 90%
Solution :
shared_buffers = 4GB # Pour 16 GB RAM
Symptôme :
- Messages "temporary file" dans les logs
- Requêtes avec sorts/jointures très lentes
Solution :
work_mem = 64MB # Ajuster selon RAM et connexions
Symptôme :
- Log : "checkpoints are occurring too frequently"
- Pics I/O réguliers
Solution :
max_wal_size = 8GB
checkpoint_timeout = 15min
Symptôme :
- Bloat massif des tables
- Performances qui se dégradent progressivement
- Warnings "transaction ID wraparound"
Solution :
autovacuum = on # NE JAMAIS DÉSACTIVER
Puis lancez un VACUUM manuel :
VACUUM VERBOSE ANALYZE;Symptôme :
- Erreur "FATAL: sorry, too many clients already"
- Performances dégradées avec beaucoup de connexions
Solution :
- Implémentez PgBouncer (connection pooler)
- Réduisez
max_connections:
max_connections = 100
Symptôme :
- Index inutilisés (avec SSD)
- Préférence pour sequential scans même sur petites tables
Solution :
random_page_cost = 1.1 # Pour SSD
Symptôme :
password_encryption = md5oupg_hba.confutilisemd5
Solution :
# postgresql.conf
password_encryption = scram-sha-256
# pg_hba.conf
host all all 0.0.0.0/0 scram-sha-256
Puis réinitialisez les mots de passe :
ALTER USER mon_user PASSWORD 'nouveau_mot_de_passe';Symptôme :
- Impossible de diagnostiquer les problèmes
- Pas de visibilité sur les slow queries
Solution :
logging_collector = on
log_destination = 'stderr,csvlog'
log_min_duration_statement = 1000
log_line_prefix = '%t [%p]: user=%u,db=%d '
Voici les 10 paramètres à auditer en priorité :
shared_buffers: 25% de la RAM (max 16 GB)work_mem: RAM / (max_connections × 3)maintenance_work_mem: 5-10% de la RAMeffective_cache_size: 50-75% de la RAMmax_wal_size: 4-16 GB selon charge d'écriturerandom_page_cost: 1.1 pour SSD, 4.0 pour HDDautovacuum: ON (jamais OFF)max_connections: 100-200 max, utilisez PgBouncer au-delàpassword_encryption: scram-sha-256 (pas MD5)ssl: ON en production
Maintenez un fichier de documentation expliquant :
- Pourquoi chaque paramètre a sa valeur actuelle
- La date de la dernière modification
- Les tests effectués avant/après
- Appliquez les changements sur un environnement de test
- Mesurez les performances avant/après
- Validez qu'il n'y a pas de régression
Ne modifiez jamais plusieurs paramètres simultanément :
- Impossible d'isoler l'impact de chaque changement
- Difficile de revenir en arrière en cas de problème
Après toute modification :
- Surveillez les métriques (CPU, RAM, I/O)
- Vérifiez les logs pour détecter des erreurs
- Observez les temps de réponse des requêtes
Pour les paramètres critiques comme work_mem :
- Commencez par doubler la valeur
- Mesurez l'impact
- Répétez jusqu'à trouver l'optimal
Avant toute modification :
cp postgresql.conf postgresql.conf.backup.$(date +%Y%m%d)ALTER SYSTEM écrit dans postgresql.auto.conf et écrase postgresql.conf.
Préférez :
- Modifier directement
postgresql.conf(tracé dans Git) - Ou documenter chaque
ALTER SYSTEMeffectué
Certains paramètres nécessitent un redémarrage de PostgreSQL :
shared_buffersmax_connectionsshared_preload_libraries
Planifiez ces changements lors d'une fenêtre de maintenance.
Effectuez un audit complet :
- Tous les 3-6 mois pour les systèmes critiques
- Après chaque changement matériel
- Après chaque mise à jour majeure
PostgreSQL évolue constamment (PostgreSQL 18 apporte beaucoup de nouveautés).
Ressources :
- Documentation officielle : https://www.postgresql.org/docs/18/
- Blog Percona PostgreSQL : https://www.percona.com/blog/tag/postgresql/
- Chaîne YouTube Cybertec : https://www.youtube.com/@PostgreSQL
Lors de l'audit d'une instance PostgreSQL 18, portez une attention particulière aux nouveautés :
io_method = 'worker': Activer pour meilleures performances I/Oautovacuum_worker_slots: Permet l'ajustement dynamique des workersautovacuum_vacuum_max_threshold: Plafonne les dead tuples avant VACUUMssl_tls13_ciphers: Configurer pour TLS 1.3
- Checksums activés par défaut : Vérifier la compatibilité
- OAuth 2.0 : Envisager pour authentification moderne
- Virtual Generated Columns : Évaluer pour remplacer certaines colonnes calculées
- UUIDv7 : Considérer pour nouveaux identifiants
PostgreSQL 18 intègre plusieurs optimisations automatiques du planificateur :
- Auto-élimination des self-joins
- Optimisation des OR-clauses
- Skip Scan pour index multi-colonnes
Ces optimisations ne nécessitent aucune configuration, mais soyez conscient qu'elles peuvent changer les plans de requêtes.
Voici une configuration complète pour un serveur PostgreSQL 18 typique :
#------------------------------------------------------------------------------
# POSTGRESQL 18 - CONFIGURATION OPTIMISÉE
# Serveur : 16 GB RAM, 8 CPU cores, SSD NVMe
# Cas d'usage : OLTP web application (mixte lecture/écriture)
# Date : 2025-11-21
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# MÉMOIRE
#------------------------------------------------------------------------------
shared_buffers = 4GB # 25% de 16 GB
work_mem = 50MB # 16GB / (100 connexions × 3)
maintenance_work_mem = 1GB # ~6% de 16 GB
effective_cache_size = 12GB # 75% de 16 GB
#------------------------------------------------------------------------------
# PERFORMANCE
#------------------------------------------------------------------------------
random_page_cost = 1.1 # SSD/NVMe
seq_page_cost = 1.0
effective_io_concurrency = 300 # NVMe
max_parallel_workers_per_gather = 4 # 8 cores disponibles
max_parallel_workers = 8
max_worker_processes = 8
#------------------------------------------------------------------------------
# WAL
#------------------------------------------------------------------------------
wal_level = replica
max_wal_size = 8GB # Charge d'écriture modérée
min_wal_size = 2GB
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
#------------------------------------------------------------------------------
# CONNEXIONS
#------------------------------------------------------------------------------
max_connections = 100
superuser_reserved_connections = 3
listen_addresses = '*'
port = 5432
#------------------------------------------------------------------------------
# AUTOVACUUM
#------------------------------------------------------------------------------
autovacuum = on
autovacuum_max_workers = 5
autovacuum_naptime = 30s
autovacuum_vacuum_scale_factor = 0.1
autovacuum_vacuum_threshold = 50
autovacuum_work_mem = 512MB
#------------------------------------------------------------------------------
# SÉCURITÉ
#------------------------------------------------------------------------------
password_encryption = scram-sha-256
ssl = on
ssl_min_protocol_version = 'TLSv1.2'
ssl_prefer_server_ciphers = on
#------------------------------------------------------------------------------
# I/O (PostgreSQL 18)
#------------------------------------------------------------------------------
io_method = 'worker' # Nouveau : I/O asynchrone
#------------------------------------------------------------------------------
# LOGGING
#------------------------------------------------------------------------------
logging_collector = on
log_destination = 'stderr,csvlog'
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_min_duration_statement = 1000 # 1 seconde
log_line_prefix = '%t [%p]: user=%u,db=%d,app=%a,client=%h '
log_connections = on
log_disconnections = on
log_statement = 'ddl'
#------------------------------------------------------------------------------
# EXTENSIONS
#------------------------------------------------------------------------------
shared_preload_libraries = 'pg_stat_statements'
#------------------------------------------------------------------------------
# FIN DE LA CONFIGURATION
#------------------------------------------------------------------------------
- PostgreSQL 18 Documentation : https://www.postgresql.org/docs/18/
- Server Configuration : https://www.postgresql.org/docs/18/runtime-config.html
- PGTune : https://pgtune.leopard.in.ua/
- pgBadger : https://github.com/darold/pgbadger
- PgBouncer : https://www.pgbouncer.org/
- PostgreSQL: Up and Running par Regina Obe et Leo Hsu
- The Art of PostgreSQL par Dimitri Fontaine
- Reddit : r/PostgreSQL
- Mailing lists : pgsql-general@postgresql.org
- Discord : PostgreSQL Community Server
L'audit de configuration est une étape essentielle pour garantir :
- Performances optimales de votre instance PostgreSQL
- Stabilité en production
- Sécurité des données
- Utilisation efficace des ressources matérielles
Avec PostgreSQL 18, de nouvelles opportunités d'optimisation apparaissent :
- I/O asynchrone pour des performances jusqu'à 3× supérieures
- Autovacuum amélioré avec ajustements dynamiques
- Authentification moderne avec OAuth 2.0
- Checksums par défaut pour meilleure intégrité
N'oubliez pas :
- Auditez régulièrement (tous les 3-6 mois)
- Testez avant de modifier en production
- Documentez vos changements
- Surveillez les impacts après modifications
- Formez-vous continuellement
Avec une configuration bien auditée et optimisée, votre PostgreSQL 18 sera :
- ⚡ Rapide
- 🛡️ Sécurisé
- 💪 Stable
- 📈 Évolutif