Quick Answer
LCK_M_BU_ABORT_BLOCKERS occurs when a task waits to acquire a Bulk Update lock with the ABORT_AFTER_WAIT=BLOCKERS option, introduced in SQL Server 2014. This wait appears during ALTER TABLE or ALTER INDEX operations configured to kill blocking sessions after the wait timeout expires. It's typically not concerning unless wait times exceed the configured timeout threshold.
Root Cause Analysis
This wait type emerges from SQL Server's implementation of the low priority wait mechanism for DDL operations. When ALTER TABLE or ALTER INDEX includes WAIT_AT_LOW_PRIORITY with ABORT_AFTER_WAIT=BLOCKERS, the operation requests a Bulk Update (BU) lock but defers acquisition until blocking sessions complete or the timeout expires.
The lock manager places the request in a special queue with reduced priority. During this phase, the session exhibits LCK_M_BU_ABORT_BLOCKERS waits while the scheduler periodically checks if blocking conditions have cleared. The BU lock provides shared access for readers while preventing concurrent schema modifications, making it essential for online index operations and table alterations.
SQL Server 2014 introduced this mechanism specifically to address blocking chains during maintenance windows. Unlike traditional lock waits that queue indefinitely, this implementation includes timeout logic within the lock manager itself. When the timeout expires, the lock manager identifies blocking sessions through sys.dm_tran_locks and terminates them via the KILL mechanism.
The wait accumulates in sys.dm_os_wait_stats during the entire timeout period, not just during active blocking scenarios. This behavior differs from standard lock waits that only register time spent actually waiting for resources.
Version-specific behavior remains consistent from SQL Server 2014 through 2022, though lock manager efficiency improvements in SQL Server 2019 reduced overhead for tracking these specialized wait states.
AutoDBA checks Blocking session detection, DDL operation monitoring, and low priority wait configurations across your entire SQL Server instance in 60 seconds. Download the free diagnostic script and see what else needs attention.
Diagnostic Queries
-- Check current sessions with LCK_M_BU_ABORT_BLOCKERS waits
SELECT
s.session_id,
s.wait_type,
s.wait_time,
s.blocking_session_id,
t.text AS current_statement,
s.cpu_time,
s.logical_reads
FROM sys.dm_exec_requests s
CROSS APPLY sys.dm_exec_sql_text(s.sql_handle) t
WHERE s.wait_type = 'LCK_M_BU_ABORT_BLOCKERS'
ORDER BY s.wait_time DESC;
-- Identify blocking chains affecting BU lock requests
WITH blocking_tree AS (
SELECT
session_id,
blocking_session_id,
wait_type,
wait_resource,
wait_time,
0 AS level
FROM sys.dm_exec_requests
WHERE blocking_session_id = 0
AND session_id IN (
SELECT DISTINCT blocking_session_id
FROM sys.dm_exec_requests
WHERE blocking_session_id != 0
)
UNION ALL
SELECT
r.session_id,
r.blocking_session_id,
r.wait_type,
r.wait_resource,
r.wait_time,
b.level + 1
FROM sys.dm_exec_requests r
INNER JOIN blocking_tree b ON r.blocking_session_id = b.session_id
WHERE r.blocking_session_id != 0
)
SELECT * FROM blocking_tree
WHERE EXISTS (
SELECT 1 FROM sys.dm_exec_requests
WHERE wait_type = 'LCK_M_BU_ABORT_BLOCKERS'
AND blocking_session_id IN (SELECT session_id FROM blocking_tree)
);
-- Check ALTER operations with low priority wait settings
SELECT
r.session_id,
r.command,
r.percent_complete,
r.estimated_completion_time,
t.text,
r.wait_type,
r.wait_time
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.command LIKE 'ALTER%'
OR t.text LIKE '%WAIT_AT_LOW_PRIORITY%'
ORDER BY r.start_time;
-- Analyze historical wait patterns for this wait type
SELECT
wait_type,
waiting_tasks_count,
wait_time_ms,
max_wait_time_ms,
signal_wait_time_ms,
wait_time_ms / NULLIF(waiting_tasks_count, 0) AS avg_wait_ms
FROM sys.dm_os_wait_stats
WHERE wait_type = 'LCK_M_BU_ABORT_BLOCKERS'
AND waiting_tasks_count > 0;
-- Find objects involved in BU lock conflicts
SELECT
l.resource_database_id,
DB_NAME(l.resource_database_id) AS database_name,
l.resource_associated_entity_id,
OBJECT_NAME(l.resource_associated_entity_id, l.resource_database_id) AS object_name,
l.resource_type,
l.resource_description,
l.request_mode,
l.request_type,
l.request_session_id
FROM sys.dm_tran_locks l
WHERE l.request_mode = 'BU'
OR l.request_session_id IN (
SELECT session_id
FROM sys.dm_exec_requests
WHERE wait_type = 'LCK_M_BU_ABORT_BLOCKERS'
);
Fix Scripts
Increase timeout duration for ALTER operations
-- Modify existing ALTER statement to use longer timeout
-- Replace existing WAIT_AT_LOW_PRIORITY clause
-- TEST IN DEVELOPMENT FIRST - this affects blocking behavior
ALTER INDEX IX_YourIndex ON YourTable REBUILD
WITH (ONLINE = ON,
WAIT_AT_LOW_PRIORITY (MAX_DURATION = 10 MINUTES,
ABORT_AFTER_WAIT = BLOCKERS));
-- Increases timeout from default to 10 minutes
-- Kills blocking sessions after timeout expires
-- Monitor for killed session impacts
Kill specific blocking sessions manually
-- Identify and terminate sessions blocking BU lock acquisition
-- CAUTION: This terminates active user sessions
DECLARE @BlockingSessionId INT;
SELECT @BlockingSessionId = blocking_session_id
FROM sys.dm_exec_requests
WHERE wait_type = 'LCK_M_BU_ABORT_BLOCKERS'
AND blocking_session_id > 0;
IF @BlockingSessionId IS NOT NULL
BEGIN
-- Verify session is safe to kill before executing
SELECT
session_id,
login_name,
program_name,
host_name,
last_request_start_time
FROM sys.dm_exec_sessions
WHERE session_id = @BlockingSessionId;
-- Uncomment next line only after verification
-- KILL @BlockingSessionId;
END
Switch to SELF termination mode
-- Change ALTER operation to kill itself instead of blockers
-- Safer option that avoids terminating user sessions
ALTER INDEX IX_YourIndex ON YourTable REBUILD
WITH (ONLINE = ON,
WAIT_AT_LOW_PRIORITY (MAX_DURATION = 5 MINUTES,
ABORT_AFTER_WAIT = SELF));
-- Operation cancels itself after timeout
-- No impact on blocking sessions
-- May require retry during low activity period
Implement retry logic with exponential backoff
-- Retry ALTER operation with increasing timeout values
DECLARE @AttemptCount INT = 1;
DECLARE @MaxAttempts INT = 3;
DECLARE @TimeoutMinutes INT = 2;
WHILE @AttemptCount <= @MaxAttempts
BEGIN
BEGIN TRY
DECLARE @SQL NVARCHAR(MAX) =
'ALTER INDEX IX_YourIndex ON YourTable REBUILD ' +
'WITH (ONLINE = ON, ' +
'WAIT_AT_LOW_PRIORITY (MAX_DURATION = ' +
CAST(@TimeoutMinutes AS VARCHAR(10)) + ' MINUTES, ' +
'ABORT_AFTER_WAIT = SELF))';
EXEC sp_executesql @SQL;
BREAK; -- Success, exit loop
END TRY
BEGIN CATCH
SET @AttemptCount = @AttemptCount + 1;
SET @TimeoutMinutes = @TimeoutMinutes * 2; -- Double timeout
WAITFOR DELAY '00:01:00'; -- Wait 1 minute between attempts
END CATCH
END
AutoDBA generates fix scripts like these automatically, with impact estimates and rollback SQL included.
Prevention
Schedule ALTER TABLE and ALTER INDEX operations during maintenance windows when user activity is minimal. This reduces the likelihood of encountering blocking sessions that trigger the timeout mechanism.
Configure appropriate MAX_DURATION values based on historical blocking patterns. Query sys.dm_os_wait_stats regularly to establish baseline wait times for your workload, then set timeouts 2-3 times higher than typical blocking durations.
Use ABORT_AFTER_WAIT = SELF instead of BLOCKERS for non-critical maintenance operations. This approach prevents terminating user sessions while still providing timeout functionality. Reserve BLOCKERS mode for critical operations that must complete within specific windows.
Implement connection pooling with shorter connection timeouts to reduce long-running idle transactions that commonly cause blocking. Configure applications to use READ_COMMITTED_SNAPSHOT isolation level where appropriate to minimize reader-writer conflicts.
Monitor blocking chains proactively using Extended Events or custom monitoring solutions. Create alerts when blocking duration exceeds thresholds, allowing manual intervention before ALTER operations reach their timeout limits.
Consider partitioning strategies for large tables to reduce the scope of ALTER operations. Partition-level index rebuilds generate smaller lock footprints and shorter blocking windows compared to full table operations.
Need hands-on help?
Dealing with persistent lck_m_bu_abort_blockers issues across your environment? Samix Technology provides hands-on SQL Server performance consulting with 15+ years of production DBA experience.