DBAtlas · Atlas de operaciones de bases de datos

Análisis de deadlocks

Síntoma

'deadlock detected', 'ORA-00060', 'chosen as deadlock victim': las transacciones se bloquean entre sí y una se aborta.

1. Los deadlocks son normales, pero no deberían ser frecuentes

La BD detecta el deadlock y lo resuelve eligiendo una víctima: esto es por diseño. El objetivo es reducir la frecuencia. La aplicación debe reintentar la transacción víctima. Primero capture el deadlock graph.

2. Obtenga el deadlock graph/detalles

¿Qué dos (o más) sesiones, qué recursos y qué modos de bloqueo entraron en conflicto?

Oracle

-- Check the trace file referenced in the alert log (deadlock graph). Also:
SELECT * FROM dba_hist_active_sess_history WHERE event LIKE 'enq: TX%' ORDER BY sample_time DESC;

PostgreSQL

-- log_lock_waits=on; deadlock details are in postgresql.log. Check the deadlock_timeout setting.

MySQL

SHOW ENGINE INNODB STATUS\G  -- LATEST DETECTED DEADLOCK section

SQL Server

-- Deadlock XML in the system_health Extended Events session (ring_buffer, recent events):
SELECT x.ev.value('@timestamp','datetime2') AS event_time, x.ev.query('.') AS deadlock_xml
FROM (SELECT CAST(t.target_data AS XML) td FROM sys.dm_xe_session_targets t
      JOIN sys.dm_xe_sessions s ON s.address = t.event_session_address
      WHERE s.name = N'system_health' AND t.target_name = N'ring_buffer') r
CROSS APPLY r.td.nodes('//RingBufferTarget/event[@name="xml_deadlock_report"]') AS x(ev);
-- For longer history, the event_file target:
-- SELECT CAST(event_data AS XML) FROM sys.fn_xe_file_target_read_file(N'system_health*.xel', NULL, NULL, NULL) WHERE object_name = N'xml_deadlock_report';

3. Resuelva el patrón de conflicto

La causa más común: dos transacciones que acceden a los recursos en orden OPUESTO. Acceda a los recursos en el MISMO orden en todas las rutas de código. La segunda causa más común: bloqueos de rango amplios por un índice faltante; agregue el índice necesario.

4. Reduzca la duración y el alcance de los bloqueos

Mantenga las transacciones cortas (no incluya interacción del usuario dentro de una transacción). Elija un nivel de aislamiento adecuado. Cuando sea necesario, adquiera los bloqueos de fila temprano (SELECT ... FOR UPDATE con un orden determinista).

5. El reintento en la aplicación es obligatorio

Los deadlocks no se pueden eliminar por completo; implemente el reintento automático (exponential backoff) para la transacción víctima. Así el usuario no ve un error.

Abrir en DBAtlas →