
Vous lancez sudo -u postgres psql, vous tombez sur un prompt postgres=#, et vous tapez des requêtes SQL. Ça fonctionne. Mais qu’est-ce qui tourne en dessous ? Quel processus écoute sur quel port, où sont stockées les données, pourquoi il y a trois bases alors que vous n’en avez créé aucune, et que signifie ce fichier pg_hba.conf qui décide si vous avez le droit de vous connecter ?
PostgreSQL n’est pas une simple base de données — c’est un système complet avec son propre vocabulaire : cluster, instance, schéma, rôle, tablespace, WAL. Beaucoup de ces termes sont trompeurs. Un cluster n’a rien à voir avec la haute disponibilité. Un rôle n’est ni un utilisateur ni un groupe — c’est les deux à la fois. Ce guide démonte la mécanique interne pour que vous compreniez ce que vous administrez avant de toucher à la configuration.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Distinguer cluster, instance, base de données et schéma — les quatre niveaux de la hiérarchie PostgreSQL
- Identifier les processus serveur et comprendre le rôle de chaque background worker
- Expliquer ce que sont les WAL et pourquoi ils sont critiques pour la fiabilité
- Différencier une connexion par socket Unix d’une connexion TCP et savoir laquelle est active
- Lire un
pg_hba.confet comprendre les règles d’authentification
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »Ce guide est le point de départ avant toute administration PostgreSQL. Vous en avez besoin quand :
- Vous installez PostgreSQL pour la première fois et voulez comprendre ce qui a été créé automatiquement
- Vous devez diagnostiquer un problème de connexion (refus d’accès, mauvais socket, port inaccessible)
- Vous voulez séparer les données de plusieurs applications dans des bases ou schémas distincts
- Vous préparez une stratégie de sauvegarde et devez comprendre ce que sont les WAL avant de configurer l’archivage
- Vous lisez la documentation officielle et les termes cluster, PGDATA, backend vous bloquent
Ce guide ne couvre pas…
Section intitulée « Ce guide ne couvre pas… »Ce guide explique l’architecture — il ne configure rien. Les actions pratiques sont dans les guides dédiés :
Le cluster PostgreSQL : pas ce que vous croyez
Section intitulée « Le cluster PostgreSQL : pas ce que vous croyez »Un cluster = un répertoire de données (PGDATA)
Section intitulée « Un cluster = un répertoire de données (PGDATA) »Dans le monde PostgreSQL, cluster ne signifie pas « plusieurs serveurs qui travaillent ensemble ». Un cluster PostgreSQL désigne un répertoire de données unique, géré par un serveur PostgreSQL qui l’ouvre et l’exploite. C’est l’équivalent d’un « moteur de base de données avec toutes ses données locales ».
Analogie : pensez à un cluster comme un coffre-fort. Le coffre contient plusieurs tiroirs (les bases de données), chaque tiroir a des compartiments (les schémas), et il y a un gardien unique (le processus serveur) qui contrôle l’accès.
Sur Debian/Ubuntu, l’installation crée automatiquement un cluster nommé main :
pg_lsclustersVer Cluster Port Status Owner Data directory Log file18 main 5432 online postgres /var/lib/postgresql/18/main /var/log/postgresql/postgresql-18-main.logLa colonne Data directory indique le PGDATA — le répertoire racine du cluster. Tout ce que PostgreSQL stocke (données, configuration interne, WAL) se trouve dans ce répertoire ou est référencé depuis celui-ci.
Ce qu’il contient : bases, WAL, configuration
Section intitulée « Ce qu’il contient : bases, WAL, configuration »Voici le contenu réel du PGDATA sur une installation fraîche de PostgreSQL 18 :
ls -la /var/lib/postgresql/18/main/total 92drwx------ 19 postgres postgres 4096 Apr 13 08:49 .drwxr-xr-x 3 postgres postgres 4096 Apr 13 08:49 ..-rw------- 1 postgres postgres 3 Apr 13 08:49 PG_VERSIONdrwx------ 5 postgres postgres 4096 Apr 13 08:49 basedrwx------ 2 postgres postgres 4096 Apr 13 08:53 globaldrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_commit_tsdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_dynshmemdrwx------ 4 postgres postgres 4096 Apr 13 08:54 pg_logicaldrwx------ 4 postgres postgres 4096 Apr 13 08:49 pg_multixactdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_notifydrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_replslotdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_serialdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_snapshotsdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_statdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_stat_tmpdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_subtransdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_tblspcdrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_twophasedrwx------ 4 postgres postgres 4096 Apr 13 08:49 pg_waldrwx------ 2 postgres postgres 4096 Apr 13 08:49 pg_xact-rw------- 1 postgres postgres 88 Apr 13 08:49 postgresql.auto.conf-rw------- 1 postgres postgres 130 Apr 13 08:49 postmaster.opts-rw------- 1 postgres postgres 108 Apr 13 08:49 postmaster.pidLes éléments essentiels à retenir :
| Élément | Rôle |
|---|---|
PG_VERSION | Indique la version majeure (ici 18) |
base/ | Contient les données de chaque base, un sous-répertoire par OID |
global/ | Tables partagées entre toutes les bases (rôles, tablespaces) |
pg_wal/ | Les fichiers WAL (Write-Ahead Log) — journal de transactions |
pg_tblspc/ | Liens symboliques vers les tablespaces additionnels |
postmaster.pid | Le PID du processus principal — preuve que le serveur tourne |
postgresql.auto.conf | Paramètres modifiés via ALTER SYSTEM (surcharge le .conf) |
Sur Debian/Ubuntu, les fichiers de configuration ne sont pas dans PGDATA mais dans /etc/postgresql/18/main/ :
SELECT name, setting FROM pg_settingsWHERE name IN ('data_directory','config_file','hba_file','ident_file')ORDER BY name; name | setting----------------+----------------------------------------- config_file | /etc/postgresql/18/main/postgresql.conf data_directory | /var/lib/postgresql/18/main hba_file | /etc/postgresql/18/main/pg_hba.conf ident_file | /etc/postgresql/18/main/pg_ident.confCette séparation est une spécificité Debian — sur Red Hat ou en installation depuis les sources, tout est dans PGDATA.
Bases, schémas, tablespaces : la hiérarchie logique
Section intitulée « Bases, schémas, tablespaces : la hiérarchie logique »Base de données vs schéma
Section intitulée « Base de données vs schéma »PostgreSQL organise les objets SQL (tables, vues, fonctions) en trois niveaux :
- Cluster → contient une ou plusieurs bases de données
- Base de données → contient un ou plusieurs schémas
- Schéma → contient les objets SQL (tables, vues, fonctions, séquences)
Analogie : une base de données est un immeuble dans une ville (le cluster). Chaque étage de l’immeuble est un schéma. Les appartements sont les tables. Vous ne pouvez pas prendre l’ascenseur entre deux immeubles — une connexion PostgreSQL cible une seule base à la fois.
Une installation fraîche contient trois bases :
\l List of databases Name | Owner | Encoding | Locale Provider | Collate | Ctype | Locale | ICU Rules | Access privileges-----------+----------+----------+-----------------+---------+---------+--------+-----------+----------------------- postgres | postgres | UTF8 | libc | C.UTF-8 | C.UTF-8 | | | template0 | postgres | UTF8 | libc | C.UTF-8 | C.UTF-8 | | | =c/postgres + | | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | libc | C.UTF-8 | C.UTF-8 | | | =c/postgres + | | | | | | | | postgres=CTc/postgres| Base | Rôle |
|---|---|
postgres | Base par défaut pour l’administration. C’est là où vous atterrissez avec sudo -u postgres psql. |
template1 | Modèle utilisé automatiquement par CREATE DATABASE. Toute modification ici (extensions, schémas) sera héritée par les nouvelles bases. |
template0 | Modèle « propre », jamais modifié. Utilisé pour restaurer une base avec un encoding différent (createdb --template=template0). |
Chaque base correspond à un sous-répertoire dans base/, identifié par son OID (Object Identifier) :
SELECT oid, datname FROM pg_database ORDER BY oid; oid | datname-----+----------- 1 | template1 4 | template0 5 | postgresLe répertoire base/5/ contient donc les fichiers de la base postgres.
Le schéma public : risques du search_path et changements depuis PostgreSQL 15
Section intitulée « Le schéma public : risques du search_path et changements depuis PostgreSQL 15 »Chaque base contient au minimum le schéma public :
\dn+ List of schemas Name | Owner | Access privileges | Description--------+-------------------+----------------------------------------+------------------------ public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema | | =U/pg_database_owner |Quand vous créez une table sans préciser de schéma, PostgreSQL utilise le search_path pour décider où la placer :
SHOW search_path; search_path----------------- "$user", publicPostgreSQL cherche d’abord un schéma portant le nom de l’utilisateur connecté ("$user"), puis le schéma public. Si le schéma personnel n’existe pas, tout tombe dans public.
Bonne pratique : créez un schéma dédié par application (CREATE SCHEMA monapp;) plutôt que de tout mettre dans public. Cela facilite les sauvegardes ciblées, les permissions et la lisibilité.
Tablespaces : séparer données et index (cas d’usage)
Section intitulée « Tablespaces : séparer données et index (cas d’usage) »Un tablespace est un emplacement physique (un répertoire sur le disque) où PostgreSQL peut stocker des fichiers de données en dehors de PGDATA. Cas d’usage typiques : placer les index sur un SSD rapide, les tables d’archive sur un HDD, ou les données temporaires sur un volume dédié.
En pratique, les tablespaces ne sont utiles qu’en production avec des contraintes de performances I/O ou de capacité disque. Vous pouvez ignorer ce concept au début — le tablespace par défaut suffit largement.
Rôles : ni utilisateurs ni groupes (les deux à la fois)
Section intitulée « Rôles : ni utilisateurs ni groupes (les deux à la fois) »LOGIN vs NOLOGIN
Section intitulée « LOGIN vs NOLOGIN »PostgreSQL n’a pas de notion séparée d’« utilisateur » et de « groupe ». Il n’existe qu’un seul concept : le rôle. Un rôle peut se connecter (comme un utilisateur) ou non (comme un groupe), selon qu’il possède l’attribut LOGIN ou NOLOGIN.
\du List of roles Role name | Attributes-----------+------------------------------------------------------------ postgres | Superuser, Create role, Create DB, Replication, Bypass RLSSur une installation fraîche, il n’existe qu’un seul rôle : postgres, le superuser. Il cumule tous les privilèges — c’est l’équivalent de root sous Linux.
Analogie : un rôle PostgreSQL est comme un badge d’accès dans un immeuble. Certains badges permettent d’entrer (LOGIN), d’autres sont des profils de groupe qui donnent accès à certains étages mais ne servent pas à passer le tourniquet (NOLOGIN). Un badge peut hériter des droits d’un autre badge.
Héritage de rôles
Section intitulée « Héritage de rôles »Vous pouvez créer des rôles « groupe » (NOLOGIN) et y rattacher des rôles « utilisateur » (LOGIN) :
-- Rôle groupe : accès lecture seuleCREATE ROLE app_reader NOLOGIN;GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_reader;
-- Rôle utilisateur qui hérite des droits de app_readerCREATE ROLE bob LOGIN PASSWORD '<change-me>' IN ROLE app_reader;Le rôle bob peut se connecter et hérite automatiquement des droits de app_reader. C’est le mécanisme standard pour implémenter le moindre privilège dans PostgreSQL.
Le superuser et pourquoi ne pas s’en servir au quotidien
Section intitulée « Le superuser et pourquoi ne pas s’en servir au quotidien »Le rôle postgres (superuser) contourne toutes les vérifications de permissions. Il peut lire, modifier et supprimer n’importe quelle donnée dans n’importe quelle base. Il peut aussi charger des extensions C arbitraires, modifier la configuration et créer d’autres superusers.
Ne l’utilisez pas pour vos applications. Créez des rôles dédiés avec les permissions minimales nécessaires :
| Rôle | Permissions | Usage |
|---|---|---|
postgres | Superuser — tout | Administration, ALTER SYSTEM, maintenance |
app_owner | Propriétaire du schéma | Migrations, DDL (CREATE TABLE, ALTER) |
app_writer | INSERT, UPDATE, DELETE | Connexion applicative en écriture |
app_reader | SELECT uniquement | Connexion en lecture, reporting, monitoring |
Le guide Sécurisation détaille cette séparation de rôles.
Les processus PostgreSQL
Section intitulée « Les processus PostgreSQL »Le processus principal (accepte les connexions, lance les workers)
Section intitulée « Le processus principal (accepte les connexions, lance les workers) »PostgreSQL fonctionne en multi-processus (pas en multi-thread). Un processus principal (postgres) écoute les connexions et démarre les processus auxiliaires nécessaires au fonctionnement du cluster. Pour chaque client qui se connecte, il crée un processus fils dédié — le backend.
Voici l’arbre des processus sur notre serveur PostgreSQL 18 :
ps auxf | grep postgrespostgres 4323 /usr/lib/postgresql/18/bin/postgres -D /var/lib/postgresql/18/main -c config_file=/etc/postgresql/18/main/postgresql.confpostgres 4324 \_ postgres: 18/main: io worker 0postgres 4325 \_ postgres: 18/main: io worker 2postgres 4326 \_ postgres: 18/main: io worker 1postgres 4327 \_ postgres: 18/main: checkpointerpostgres 4328 \_ postgres: 18/main: background writerpostgres 4330 \_ postgres: 18/main: walwriterpostgres 4331 \_ postgres: 18/main: autovacuum launcherpostgres 4332 \_ postgres: 18/main: logical replication launcherLe processus principal (PID 4323) lance les background workers au démarrage. Ils restent actifs en permanence.
Backend workers (un par connexion)
Section intitulée « Backend workers (un par connexion) »Lorsqu’un client se connecte (via psql, une application, un outil de monitoring), PostgreSQL crée un backend dédié pour cette session. Ce processus exécute les requêtes SQL du client et disparaît à la déconnexion.
SELECT pid, usename, application_name, client_addr, backend_type, stateFROM pg_stat_activity WHERE backend_type = 'client backend'; pid | usename | application_name | client_addr | backend_type | state------+----------+------------------+-------------+----------------+-------- 4744 | postgres | psql | | client backend | activeLe champ client_addr est vide — la connexion passe par un socket Unix local, pas par TCP. Chaque backend consomme de la mémoire, mais attention : work_mem n’est pas réservé une fois par connexion. C’est une limite par opération interne de tri ou de hachage, qui peut se multiplier sur une requête complexe et sur plusieurs sessions concurrentes. C’est pourquoi le paramètre max_connections existe : limiter le nombre de processus simultanés pour éviter l’épuisement mémoire.
Background workers (autovacuum, WAL writer, checkpointer, archiver)
Section intitulée « Background workers (autovacuum, WAL writer, checkpointer, archiver) »Les background workers sont des processus permanents qui assurent le bon fonctionnement interne :
| Processus | Rôle |
|---|---|
| checkpointer | Écrit périodiquement les données modifiées (dirty pages) du cache vers le disque. Garantit un point de reprise cohérent. |
| background writer | Écrit les pages modifiées en avance pour réduire la charge lors des checkpoints. |
| walwriter | Écrit les enregistrements WAL du cache vers les fichiers pg_wal/. |
| autovacuum launcher | Déclenche le nettoyage automatique des lignes mortes et met à jour les statistiques. |
| logical replication launcher | Gère les workers de réplication logique (si configurée). |
| io worker (PG 18+) | Nouveauté PostgreSQL 18 : workers d’I/O asynchrones pour paralléliser les lectures/écritures disque. Améliore les performances sur les systèmes multi-cœurs. |
Flux d’une requête du client au disque
Section intitulée « Flux d’une requête du client au disque »Quand vous exécutez un INSERT INTO clients VALUES (...), voici ce qui se passe :
-
Le client envoie la requête au backend dédié via le socket Unix ou TCP
-
Le backend écrit dans le WAL — l’opération est journalisée avant toute modification des données (Write-Ahead Logging)
-
Le walwriter écrit le WAL sur disque (flush). À ce moment, l’opération est durable même en cas de crash
-
Le backend modifie les pages en mémoire (shared buffers). Les données sont maintenant visibles par les autres connexions
-
Le checkpointer écrira ces pages sur disque lors du prochain checkpoint. Entre-temps, les WAL garantissent la récupération
Ce mécanisme explique pourquoi PostgreSQL redémarre dans un état cohérent après un crash : il rejoue les WAL nécessaires pour remettre les fichiers de données en phase avec les transactions durablement enregistrées. En configuration non durable (comme avec synchronous_commit = off), les toutes dernières transactions validées côté client mais pas encore flushées sur disque peuvent toutefois être perdues.
Connexions : socket Unix vs TCP
Section intitulée « Connexions : socket Unix vs TCP »Connexion locale (peer, socket)
Section intitulée « Connexion locale (peer, socket) »Par défaut, psql se connecte via un socket Unix — un fichier spécial sur le disque qui permet la communication entre processus sans passer par le réseau :
ls -la /var/run/postgresql/srwxrwxrwx 1 postgres postgres 0 Apr 13 08:49 .s.PGSQL.5432-rw------- 1 postgres postgres 69 Apr 13 08:49 .s.PGSQL.5432.lock-rw-r--r-- 1 postgres postgres 5 Apr 13 08:49 18-main.pidLe fichier .s.PGSQL.5432 est le socket. Le numéro correspond au port. Quand vous exécutez sudo -u postgres psql, la connexion passe par ce socket et utilise l’authentification peer : PostgreSQL vérifie que l’utilisateur système (postgres) correspond au rôle demandé.
Avantages du socket Unix :
- Pas de mot de passe avec l’authentification peer
- Plus rapide que TCP (pas de couche réseau)
- Plus sûr — pas d’exposition réseau
Connexion réseau (host, hostssl, scram-sha-256)
Section intitulée « Connexion réseau (host, hostssl, scram-sha-256) »Pour les connexions depuis un autre serveur ou une application distante, PostgreSQL écoute sur TCP. Par défaut sur Debian, il n’écoute que sur localhost :
# Connexion TCP locale — nécessite un mot de passepsql -h 127.0.0.1 -U postgresCette connexion passe par TCP et pg_hba.conf exige une authentification scram-sha-256 (un mot de passe hashé). Contrairement au socket, l’identité de l’utilisateur système ne suffit pas.
Où ça se configure : pg_hba.conf
Section intitulée « Où ça se configure : pg_hba.conf »Le fichier pg_hba.conf (Host-Based Authentication) contrôle qui peut se connecter, depuis où, et comment. Voici les lignes actives sur une installation fraîche :
local all postgres peerlocal all all peerhost all all 127.0.0.1/32 scram-sha-256host all all ::1/128 scram-sha-256local replication all peerhost replication all 127.0.0.1/32 scram-sha-256host replication all ::1/128 scram-sha-256Lecture ligne par ligne :
| Type | Base | Utilisateur | Adresse | Méthode | Signification |
|---|---|---|---|---|---|
local | all | postgres | — | peer | Connexion socket : le rôle postgres est authentifié par le système |
local | all | all | — | peer | Connexion socket : tout rôle ayant un utilisateur système correspondant |
host | all | all | 127.0.0.1/32 | scram-sha-256 | Connexion TCP locale : mot de passe hashé requis |
host | all | all | ::1/128 | scram-sha-256 | Idem en IPv6 |
Le guide Sécurisation détaille comment écrire un pg_hba.conf restrictif, activer TLS et configurer scram-sha-256.
Les WAL en 5 minutes
Section intitulée « Les WAL en 5 minutes »Écriture séquentielle avant modification des données
Section intitulée « Écriture séquentielle avant modification des données »Les WAL (Write-Ahead Logs) sont le mécanisme de journalisation de PostgreSQL. Le principe est simple : toute modification est d’abord écrite dans le journal (WAL) avant d’être appliquée aux fichiers de données. C’est une écriture séquentielle, donc performante.
Analogie : imaginez un cahier de brouillon (le WAL) et un classeur (les données). Avant de ranger un document dans le classeur, vous notez l’opération dans le brouillon. Si quelqu’un renverse le classeur (crash), vous pouvez tout reconstituer en relisant le brouillon.
Les fichiers WAL se trouvent dans pg_wal/ :
ls /var/lib/postgresql/18/main/pg_wal/000000010000000000000001archive_statussummariesChaque fichier WAL fait 16 Mo par défaut. Le position courante d’écriture (LSN — Log Sequence Number) indique où PostgreSQL en est :
SELECT pg_current_wal_lsn(); pg_current_wal_lsn-------------------- 0/17A6148Pourquoi c’est la base de tout : crash recovery, réplication, PITR
Section intitulée « Pourquoi c’est la base de tout : crash recovery, réplication, PITR »Les WAL servent à trois fonctions critiques :
| Fonction | Comment ça marche |
|---|---|
| Crash recovery | Au redémarrage après un crash, PostgreSQL rejoue les WAL depuis le dernier checkpoint pour retrouver un état cohérent. Les transactions dont les WAL ont été flushés sont garanties. |
| Réplication | Un serveur standby reçoit les WAL du primary et les rejoue en continu. C’est le principe de la streaming replication. |
| PITR (Point-In-Time Recovery) | En archivant les WAL, vous pouvez restaurer une base à n’importe quel instant — “je veux l’état de ma base à 14h32 mardi dernier”. |
À retenir
Section intitulée « À retenir »- Un cluster PostgreSQL = un répertoire PGDATA + un serveur PostgreSQL. Ce n’est pas de la haute disponibilité.
- Sur Debian/Ubuntu, les fichiers de configuration (
postgresql.conf,pg_hba.conf) sont dans/etc/postgresql/18/main/, pas dans PGDATA. - Trois bases existent par défaut :
postgres(administration),template1(modèle pour CREATE DATABASE),template0(modèle propre). - Un schéma est un espace de noms dans une base. Depuis PostgreSQL 15, le schéma
publicest restreint au propriétaire de la base. - Un rôle remplace utilisateurs et groupes. L’attribut LOGIN permet la connexion, NOLOGIN crée un rôle groupe.
- PostgreSQL fonctionne en multi-processus : un processus principal, des workers permanents, et un backend par client connecté.
- Les io workers sont une nouveauté PostgreSQL 18 — ils parallélisent les opérations d’I/O disque.
- Les connexions locales passent par un socket Unix (peer, pas de mot de passe). Les connexions distantes utilisent TCP (scram-sha-256).
- Les WAL (Write-Ahead Logs) journalisent toute modification avant écriture. Ils permettent le crash recovery, la réplication et le PITR.