Продолжая тему динамических представлений MS SQL Server, в данной статье будет описано как получить информацию о текущих блокировках СУБД.
Для большей информативности, текущая статья использует материал представленный в статье «Получение информации о текущих исполняемых запросах MS SQL Server», поэтому рекомендуется с ней ознакомиться.
Эксперимент
Произведем те же действия что и в приведенной выше статье, а именно:
- Создадим тестовую базу и обработку
- Выполним запись в регистр сведений через обработку и встанем на ожидании, не завершив транзакцию
- В Management Studio выполним запрос выборки всех данных из таблицы регистра сведений
- Получим текущие исполняемые запросы в СУБД
Получение информации о текущих блокировках СУБД
Текущее состояние нашей системы дает возможность выполнить запрос, который вернет информацию о текущих блокировках СУБД. В моем запросе будут использованы следующие представления:
Представление | Описание |
---|---|
dm_tran_locks | Возвращает сведения об активных в данный момент в SQL Server ресурсах диспетчера блокировок |
partitions | Возвращает информацию о секциях |
indexes | Возвращает информацию об индексах |
Текст запроса приведен ниже, а также доступен во вложении к статье:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
SELECT db_name(tl.resource_database_id) AS DB_Name, object_name(p.object_id) AS TableName, si.index_id AS IndexID, si.name AS IndexName, tl.resource_type AS ResourceType, tl.request_mode AS RequestMode, tl.request_type AS RequestType, tl.request_status AS RequestStatus, tl.request_session_id AS RequestSessionID, tl.resource_description AS ResourceDescription FROM sys.dm_tran_locks AS tl left join sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id left join sys.indexes AS si ON p.object_id = si.object_id and p.index_id = si.index_id WHERE tl.resource_database_id = DB_ID('MyBase') /* Condition by DB */ and p.object_id = object_id('_InfoRg243') /* Condition by table */ ORDER BY tl.request_session_id, si.index_id |
В условии отбора «MyBase» — имя базы данных в СУБД; «_InfoRg243» — условие по таблице.
Результат запроса к представлению dm_exec_requests (запрос из статьи, указанной в начале):
Результат запроса к представлению dm_tran_locks:
Описания колонок результата запроса представлены ниже:
Имя колонки | Описание |
---|---|
DB_Name | Имя базы данных к которой выполняется запрос |
TableName | Имя сущности в базе данных, с которой связан ресурс (в примере ожидается имя таблицы) |
IndexID | Идентификатор индекса, связанного с таблицей |
IndexName | Имя индекса, связанного с таблицей |
ResourceType | Тип ресурса |
RequestMode | Запрашиваемый/предоставленный режим запроса |
RequestType | Тип запроса |
RequestStatus | Текущее состояние запроса |
RequestSessionID | Идентификатор сеанса, которому принадлежит этот запрос |
ResourceDescription | Описание ресурса |
Анализ полученного результата
Во-первых, интерпретируем результат запроса к представлению dm_tran_locks независимо от dm_exec_requests:
Как видно, сессия с идентификатором «65» установила (GRANT) на единственный индекс таблицы «_InfoRg243» следующие блокировки: IX на уровне страницы индекса и X на уровне ключа индекса. Как можно догадаться, это тот сеанс, который производит запись в регистр из 1С:Предприятие. Сессия с номером «55» установила (GRANT) блокировку IS на уровне страницы единственного индекса таблицы «_InfoRg243», а S блокировку на уровне ключа записи установить не удалось и поэтому она находится в ожидание (WAIT) до момента освобождения ресурса (или таймаута).
В результате данного запроса нет явного указания на связь заблокированного и блокирующего сеанса, хотя, при желании, сопоставив описания ресурсов, можно сделать вывод об этом. Поэтому, на мой взгляд, при разборе конфликтов блокировок логичнее сначала получить информацию по представлению dm_exec_requests, а затем уже получить информацию о том какие блокировки были установлены/запрошены источником и жертвой.
При таком подходе (сначала dm_exec_requests, затем dm_tran_locks) получим следующую интерпретацию:
Представление | Интерпретация результата |
---|---|
dm_exec_requests | Сеансом с идентификатором «55» (жертва) был отправлен запрос «Select * from dbo._InfoRg243», который встал на ожидании получения S блокировки по ресурсу «KEY: 9:72057594051559424 (227b7397de24)». Блокирующим является сеанс с идентификатором «65» (источник) |
dm_tran_locks | Запрашиваемая блокировка сеанса «55» по ресурсу «227b7397de24»: S блокировка по ключу индекса «_InfoRg243_ByDims_N» таблицы «_InfoRg243». Как видно, причина по которой жертве не удается установить блокировку заключается в том что источник уже установил исключительную блокировку на данный ресурс. Установленная источником блокировка (X) несовместима с блокировкой жертвы (S) |
Причина почему не возникает конфликта блокировок на уровне страниц индекса, несмотря на то что ситуация схожа с блокировкой на уровне ключей, заключается в том что блокировки IS и IX совместимы.