🔝 Retour au Sommaire
Le terme "Bare Metal" (littéralement "métal nu") désigne l'installation de PostgreSQL directement sur un serveur physique, sans couche de virtualisation intermédiaire. C'est la méthode de déploiement la plus traditionnelle et la plus proche du matériel.
Analogie simple : Imaginez que vous possédez une voiture. Le déploiement bare metal, c'est conduire votre propre voiture (contrôle total), alors que la virtualisation reviendrait à louer une voiture ou utiliser un taxi (moins de contrôle, mais plus de flexibilité).
| Critère | Bare Metal | VM | Conteneurs | Cloud Managé |
|---|---|---|---|---|
| Performance | ⭐⭐⭐⭐⭐ Maximale | ⭐⭐⭐⭐ Très bonne | ⭐⭐⭐⭐ Très bonne | ⭐⭐⭐ Variable |
| Contrôle | ⭐⭐⭐⭐⭐ Total | ⭐⭐⭐⭐ Élevé | ⭐⭐⭐ Moyen | ⭐⭐ Limité |
| Coût initial | ⭐ Élevé | ⭐⭐⭐ Moyen | ⭐⭐⭐⭐ Faible | ⭐⭐⭐⭐⭐ Très faible |
| Scalabilité | ⭐⭐ Limitée | ⭐⭐⭐⭐ Bonne | ⭐⭐⭐⭐⭐ Excellente | ⭐⭐⭐⭐⭐ Excellente |
| Maintenance | ⭐⭐ Exigeante | ⭐⭐⭐ Moyenne | ⭐⭐⭐⭐ Facilitée | ⭐⭐⭐⭐⭐ Minimale |
Situations idéales pour le bare metal :
-
Charges critiques à haute performance
- Applications financières nécessitant une latence minimale
- Systèmes transactionnels à très haut débit (>10 000 transactions/seconde)
- Bases de données volumineuses (plusieurs téraoctets)
-
Besoins de contrôle total
- Optimisation fine du matériel et du système
- Configurations réseau complexes
- Respect de réglementations strictes (données sensibles, souveraineté)
-
Prévisibilité des ressources
- Charges de travail stables et prévisibles
- Budget opérationnel maîtrisé sur le long terme
- Absence de besoin d'élasticité rapide
-
Contraintes de conformité
- Interdiction de cloud public (secteur bancaire, santé, défense)
- Nécessité de conserver les données physiquement sur site
- Certifications spécifiques (ISO 27001, HDS, PCI-DSS)
Quand éviter le bare metal :
- Startup en phase de croissance rapide
- Charges de travail très variables
- Équipe technique limitée
- Budget d'investissement initial restreint
Recommandations générales :
PostgreSQL bénéficie d'une architecture multi-cœurs pour gérer plusieurs connexions simultanées. Cependant, chaque requête individuelle n'utilise généralement qu'un seul cœur (sauf opérations parallélisées).
Configuration idéale selon le cas d'usage :
- CPU recommandé : 16 à 32 cœurs physiques
- Fréquence : Privilégier la fréquence élevée (3.0+ GHz)
- Architecture : Intel Xeon Gold ou AMD EPYC
- Exemple : Intel Xeon Gold 6348 (28 cœurs @ 2.6 GHz, boost 3.5 GHz)
Pourquoi ? De nombreuses petites requêtes simultanées nécessitent beaucoup de cœurs. La fréquence haute accélère chaque requête individuelle.
- CPU recommandé : 32 à 64 cœurs physiques
- Fréquence : Acceptable à 2.5+ GHz
- Architecture : AMD EPYC (meilleur rapport cœurs/prix)
- Exemple : AMD EPYC 7543 (32 cœurs @ 2.8 GHz)
Pourquoi ? Les requêtes analytiques peuvent être parallélisées (PostgreSQL 18 améliore cette capacité). Plus de cœurs = plus de parallélisme.
- CPU recommandé : 24 à 48 cœurs physiques
- Fréquence : 2.8+ GHz
- Équilibre : Intel Xeon Platinum ou AMD EPYC
Point technique important : Désactiver l'Hyper-Threading peut parfois améliorer les performances PostgreSQL, car il préfère les cœurs physiques aux threads logiques.
La RAM est cruciale pour PostgreSQL. Plus vous en avez, meilleures seront vos performances, car PostgreSQL garde en mémoire :
- Les données fréquemment consultées (shared_buffers)
- Les résultats intermédiaires de requêtes (work_mem)
- Les index
- Les statistiques du planificateur
Formule de base :
RAM totale = Taille de la base de données active × 0.25 + Overhead PostgreSQL + Overhead OS
Exemple concret :
- Base de données : 400 GB
- Données "chaudes" (fréquemment consultées) : ~100 GB
- RAM recommandée : 64 à 128 GB
| Usage | RAM Minimale | RAM Idéale | Justification |
|---|---|---|---|
| Développement/Test | 8 GB | 16 GB | Données limitées |
| OLTP Léger | 16 GB | 32 GB | Nombreuses connexions |
| OLTP Production | 64 GB | 128 GB | Hot dataset en mémoire |
| OLAP/Data Warehouse | 128 GB | 256+ GB | Requêtes complexes gourmandes |
| Mixte Haute Performance | 128 GB | 512+ GB | Tout en mémoire idéalement |
Type de RAM : Privilégier ECC (Error-Correcting Code) pour la fiabilité en production. La RAM ECC détecte et corrige automatiquement les erreurs de mémoire.
Vitesse : DDR4-3200 MHz minimum, DDR5 si disponible. L'impact de la fréquence mémoire est modéré mais non négligeable.
Le stockage est souvent le goulot d'étranglement principal de PostgreSQL. Les performances I/O (Input/Output) conditionnent directement les temps de réponse.
- Performance : ⭐⭐⭐⭐⭐ Excellente
- Latence : < 100 µs (microsecondes)
- IOPS : 500 000 à 1 000 000+ en lecture aléatoire
- Bande passante : 3 000 à 7 000 MB/s
- Usage : Production haute performance, OLTP exigeant
- Exemples : Samsung PM9A3, Intel P5800X, Micron 7450
Avantage PostgreSQL 18 : Le nouveau sous-système I/O asynchrone (AIO) exploite pleinement les NVMe pour des gains jusqu'à 3× sur certaines charges.
- Performance : ⭐⭐⭐⭐ Bonne
- Latence : < 500 µs
- IOPS : 50 000 à 100 000
- Bande passante : 500 à 600 MB/s
- Usage : Production standard, petit budget
- Exemples : Samsung 870 EVO, Crucial MX500
- Performance : ⭐⭐ Médiocre
- Latence : 5 à 10 ms (millisecondes !)
- IOPS : 100 à 200 seulement
- Usage : Archivage, sauvegardes uniquement
- Pourquoi éviter ? PostgreSQL génère beaucoup d'I/O aléatoires, domaine où les HDD sont catastrophiques.
Configuration recommandée en production :
Serveur PostgreSQL (Bare Metal)
├── Disque 1 (NVMe) : Système d'exploitation (OS)
│ └── 100-200 GB
├── Disques 2-3 (NVMe en RAID 1) : Données PostgreSQL (PGDATA)
│ └── Selon volume de données
├── Disques 4-5 (NVMe en RAID 1) : WAL (Write-Ahead Log)
│ └── 50-100 GB minimum
└── Disques 6-N (SATA/HDD) : Sauvegardes et archives
└── 2-3× taille des données
Séparation des WAL : Placer les WAL sur des disques dédiés réduit la contention I/O et améliore les performances transactionnelles.
| RAID | Redondance | Performance Lecture | Performance Écriture | Usage PostgreSQL |
|---|---|---|---|---|
| RAID 0 | ❌ Aucune | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | |
| RAID 1 | ✅ Mirroring | ⭐⭐⭐⭐ | ⭐⭐⭐ | ✅ WAL, petites bases |
| RAID 5 | ✅ Parité | ⭐⭐⭐⭐ | ⭐⭐ | |
| RAID 10 | ✅ Stripe+Mirror | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ Recommandé pour PGDATA |
| RAID 6 | ✅ Double parité | ⭐⭐⭐ | ⭐⭐ | 🔧 Archives, sauvegardes |
Configuration idéale en production :
- PGDATA : RAID 10 (4 à 8 disques NVMe)
- WAL : RAID 1 (2 disques NVMe dédiés)
- Sauvegardes : RAID 6 ou pas de RAID (backups multiples)
Contrôleur RAID : Privilégier un contrôleur matériel avec cache BBU (Battery Backup Unit) de 2 à 4 GB pour sécuriser les écritures en cas de coupure.
- Carte réseau : 10 GbE minimum (25 GbE ou 40 GbE pour haute performance)
- Connectivité : Redondance réseau (bonding/teaming) pour la haute disponibilité
- Latence : < 1 ms sur le réseau local (LAN)
-
Séparation des réseaux :
┌─────────────────────────────────┐ │ Serveur PostgreSQL Bare Metal │ ├─────────────────────────────────┤ │ eth0: Réseau de production │ → Connexions clients │ eth1: Réseau de réplication │ → Streaming vers standby │ eth2: Réseau de sauvegarde │ → Transferts pg_basebackup │ eth3: Réseau d'administration │ → SSH, monitoring └─────────────────────────────────┘ -
Jumbo Frames : Activer les trames de 9000 bytes (MTU) pour améliorer le débit réseau sur connexions 10 GbE+
-
TCP Tuning : Ajustement des paramètres kernel pour PostgreSQL (voir section OS)
Distributions Linux recommandées :
-
Ubuntu Server LTS (22.04 ou 24.04)
- ✅ Support officiel PostgreSQL excellent
- ✅ Documentation abondante
- ✅ Packages maintenus par PGDG (PostgreSQL Global Development Group)
- 🎯 Recommandé pour débutants
-
Rocky Linux / AlmaLinux (successeurs de CentOS)
- ✅ Stabilité enterprise
- ✅ Cycle de vie long (10 ans)
- 🎯 Recommandé pour production conservatrice
-
Debian
- ✅ Très stable
- ✅ Léger en ressources
- 🎯 Recommandé pour experts
-
Red Hat Enterprise Linux (RHEL)
- ✅ Support commercial
- ✅ Certifications
- 💰 Payant
À éviter en production : Distributions non-LTS, rolling release (Arch, Fedora), ou expérimentales.
Créer le fichier /etc/sysctl.d/99-postgresql.conf :
# Gestion de la mémoire partagée
# Permet à PostgreSQL d'allouer de grands segments de mémoire partagée
kernel.shmmax = 68719476736 # 64 GB (ajuster selon RAM)
kernel.shmall = 4294967296 # Pages mémoire
# Swappiness : éviter le swap au maximum
# Valeur 0-100, plus c'est bas, moins le kernel utilise le swap
vm.swappiness = 1
# Dirty pages : contrôle de l'écriture sur disque
# Pourcentage de RAM avant flush forcé
vm.dirty_ratio = 10
vm.dirty_background_ratio = 3
# Éviter l'OOM Killer de tuer PostgreSQL
vm.overcommit_memory = 2
vm.overcommit_ratio = 80 Explications pour débutants :
-
Mémoire partagée (shmmax/shmall) : PostgreSQL utilise de la mémoire partagée entre tous ses processus. Il faut autoriser le système à allouer suffisamment.
-
Swappiness : Le "swap" est l'utilisation du disque comme extension de la RAM. C'est TRÈS lent. On configure le système pour éviter au maximum de "swapper".
-
Dirty pages : Les données modifiées en RAM (pages "sales") doivent être écrites sur disque. On contrôle quand et comment ces écritures se produisent pour éviter des pics d'I/O soudains.
-
Overcommit : Linux peut promettre plus de mémoire qu'il n'en a (overcommit). Si la RAM est saturée, le système peut tuer des processus (OOM Killer). On configure pour protéger PostgreSQL.
Ajouter au même fichier /etc/sysctl.d/99-postgresql.conf :
# Buffer TCP/IP pour connexions nombreuses
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 4194304
# Backlog de connexions
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
# Réutilisation rapide des sockets TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
# Keepalive TCP (détection rapide de connexions mortes)
net.ipv4.tcp_keepalive_time = 200
net.ipv4.tcp_keepalive_intvl = 20
net.ipv4.tcp_keepalive_probes = 3 Appliquer les changements :
sudo sysctl -p /etc/sysctl.d/99-postgresql.confModifier /etc/security/limits.d/postgresql.conf :
# Utilisateur PostgreSQL
postgres soft nofile 65536 # Descripteurs de fichiers
postgres hard nofile 65536
postgres soft nproc 65536 # Nombre de processus
postgres hard nproc 65536
postgres soft memlock unlimited # Mémoire verrouillée
postgres hard memlock unlimited Pourquoi ? PostgreSQL peut gérer des milliers de connexions, chacune nécessitant des descripteurs de fichiers (connexions réseau, fichiers ouverts).
| Filesystem | Performance | Fiabilité | Recommandation |
|---|---|---|---|
| ext4 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ Recommandé (défaut, éprouvé) |
| XFS | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ✅ Excellent (gros volumes) |
| btrfs | ⭐⭐⭐ | ⭐⭐⭐ | |
| ZFS | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 🔧 Complexe (nécessite expertise) |
Recommandation générale : ext4 pour débuter, XFS si vous avez de très gros volumes (>10 TB).
Fichier /etc/fstab pour la partition PostgreSQL :
# Partition PGDATA (exemple avec /dev/sda2 monté sur /var/lib/postgresql)
UUID=xxx /var/lib/postgresql ext4 noatime,nodiratime,nobarrier 0 2
# Partition WAL (si séparée)
UUID=yyy /var/lib/postgresql/18/main/pg_wal ext4 noatime,nodiratime,nobarrier 0 2Explications des options :
- noatime : Ne met pas à jour l'heure du dernier accès aux fichiers. Économise des écritures inutiles.
- nodiratime : Même principe pour les répertoires.
- nobarrier : Désactive les barrières d'écriture (
⚠️ uniquement si batterie BBU sur contrôleur RAID ou UPS).
nobarrier améliore les performances mais risque de corruption en cas de coupure électrique soudaine. N'utiliser que si infrastructure électrique fiable (UPS + BBU).
Emplacement : /etc/postgresql/18/main/postgresql.conf (Ubuntu) ou /var/lib/postgresql/18/data/postgresql.conf
# =====================================
# CONNEXIONS
# =====================================
max_connections = 200
# Débutant : 100-200 connexions pour OLTP typique
# Avancé : Utiliser PgBouncer pour pooling, limiter à 100-150 ici
# =====================================
# MÉMOIRE
# =====================================
# Shared Buffers : Cache principal de PostgreSQL
# Règle : 25% de la RAM totale (max 40%)
shared_buffers = 32GB # Pour 128 GB RAM
# Explication : PostgreSQL garde les données fréquentes ici
# Work Memory : Mémoire par opération de tri/hash
# Règle : (RAM totale × 0.25) / max_connections
work_mem = 64MB # Pour 128 GB RAM et 200 connexions
# Explication : Chaque tri, hash join utilise cette mémoire
# ⚠️ Trop élevé = risque OOM avec beaucoup de connexions
# Maintenance Work Memory : Pour VACUUM, CREATE INDEX, etc.
# Règle : 5-10% de la RAM, jusqu'à 2 GB
maintenance_work_mem = 2GB
# Explication : Accélère les opérations de maintenance
# Effective Cache Size : Informe le planificateur de la RAM disponible
# Règle : 50-75% de la RAM totale
effective_cache_size = 96GB # Pour 128 GB RAM
# Explication : Pas une allocation, juste une indication pour le planificateur# =====================================
# WAL (Write-Ahead Log)
# =====================================
# Niveau de journalisation
wal_level = replica
# Options : minimal, replica, logical
# 'replica' permet la réplication streaming
# Taille maximale du WAL
max_wal_size = 16GB # Augmenter pour réduire les checkpoints
min_wal_size = 4GB
# Compression WAL (PostgreSQL 18+)
wal_compression = zstd # Nouveau : zstd plus performant que lz4
# Réduit l'espace disque et améliore les performances I/O
# Slots de réplication (si réplication prévue)
max_wal_senders = 5
max_replication_slots = 5 # =====================================
# CHECKPOINTS
# =====================================
# Délai maximum entre checkpoints
checkpoint_timeout = 15min # Défaut : 5min (trop court)
# Augmenter réduit les I/O mais rallong le crash recovery
# Ratio de complétion
checkpoint_completion_target = 0.9
# Étale les écritures sur 90% de l'intervalle checkpoint
# Avertissement si checkpoints trop fréquents
checkpoint_warning = 60s
# Log un warning si checkpoints < 60s (signe de sous-dimensionnement)# =====================================
# I/O ASYNCHRONE (PostgreSQL 18)
# =====================================
# Méthode I/O : 'sync', 'worker' (défaut PG18), ou 'io_uring' (Linux)
io_method = 'worker'
# 'worker' : I/O asynchrone via processus dédiés (multi-plateforme)
# 'io_uring' : performances maximales sur Linux kernel 5.1+
# Gain : jusqu'à 3× de performance sur NVMe
# Workers I/O asynchrones
io_async_workers = 16
# Règle : Nombre de cœurs CPU / 2
# Profondeur de file I/O
io_async_queue_depth = 256
# Pour NVMe, 256-512 optimalNote pour débutants : L'I/O asynchrone est une nouveauté majeure de PostgreSQL 18. Elle permet de lancer plusieurs opérations disque en parallèle au lieu de les faire séquentiellement. C'est une révolution de performance sur matériel moderne.
# =====================================
# PARALLÉLISATION
# =====================================
# Nombre de workers parallèles par requête
max_parallel_workers_per_gather = 4
# Dépend du type de charge (OLAP : 8-16, OLTP : 2-4)
# Nombre total de workers parallèles
max_parallel_workers = 16
# Règle : Nombre de cœurs CPU / 2
# Workers pour maintenance
max_parallel_maintenance_workers = 4
# Pour CREATE INDEX, VACUUM parallélisés# =====================================
# AUTOVACUUM (PostgreSQL 18 améliore)
# =====================================
autovacuum = on # Toujours activé !
# Workers autovacuum (PostgreSQL 18 améliore dynamiquement)
autovacuum_max_workers = 6
# Nouveauté PG 18 : ajustement dynamique possible
# Seuil maximum (nouveau dans PG 18)
autovacuum_vacuum_max_threshold = 10000000
# Empêche les VACUUM trop massifs d'une traite
# Coût et délai
autovacuum_vacuum_cost_delay = 2ms # Ralentir pour éviter impact I/O
autovacuum_vacuum_cost_limit = 800 # Budget "coût" par round # =====================================
# LOGGING
# =====================================
# Destination des logs
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = 1d
log_rotation_size = 100MB
# Contenu des logs
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_timezone = 'UTC'
# Requêtes lentes
log_min_duration_statement = 1000 # Log requêtes > 1s
log_statement = 'ddl' # Log toutes les DDL (CREATE, DROP, etc.)
# Checkpoints et verrous
log_checkpoints = on
log_lock_waits = on # Log attentes de verrous > deadlock_timeout
deadlock_timeout = 1s
# Auto-explain (extension à activer)
shared_preload_libraries = 'pg_stat_statements,auto_explain'
auto_explain.log_min_duration = 5000 # EXPLAIN AUTO des requêtes > 5s
auto_explain.log_analyze = on
auto_explain.log_buffers = on # =====================================
# SÉCURITÉ
# =====================================
# Écoute réseau
listen_addresses = '0.0.0.0' # Toutes interfaces (sécuriser via firewall)
# Production : IP spécifique, ex: '10.0.1.50'
port = 5432
# SSL/TLS
ssl = on
ssl_cert_file = '/etc/postgresql/18/main/server.crt'
ssl_key_file = '/etc/postgresql/18/main/server.key'
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
ssl_prefer_server_ciphers = on
# PostgreSQL 18 : Configuration TLS 1.3
ssl_min_protocol_version = 'TLSv1.2'
ssl_tls13_ciphers = 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256'
# Data Checksums (PG 18 : activé par défaut à l'initdb)
# Détection de corruption de données
data_checksums = onFichier : /etc/postgresql/18/main/pg_hba.conf
Exemple de configuration sécurisée :
# TYPE DATABASE USER ADDRESS METHOD
# Connexion locale (socket Unix)
local all postgres peer
# Connexion localhost (boucle locale)
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
# Réseau interne (adapter selon votre réseau)
host all all 10.0.0.0/8 scram-sha-256
# Réplication (depuis serveur standby)
host replication replicator 10.0.1.51/32 scram-sha-256
# Refuser tout le reste
host all all 0.0.0.0/0 reject
Explications pour débutants :
- TYPE :
local(socket Unix),host(TCP/IP),hostssl(SSL obligatoire) - DATABASE : Nom de la base ou
all - USER : Utilisateur PostgreSQL ou
all - ADDRESS : Adresse IP/réseau autorisé
- METHOD : Mode d'authentification
trust: aucun mot de passe (⚠️ JAMAIS en production)scram-sha-256: hash sécurisé (recommandé)md5: obsolète (déprécié en PG 18)cert: certificat client SSL
Nouveauté PostgreSQL 18 : Support OAuth 2.0 pour authentification moderne (intégration SSO).
UFW (Ubuntu) :
# Autoriser SSH
sudo ufw allow 22/tcp
# Autoriser PostgreSQL uniquement depuis réseau interne
sudo ufw allow from 10.0.0.0/8 to any port 5432
# Activer le firewall
sudo ufw enableFirewallD (Rocky/RHEL) :
# Zone interne
sudo firewall-cmd --permanent --zone=internal --add-source=10.0.0.0/8
sudo firewall-cmd --permanent --zone=internal --add-service=postgresql
sudo firewall-cmd --reload Principe : Appliquer les patches de sécurité régulièrement, mais de manière contrôlée.
Procédure recommandée :
- Surveiller les CVE : S'abonner à la liste de diffusion PostgreSQL security
- Tester en pré-production : Ne jamais patcher directement en production
- Fenêtre de maintenance : Planifier les mises à jour
- Sauvegarde préalable : Toujours sauvegarder avant toute intervention
Mise à jour mineure (ex: 18.1 → 18.2) :
# Sauvegarde
sudo -u postgres pg_dump -Fc dbname > /backup/dbname_before_update.dump
# Mise à jour des paquets
sudo apt update && sudo apt upgrade postgresql-18
# Redémarrage (downtime < 1 minute généralement)
sudo systemctl restart postgresqlCPU :
# Charge moyenne
uptime
# Target : load average < nombre de cœurs
# Utilisation par processus
top -u postgresMémoire :
# Utilisation globale
free -h
# Éviter le swap !
vmstat 1
# si > si/so > 0 : problème de swapDisque :
# Utilisation espace
df -h /var/lib/postgresql
# I/O en temps réel
iostat -x 1
# Surveiller : %util (< 80%), await (< 10ms pour SSD)Connexions actives :
SELECT count(*) FROM pg_stat_activity WHERE state = 'active';
-- Target : < 80% de max_connectionsCache hit ratio (doit être > 99%) :
SELECT
sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0) * 100 AS cache_hit_ratio
FROM pg_statio_user_tables;Taille des bases :
SELECT
datname,
pg_size_pretty(pg_database_size(datname)) AS size
FROM pg_database
ORDER BY pg_database_size(datname) DESC; Tables les plus volumineuses :
SELECT
schemaname || '.' || tablename AS table_fullname,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC
LIMIT 10; Extension indispensable pour identifier les requêtes lentes.
-- En tant que superuser
CREATE EXTENSION pg_stat_statements;
-- Top 10 requêtes les plus lentes
SELECT
query,
calls,
total_exec_time / 1000 AS total_time_sec,
mean_exec_time / 1000 AS mean_time_sec,
stddev_exec_time / 1000 AS stddev_time_sec
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10; Avantages :
- Portable entre versions PostgreSQL
- Restauration sélective (table par table)
- Fichier compressé
Inconvénients :
- Lente sur grosses bases (>100 GB)
- Charge la base pendant le dump
Script automatisé :
#!/bin/bash
# /usr/local/bin/backup_postgres.sh
BACKUP_DIR="/backup/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)
DATABASE="mydb"
# Création répertoire
mkdir -p "$BACKUP_DIR"
# Dump compressé
pg_dump -U postgres -Fc "$DATABASE" > "$BACKUP_DIR/${DATABASE}_${DATE}.dump"
# Rotation (garder 7 jours)
find "$BACKUP_DIR" -name "${DATABASE}_*.dump" -mtime +7 -delete
# Vérification
if [ $? -eq 0 ]; then
echo "Backup OK : ${DATABASE}_${DATE}.dump"
else
echo "Backup FAILED !" | mail -s "PostgreSQL Backup Error" admin@example.com
fiCron quotidien (3h du matin) :
0 3 * * * /usr/local/bin/backup_postgres.sh >> /var/log/backup.log 2>&1Avantages :
- Très rapide (copie fichiers)
- Permet PITR (Point-In-Time Recovery)
- Base de la réplication
Inconvénients :
- Volumineuse (toute l'instance)
- Même version majeure PostgreSQL obligatoire
Commande :
pg_basebackup -h localhost -U replicator -D /backup/base_$(date +%Y%m%d) -Fp -Xs -P -RRègle d'or des sauvegardes :
- 3 copies de vos données
- 2 médias différents (ex: disque local + NAS)
- 1 copie hors site (ex: cloud, datacenter distant)
Exemple d'architecture :
Serveur Bare Metal PostgreSQL
├─ Données en production (RAID 10)
│
├─ Backup 1 : Disques locaux dédiés (RAID 6)
│ └─ pg_dump quotidien + pg_basebackup hebdo
│
├─ Backup 2 : NAS réseau
│ └─ Synchronisation rsync des backups locaux
│
└─ Backup 3 : Cloud (S3, Azure Blob, etc.)
└─ Envoi chiffré des backups critiques
- CPU : 16-32+ cœurs, fréquence 2.8+ GHz
- RAM : 64-256 GB avec ECC
- Stockage : NVMe en RAID 10 pour PGDATA, RAID 1 pour WAL
- Réseau : 10+ GbE avec redondance
- Alimentation : UPS pour protection coupures
- OS : Ubuntu Server LTS / Rocky Linux
- Kernel : Paramètres sysctl optimisés (swappiness, dirty_ratio)
- Filesystem : ext4 ou XFS avec noatime
- Limites : nofile, nproc augmentés pour utilisateur postgres
- Sécurité : Firewall configuré, SELinux/AppArmor actif
- Version : PostgreSQL 18 installé depuis dépôt officiel PGDG
- Mémoire : shared_buffers, work_mem, maintenance_work_mem ajustés
- WAL : wal_level=replica, compression zstd activée
- I/O : io_method='worker' ou 'io_uring' configuré (PostgreSQL 18)
- Autovacuum : Actif avec paramètres adaptés
- Logging : auto_explain et pg_stat_statements activés
- SSL/TLS : Certificats configurés, TLS 1.2+ minimum
- pg_hba.conf : SCRAM-SHA-256 obligatoire, accès restreints
- Rôles : Principe du moindre privilège appliqué
- Data Checksums : Activés (défaut PG 18)
- Sauvegardes : Stratégie 3-2-1 implémentée
- Monitoring : Supervision active (Prometheus/Grafana ou équivalent)
- pg_stat_statements : Extension installée et configurée
- Alertes : Seuils définis (connexions, cache, disque, réplication)
- Logs : Rotation active, analyse automatisée (pgBadger)
- Métriques système : CPU, RAM, I/O, réseau supervisés
-
Performance maximale
- Accès direct au matériel sans overhead de virtualisation
- Latence minimale (critique pour OLTP haute fréquence)
- I/O optimal, surtout avec PostgreSQL 18 et I/O asynchrone
-
Contrôle total
- Configuration kernel et matériel sur mesure
- Pas de "voisins bruyants" (noisy neighbors) comme en cloud
- Déterminisme des performances
-
Coût prévisible
- Investissement initial, puis coût fixe mensuel (électricité, hébergement)
- Pas de facturation à l'usage
- ROI intéressant sur 3-5 ans pour charges stables
-
Conformité
- Données restent sur infrastructure contrôlée
- Audits simplifiés
- Respect des réglementations strictes (RGPD, HDS, etc.)
-
Scalabilité limitée
- Montée en charge nécessite achat matériel (délais)
- Impossible de scaler élastiquement comme en cloud
- Capacité maximale fixée par le hardware
-
Coût initial élevé
- Investissement matériel important (10 000 - 100 000€+)
- Nécessite infrastructure datacenter (racks, climatisation, électricité)
-
Maintenance lourde
- Gestion matérielle (pannes disque, RAM défectueuse)
- Mises à jour hardware complexes
- Équipe technique nécessaire 24/7
-
Pas de haute disponibilité native
- Nécessite architecture complexe (réplication, Patroni, load balancing)
- Single Point of Failure si pas de réplication
- Disaster Recovery plus difficile qu'en cloud
Le déploiement bare metal de PostgreSQL reste la référence en termes de performance brute et de contrôle total. Avec PostgreSQL 18 et ses améliorations I/O asynchrones, les gains de performance sur matériel moderne (NVMe, CPU multi-cœurs) sont spectaculaires.
Quand choisir bare metal ?
- ✅ Charges critiques à haute performance
- ✅ Conformité réglementaire stricte
- ✅ Charges stables et prévisibles
- ✅ Équipe technique expérimentée
Quand privilégier d'autres solutions ?
- ❌ Startup en croissance rapide → Cloud managé
- ❌ Charges très variables → Cloud élastique
- ❌ Équipe technique limitée → DBaaS (RDS, Azure, etc.)
- ❌ Besoin de multi-région rapide → Cloud avec réplication globale
Points clés à retenir :
- L'optimisation matérielle (CPU, RAM, NVMe) est cruciale
- La configuration OS (kernel, filesystem) impacte directement les performances
- PostgreSQL 18 apporte des gains majeurs (I/O async, autovacuum amélioré)
- La sécurité et les sauvegardes ne sont PAS négociables
- Le monitoring continu est indispensable
Un déploiement bare metal bien configuré peut servir des millions de transactions par jour avec une latence sub-milliseconde. Mais il nécessite expertise et rigueur opérationnelle.
Prochaines étapes suggérées :
- 19.1.2. Virtual Machines (VM)
- 19.1.3. Conteneurs (Docker, Podman)
- 19.1.4. Kubernetes (StatefulSets, Operators)
-
- Administration, Configuration et Sécurité (approfondissement)