Quick Answer
LCK_M_U_ABORT_BLOCKERS occurs when a task waits for an Update lock using the ABORT_BLOCKERS priority mechanism introduced in SQL Server 2014. This wait type appears exclusively during ALTER TABLE and ALTER INDEX operations with LOW_PRIORITY options that eventually escalate to terminate blocking sessions.
Root Cause Analysis
This wait type exists within SQL Server's lock manager when DDL operations use the LOW_PRIORITY wait option with ABORT_BLOCKERS. The lock manager implements a three-phase escalation: first attempting normal priority acquisition, then waiting for the specified duration, and finally executing the abort blockers phase.
During the abort blockers phase, the lock manager's deadlock monitor component identifies sessions holding incompatible locks and marks them for termination. The requesting session enters LCK_M_U_ABORT_BLOCKERS state while the scheduler coordinates this termination process. The update lock request remains queued until blocking transactions complete or are killed.
SQL Server 2014 introduced this mechanism specifically for online index rebuilds and table alterations where minimal downtime is critical. The lock manager maintains a priority queue where ABORT_BLOCKERS requests eventually supersede normal priority requests. In SQL Server 2016 and later, the implementation became more aggressive in identifying and terminating long-running queries that block these high-priority DDL operations.
The wait occurs after the initial LOW_PRIORITY timeout expires but before the DDL operation acquires the necessary schema modification locks. During this window, the lock manager systematically terminates blocking sessions based on their transaction start times and lock compatibility matrices.
AutoDBA checks LOW_PRIORITY DDL configurations, lock timeout thresholds, and index maintenance scheduling across your entire SQL Server instance in 60 seconds. Download the free diagnostic script and see what else needs attention.
Diagnostic Queries
-- Identify current LCK_M_U_ABORT_BLOCKERS waits and their blocking chains
SELECT
ws.session_id,
ws.wait_type,
ws.wait_duration_ms,
ws.blocking_session_id,
r.command,
r.percent_complete,
s.program_name,
t.text AS current_sql
FROM sys.dm_exec_requests r
INNER JOIN sys.dm_os_waiting_tasks ws ON r.session_id = ws.session_id
INNER JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE ws.wait_type = 'LCK_M_U_ABORT_BLOCKERS';
-- Find active LOW_PRIORITY DDL operations and their current phase
SELECT
r.session_id,
r.command,
r.percent_complete,
r.estimated_completion_time,
r.wait_type,
r.last_wait_type,
t.text AS ddl_statement
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.command LIKE '%ALTER%'
AND (t.text LIKE '%LOW_PRIORITY%' OR t.text LIKE '%ABORT_BLOCKERS%');
-- Examine lock requests and their priorities in the wait queue
SELECT
lr.request_session_id,
lr.resource_type,
lr.resource_database_id,
lr.resource_associated_entity_id,
lr.request_mode,
lr.request_type,
lr.request_status,
s.program_name,
s.login_name
FROM sys.dm_tran_locks lr
INNER JOIN sys.dm_exec_sessions s ON lr.request_session_id = s.session_id
WHERE lr.request_status = 'WAIT'
AND EXISTS (
SELECT 1 FROM sys.dm_os_waiting_tasks w
WHERE w.session_id = lr.request_session_id
AND w.wait_type = 'LCK_M_U_ABORT_BLOCKERS'
);
-- Monitor sessions that will be terminated by ABORT_BLOCKERS
SELECT
s.session_id,
s.login_name,
s.program_name,
s.host_name,
r.start_time,
r.total_elapsed_time,
t.text AS blocking_query
FROM sys.dm_exec_sessions s
INNER JOIN sys.dm_exec_requests r ON s.session_id = r.session_id
INNER JOIN sys.dm_tran_locks l ON s.session_id = l.request_session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE l.request_session_id IN (
SELECT DISTINCT blocking_session_id
FROM sys.dm_os_waiting_tasks
WHERE wait_type = 'LCK_M_U_ABORT_BLOCKERS'
);
Fix Scripts
Immediate Relief: Cancel the DDL Operation
-- Kill the ALTER operation causing ABORT_BLOCKERS wait
-- WARNING: This terminates the DDL operation, potentially leaving objects in inconsistent state
DECLARE @session_id INT;
SELECT @session_id = ws.session_id
FROM sys.dm_os_waiting_tasks ws
WHERE ws.wait_type = 'LCK_M_U_ABORT_BLOCKERS';
IF @session_id IS NOT NULL
BEGIN
PRINT 'Terminating session ' + CAST(@session_id AS VARCHAR(10));
EXEC('KILL ' + @session_id);
END
Manual Blocking Session Termination
-- Terminate sessions that are blocking the LOW_PRIORITY operation
-- Use with extreme caution in production, may cause transaction rollbacks
DECLARE @BlockingSessionId INT;
DECLARE blocking_cursor CURSOR FOR
SELECT DISTINCT blocking_session_id
FROM sys.dm_os_waiting_tasks
WHERE wait_type = 'LCK_M_U_ABORT_BLOCKERS'
AND blocking_session_id IS NOT NULL
AND blocking_session_id > 50; -- Avoid system sessions
OPEN blocking_cursor;
FETCH NEXT FROM blocking_cursor INTO @BlockingSessionId;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Killing blocking session: ' + CAST(@BlockingSessionId AS VARCHAR(10));
EXEC('KILL ' + @BlockingSessionId);
FETCH NEXT FROM blocking_cursor INTO @BlockingSessionId;
END
CLOSE blocking_cursor;
DEALLOCATE blocking_cursor;
Modify DDL Operation Timeout
-- Example of restarting the operation with different LOW_PRIORITY settings
-- Adjust MAX_DURATION and ABORT_AFTER_WAIT based on your maintenance window
/*
ALTER INDEX [IX_YourIndex] ON [dbo].[YourTable]
REBUILD
WITH (
ONLINE = ON,
SORT_IN_TEMPDB = ON,
MAXDOP = 4,
FILLFACTOR = 90,
LOW_PRIORITY (
MAX_DURATION = 10 MINUTES,
ABORT_AFTER_WAIT = BLOCKERS -- Options: NONE, SELF, BLOCKERS
)
);
*/
AutoDBA generates fix scripts like these automatically, with impact estimates and rollback SQL included.
Prevention
Configure DDL operations with appropriate LOW_PRIORITY timeouts based on your application's transaction patterns. Set MAX_DURATION to values that align with typical query completion times, typically 1-5 minutes for OLTP systems and 10-30 minutes for analytical workloads.
Implement application-level connection timeouts shorter than your LOW_PRIORITY MAX_DURATION to prevent indefinite blocking scenarios. This ensures user queries complete or timeout before DDL operations enter the ABORT_BLOCKERS phase.
Schedule index maintenance during maintenance windows when possible, avoiding LOW_PRIORITY altogether for planned operations. Use LOW_PRIORITY only for emergency schema changes during business hours.
Monitor sys.dm_tran_locks regularly during DDL operations to identify potential blocking chains before they trigger ABORT_BLOCKERS escalation. Implement alerts when lock wait times exceed thresholds that would trigger the abort phase.
Consider using ABORT_AFTER_WAIT = SELF instead of BLOCKERS when the DDL operation can be safely retried, preserving existing transactions at the cost of postponing the schema change.
Need hands-on help?
Dealing with persistent lck_m_u_abort_blockers issues across your environment? Samix Technology provides hands-on SQL Server performance consulting with 15+ years of production DBA experience.