Erreur PostgreSQL : out of shared memory

ERROR:  out of shared memory
HINT:  You might need to increase max_locks_per_transaction.

Malgré la formulation alarmante, il ne s'agit presque jamais du serveur qui manque de mémoire en général. Quand elle s'accompagne du hint max_locks_per_transaction, elle signifie une chose précise : la table de verrous partagée — la structure de taille fixe où PostgreSQL suit les verrous sur les tables, index et autres objets — est pleine.

Ce que signifie cette erreur

La table de verrous est dimensionnée au démarrage du serveur, avec de la place pour environ max_locks_per_transaction × (max_connections + max_prepared_transactions) verrous d'objet. Deux propriétés expliquent tout ce que vous observerez :

Chaque table, partition et index touché par une requête a besoin de sa propre entrée de verrou, conservée jusqu'à la fin de la transaction. C'est l'arithmétique qui vous piège : une requête sur une table de 2 000 partitions avec quelques index chacune peut nécessiter plusieurs milliers d'entrées — alors que le dimensionnement par défaut (64 × ~100 connexions) vous en donne environ 6 400 pour tout le serveur.

Causes fréquentes

Comment la diagnostiquer

Pendant que la charge de travail en échec s'exécute (ou juste avant qu'elle échoue) :

-- À quel point la table de verrous est pleine :
SELECT count(*) FROM pg_locks;

-- Qui consomme les entrées :
SELECT pid, count(*)
FROM pg_locks
GROUP BY pid
ORDER BY count(*) DESC
LIMIT 10;

Comparez le total à la formule ci-dessus avec vos réglages. Si un pid détient des milliers de verrous, regardez ce qu'il exécute — et si des partitions sont impliquées, comptez-les : SELECT count(*) FROM pg_inherits WHERE inhparent = 'events'::regclass;

Comment la corriger

🔍 À lire aussi : Comment lire EXPLAIN ANALYZE — le plan vous montre si l'élagage des partitions a réellement eu lieu.