Найти и удалить блокировки в Microsoft SQL Server
Блокировки в MS SQL Server — это один из способов обеспечить целостность данных при одновременном внесении изменений несколькими пользователями. MSSQL блокирует объекты в таблице при запуске транзакции и снимает блокировку при завершении транзакции. В этой статье мы научимся находить блокировки в базе данных MS SQL Server и снимать их.
Можно смоделировать блокировку одной из таблиц, используя незавершенную транзакцию (не завершенную откатом или фиксацией). Например, используйте следующий SQL-запрос:
USE tesdb1
BEGIN TRANSACTION
DELETE TOP(1) FROM tblStudentsПрежде чем будут внесены какие-либо изменения, SQL Server заблокирует таблицу. Теперь попробуйте открыть SQL Server Management Studio и выполнить простой запрос SQL:
SELECT * FROM tblStudentsЗапрос заморозится в состоянии «Выполнение запроса», пока не истечет время ожидания. Это связано с тем, что запрос SELECT пытается получить доступ к данным в таблице, заблокированной SQL Server.
В Microsoft SQL Server можно настроить блокировки на уровне строк или на уровне всей таблицы.
Чтобы получить список всех заблокированных запросов в MSSQL Server, выполните команду
select cmd,* from sys.sysprocesses
where blocked > 0Вы также можете отобразить список блокировок для конкретной базы данных:
SELECT * FROM master.dbo.sysprocesses
WHERE
dbid = DB_ID('testdb12') and blocked <> 0
order by blockedВ столбце Заблокировано отображается идентификатор процесса, который заблокировал ресурсы. Он также показывает время ожидания для этого запроса (время ожидания в миллисекундах). При необходимости это можно использовать для поиска самых ранних или последних блокировок.
В некоторых случаях блокировка может быть вызвана всем деревом процессов. Чтобы найти процесс блокировки источника, используйте следующий запрос для SPID, пока не найдете процесс с blocked=0, который является начальным процессом, удерживающим блокировку.
select * FROM
master.dbo.sysprocesses
where 1=1
--and blocked <> 0
and spid = 59SPID процесса дает вам код T-SQL последнего SQL-запроса, выполненного этим процессом или транзакцией:
DBCC INPUTBUFFER(59)Чтобы принудительно завершить процесс и снять блокировку, выполните команду:
KILL number_of_session
GOВ моем случае это будет:
KILL 59
Вы можете создать отдельную хранимую процедуру, если блокировки возникают постоянно и вы хотите выявить наиболее ресурсоемкие запросы:
CREATE PROCEDURE GetCurrentQueryCode
@SPID int
AS
DECLARE @sql_handle binary(20), @stmt_start int, @stmt_end int
SELECT @sql_handle = sql_handle, @stmt_start = stmt_start/2, @stmt_end = CASE WHEN stmt_end = -1 THEN -1 ELSE stmt_end/2 END
FROM master.dbo.sysprocesses
WHERE spid = @SPID AND ecid = 0
DECLARE @line nvarchar(4000)
SET @line = (SELECT SUBSTRING([text], COALESCE(NULLIF(@stmt_start, 0), 1),
CASE @stmt_end WHEN -1 THEN DATALENGTH([text]) ELSE (@stmt_end - @stmt_start) END) FROM ::fn_get_sql(@sql_handle))
print @lineТеперь, если вы хотите увидеть SQL-запрос, заблокировавший таблицу, все, что вам нужно сделать, это указать его SPID:
Exec GetCurrentQueryCode 51Вы также можете получить код запроса из sql_handle процесса блокировки. Например
select * from sys.dm_exec_sql_text (0x0100050069139B0650B35EA64702000000000000)Вы можете использовать Microsoft SQL Server Management Studio для поиска блокировок в MS SQL Server. Вы можете использовать один из следующих методов:
Щелкните сервер правой кнопкой мыши, откройте Монитор активности и разверните Процессы. Вы увидите список запросов, ожидающих освобождения ресурсов, со статусом SUSPENDED.
Выберите базу данных и перейдите в раздел Отчеты -> Все блокирующие транзакции. Он также показывает список заблокированных запросов и SPID источника блокировки.







