Errore PostgreSQL: out of shared memory

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

Nonostante la formulazione allarmante, quasi mai riguarda il server che esaurisce la memoria in generale. Quando arriva con l'hint max_locks_per_transaction, significa una cosa specifica: la tabella dei lock condivisa — la struttura a dimensione fissa dove PostgreSQL traccia i lock su tabelle, indici e altri oggetti — è piena.

Cosa significa questo errore

La tabella dei lock è dimensionata all'avvio del server, con spazio per circa max_locks_per_transaction × (max_connections + max_prepared_transactions) lock su oggetti. Due proprietà spiegano tutto ciò che osserverai:

Ogni tabella, partizione e indice toccato da una query ha bisogno del proprio lock entry, tenuto fino alla fine della transazione. È questa l'aritmetica che ti frega: una query su una tabella con 2.000 partizioni e qualche indice ciascuna può richiedere molte migliaia di entry — mentre il dimensionamento di default (64 × ~100 connessioni) te ne dà circa 6.400 per l'intero server.

Cause comuni

Come diagnosticarlo

Mentre il carico problematico gira (o subito prima che fallisca):

-- Quanto è pieno il lock table:
SELECT count(*) FROM pg_locks;

-- Chi sta consumando le entry:
SELECT pid, count(*)
FROM pg_locks
GROUP BY pid
ORDER BY count(*) DESC
LIMIT 10;

Confronta il totale con la formula qui sopra usando le tue impostazioni. Se un solo pid tiene migliaia di lock, guarda cosa sta eseguendo — e se sono coinvolte partizioni, contale: SELECT count(*) FROM pg_inherits WHERE inhparent = 'events'::regclass;

Come risolverlo

🔍 Lettura correlata: Come leggere EXPLAIN ANALYZE — il piano ti mostra se il partition pruning è effettivamente avvenuto.