El 24 de marzo, la base de datos Postgres de una empresa alojada en AWS RDS pasó de una carga habitual del 20-40 % de CPU a saturar el procesador al 100 %, con todo el consumo en tiempo de sistema. Los bots no podían unirse a llamadas, los clientes no conseguían respuestas de la API y ni siquiera era posible abrir una sesión psql. Sin despliegues recientes ni incidentes de AWS, el primer intento fue reiniciar la instancia: la operación tardó 60 minutos sin explicación, mientras el negocio permanecía paralizado.
La solución de emergencia llegó al modificar el grupo de seguridad de las decenas de miles de instancias EC2 que accedían a la base de datos para cortarles el acceso, drenar las conexiones pendientes y permitir un reinicio en 40 minutos. Tras la recuperación, el equipo limitó la cuota de conexiones del rol de los bots para reintroducir la carga de forma progresiva.
El análisis de los logs reveló un convoy masivo de bloqueos: 15.000 procesos esperaban un ExclusiveLock sobre la extensión de un índice GIN. Los procesos, despertados al unísono cada segundo por el temporizador de detección de interbloqueos, competían por las particiones del gestor de bloqueos. Como los bloqueos de extensión de relación no pueden formar ciclos de interbloqueo, Postgres realizaba una y otra vez la costosa comprobación sin encontrar nunca un deadlock. Además, con log_lock_waits activado, cada backend generaba líneas de log de más de 10 KB con todos los PIDs en cola, amplificando la carga. El equipo reprodujo el fallo localmente para confirmar el mecanismo.
