Примерно раз в неделю мне приходится разрешать цепочку блокировок в базе данных SQL Server 2005, вызванную долговременной блокировкой чтения из интерфейса Access 2003. Блокировка снимается всякий раз, когда пользователь открывает определенную форму, и снимается, когда пользователь завершает прокрутку формы или закрывает ее. Поскольку многие из наших пользователей открывают эту форму в качестве ссылки, эти блокировки остаются на некоторое время. Любое обновление таблицы вызывает блокировку, и внезапно никто не может выбрать из этой таблицы, так как все они ожидают первой блокировки. Для нас это большая проблема, так как многие приложения полагаются на эти данные. Я понимаю, что это поведение блокировки является частью того, как Access работает со связанными таблицами.
Я решал проблему из Activity Monitor, убивая тот процесс SELECT, который блокирует головы всякий раз, когда я узнаю об этом. Это проблема не только потому, что мне требуется время, чтобы сделать это вручную, но и потому, что она реагирует. К тому времени, когда я слышу об этом, это уже стало проблемой для многих людей.
Я хотел бы знать, существует ли автоматический способ проверки этих длительных цепочек блокировок, и либо он будет отправлен по электронной почте, либо проблема будет решена автоматически. Логика кажется достаточно простой («если какой-либо процесс, соответствующий этому запросу SELECT, блокировался более минуты, сообщите мне / убейте его»), но я не знаю, как реализовать это с SQL Server.
Для чего это стоит, я думаю, что правильное решение состоит в том, чтобы исправить или переписать приложение. Тем не менее, из-за политики департаментов, это не вариант в течение следующих нескольких месяцев, поэтому я ищу временную пробел.
источник
Ответы:
Рассматривали ли вы использование изоляции моментальных снимков ? Включение read_committed_snapshot в базе данных приведет к тому, что все операции чтения (выбора) будут заблокированы:
Нет изменений приложения. Некоторые семантики меняются под снимком, и ваше приложение может реагировать странно, но это исключение, а не норма. Подавляющее большинство приложений не замечают никакой разницы, они просто получают бесплатное повышение производительности.
В любом случае, я хочу ответить и на оригинальный вопрос: как обнаружить (и, возможно, убить) длительный запрос. На самом деле, двигатель уже делает это для вас. При превышении порога возникает событие: Класс события отчета о заблокированных процессах . Порог настраивается через опцию заблокированного процесса . Любое событие трассировки можно превратить в Уведомление о событии, а уведомления о событиях могут активировать процедуры . Соедините точки, и вы получите активированный код по требованию, который запускается, когда механизм обнаруживает запрос, который превысил порог времени выполнения. Нет опроса, нет мониторинга. Обратите внимание, что уведомление является асинхроннымк тому времени, когда вы его обрабатываете, запрос может быть завершен, и это необходимо учитывать.
Вот пример:
Теперь в новом запросе установите
WAITFOR
ожидающее уведомление:И идти вперед и вызвать некоторую блокировку. Я использовал процесс, который создал таблицу и не зафиксировал ее, а в других окнах запросов я попытался выбрать из таблицы. Через 20 секунд (мой настроенный порог выше) я получил отчет о блокировке:
Я оставлю задачу обернуть это в автоматизированный процесс в качестве упражнения для читателя. И да, очередь / служба / активированная процедура должна быть в
[msdb]
.источник
Вы можете создать свой собственный инструмент мониторинга или обратиться к стороннему решению, которое может предоставить его вам. Если вы заинтересованы в создании собственного, это зависит от того, с какой версией SQL Server вы работаете. Если это 2005, вы можете использовать событие трассировки Отчета о заблокированных процессах . Если вы работаете в версии 2008 или выше, я бы предложил использовать эквивалентное расширенное событие block_process_report. Джонатан Кеяйас хорошо написал о том, как его использовать.
Если вы просматриваете сторонние продукты, в программном обеспечении Red Gate SQL Monitor заблокированы процессы и встроены длительные оповещения о процессах.
источник
Хотя это не относится к тому, как уведомить вас о проблеме, эта процедура покажет вам, как сделать запрос, чтобы увидеть, существует ли блокировка. Он также будет генерировать команды уничтожения для вас, если вы передадите правильный параметр.
Надеюсь, что это дает вам некоторые идеи.
источник
Я бы предложил прочитать следующую тему на форуме MSDN . Речь идет о блокировке, вызванной доступом к базе данных SQL Server. Предполагается, что в основном доступ к таблицам осуществляется с помощью подсказки NOLOCK, чтобы не возникало проблем с блокировкой. NOLOCK - не лучшее решение, так как оно может вызвать другие проблемы, но уменьшит большинство проблем с блокировкой.
Лучшим решением было бы реализовать идею Ремуса, настроить изоляцию моментальных снимков в вашей базе данных. Или реализуйте уровень изоляции моментального снимка только для определенных соединений, которые, по вашему мнению, вызывают блокировку.
Для того, чтобы правильно контролировать ваш сервер на наличие проблем с блокировкой, я бы предложил:
Если вы хотите упреждающего ответа на эту проблему, вместо того, чтобы каждый час выполнять мониторинг трассировок, заставляйте его запускаться каждую минуту и убивайте любой ведущий блокирующий сеанс доступа.
источник
Следуя прекрасному ответу @Remus Rusanu, я выполнил задачу читателя, чтобы связать событие с хранимой процедурой.
В моем случае sp запишет xml события блокировки в таблицу, но вы можете делать все, что захотите, в этой позиции.
Итак, следуйте коду Remus и создайте
queue
, theservice
и thenotification
с помощью простого копирования / вставки сверху. Добавьтеsp_configure
параметры, и вы в основном настроены.Единственное, что осталось сделать, это
queue
Как только вы активируете SP, события начнут перетекать в вашу таблицу.
Я обнаружил, что очередь деактивируется сразу, если в SP возникла ошибка. В этом случае вам нужно перейти в Server Studio и снова активировать его в контекстном меню записи очереди (
[msdb]->Service Broker->Warteschlangen
в немецкой версии).Мне потребовалось довольно много времени, чтобы все заработало и было найдено правильное место в документации, поэтому я полагаю, что это полезно и для других. Я использую SQLServer 2005.
Создайте SP без аргументов
Создать
pdix_lock_events
таблицуАктивируйте SP на
queue
источник