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 sectionSQL 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.