PostgreSQL: el problema de los 16 desbloques rápidos y su solución

Fuentes: PostgreSQL: The 16-Quick-Unlock Problem and Its Solution

PostgreSQL aplica un bloqueo de acceso (AccessShareLock) a cada índice de una tabla durante el planificado de cualquier consulta, independientemente de si el índice se utiliza. En tablas con muchos índices, esto genera una alta contención de CPU debido a la saturación de la tabla de desbloques compartida. Hasta la versión 17, el sistema optimizaba esto mediante un 'fast-path' de 16 slots; si una consulta requería más de 16 desbloques, el exceso pasaba por la tabla compartida, causando cuellos de botella en máquinas de muchos núcleos. Esta situación afectaba especialmente a las tablas principales con índices secundarios, degradando el rendimiento global.

La solución técnica varía según la versión. En PostgreSQL 18, el desarrollador Tomas Vondra eliminó el límite fijo de 16 slots, escalando la capacidad del fast-path según el parámetro max_locks_per_transaction (por defecto 64), permitiendo que las consultas complejas usen el fast-path sin preparación previa. Alternativamente, las consultas preparadas resuelven el problema al reutilizar planes de ejecución, evitando el planificado y reduciendo los desbloques a solo los necesarios. Sin embargo, las consultas preparadas presentan limitaciones con conectores como PgBouncer o RDS Proxy. La recomendación final es reducir el número de índices en tablas con alta actividad, ya que cada índice adicional aumenta la contención de memoria compartida y el tiempo de mantenimiento de datos.