SQL Server: заблокирован при блокировке ресурсов буфера связи

30

В чем может быть причина такого тупика? (вообще не тупик)

Блокировка ресурсов буфера связи

Указано ли, что в системе недостаточно памяти, а количество буферов исчерпано?

Подробная ошибка:

Транзакция (ID процесса 59) была заблокирована для ресурсов буфера связи блокировки с другим процессом и была выбрана в качестве жертвы тупика. Перезапустите транзакцию

Шон Мелтон
источник

Ответы:

24

Полное сообщение, которое обычно видно:

Транзакция (ID процесса 53) заблокирована при блокировке | ресурсы буфера связи с другим процессом и были выбраны в качестве жертвы тупика. Перезапустите транзакцию.

Этот тип блокировки обычно наблюдается в запросах взаимоблокировки, которые SQL Server выполнял как параллельные, иногда называемые «параллельными взаимными блокировками внутри запроса». Я видел несколько утверждений о том, что это также указывает на то, что системные ресурсы являются низкими, что, я думаю, может быть связано с небольшой долей.

Общее правило, которое я заметил, чтобы определить, является ли это параллельной взаимоблокировкой, это когда вы извлекаете график взаимоблокировки XML (что можно сделать с помощью сеанса system_health в 2008 г. и более поздних версиях), вы заметите разные идентификаторы процессов, показывающие один и тот же бит кода внутри стек выполнения.

А также, глядя на список ресурсов графика взаимоблокировок и отмечая тип события официанта. Они чаще всего показывают «e_xxxxxx», или что-то вроде этого может быть:

<waiter-list>
 <waiter event="e_waitPipeGetRow" type="consumer" id="process821d828" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process8209198" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process3827c18" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process3809eb8" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process8226b08" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process9acb6d8" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process6188d7828" />
 <waiter event="e_waitPipeGetRow" type="consumer" id="process381cef8" />
</waiter-list>

Чтобы попытаться решить проблему, предлагаются различные пути в Интернете и в книгах. Я обычно начинаю с рассмотрения плана выполнения запроса / процедуры и сосредотачиваюсь на областях, которые показывают параллельное выполнение. Затем сначала попытайтесь настроить запрос, а затем, в крайнем случае, можете начать использовать подсказки запроса.

Наиболее распространенный запрос намека вы будете видеть упомянутый решить эти тупики реализующие MAXDOP 1. Однако перед этим вы можете проверить, установлены ли на уровне сервера MAXDOP и порог стоимости. Пороговое значение стоимости обычно устанавливается на 5 по умолчанию, и я хотел бы повысить его до 35 или 40, чтобы начать с него, если рассматриваемый запрос имеет низкую стоимость для этого раздела кода, он может вообще не нуждаться в параллельном выполнении. Я не очень люблю использовать подсказки запросов MAXDOP, но это не значит, что у них нет своего места и цели. только мое мнение.

Шон Мелтон
источник