Error de PostgreSQL: out of shared memory

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

A pesar de la formulación alarmante, esto casi nunca tiene que ver con que el servidor se quede sin memoria en general. Cuando viene con el hint sobre max_locks_per_transaction, significa una cosa concreta: la tabla de bloqueos compartida — la estructura de tamaño fijo donde PostgreSQL rastrea los bloqueos sobre tablas, índices y otros objetos — está llena.

Qué significa este error

La tabla de bloqueos se dimensiona al arrancar el servidor, con espacio para aproximadamente max_locks_per_transaction × (max_connections + max_prepared_transactions) bloqueos de objeto. Dos propiedades explican todo lo que observarás:

Cada tabla, partición e índice tocado por una consulta necesita su propia entrada de bloqueo, sostenida hasta el final de la transacción. Esa es la aritmética que te atrapa: una consulta sobre una tabla con 2.000 particiones y unos cuantos índices cada una puede necesitar muchos miles de entradas — mientras que el dimensionamiento por defecto (64 × ~100 conexiones) te da unas 6.400 para todo el servidor.

Causas comunes

Cómo diagnosticarlo

Mientras se ejecuta la carga de trabajo que falla (o justo antes de que falle):

-- Cuán llena está la tabla de bloqueos:
SELECT count(*) FROM pg_locks;

-- Quién está consumiendo las entradas:
SELECT pid, count(*)
FROM pg_locks
GROUP BY pid
ORDER BY count(*) DESC
LIMIT 10;

Compara el total con la fórmula de arriba usando tus ajustes. Si un pid sostiene miles de bloqueos, mira qué está ejecutando — y si hay particiones implicadas, cuéntalas: SELECT count(*) FROM pg_inherits WHERE inhparent = 'events'::regclass;

Cómo solucionarlo

🔍 Lectura relacionada: Cómo leer EXPLAIN ANALYZE — el plan te muestra si la poda de particiones realmente ocurrió.