SQL Server 2008: получение тупиков ... без блокировок - PullRequest
6 голосов
/ 29 марта 2011

В настоящее время я провожу некоторые эксперименты с базой данных SQL Server 2008.В частности, у меня есть приложение JDBC, которое использует сотни параллельных потоков для выполнения тысяч задач, каждая из которых выполняет следующий запрос к базе данных:

UPDATE from Table A where rowID='123'

Однако я получаю тонну тупиковых ситуаций.ошибки (исключение SQL 1205) всякий раз, когда я устанавливаю уровень изоляции выше READ_UNCOMMITTED.Это происходит, даже если я устанавливаю блокировку строк, таблицы и подсказки исключительной блокировки!И даже в Snapshot Isolation, которая не использует блокировки, я все еще получаю ошибки взаимоблокировки.

Я запустил трассировку через SQL Profiler, чтобы получить график взаимоблокировок, когда это происходит, но он не был особенно полезен.Он показал процесс жертвы, связанный с «Пулом потоков», подключенным к сотням других процессов.Вы можете проверить это здесь:

http://i.stack.imgur.com/7rlv3.jpg

У кого-нибудь есть какие-нибудь намеки относительно того, почему это происходит?Последние несколько дней я схожу с ума, пытаясь понять это.Моя текущая гипотеза заключается в том, что это связано с доступными рабочими потоками в моем экземпляре БД, объемом доступной памяти или чем-то, что не связано с фактическими блокировками на уровне запросов.

Спасибо!

Ответы [ 3 ]

6 голосов
/ 29 марта 2011

Вы встретили более эзотерического зверя: тупик ресурса. Имеется поток, который не может порождать дочерние задачи (sys.dm_os_tasks) для выполнения своей работы, поскольку все рабочие (sys.dm_os_workers) заняты. В свою очередь, занятые работники выполняют задачи, которые, вероятно, заблокированы, вероятно, обычными замками, жертвой.

Есть два урока, которые я вижу здесь, чтобы взять их домой:

1) ОБНОВЛЕНИЕ, которое вы опубликовали, пытается идти параллельно. Если обновление точно такое, как вы опубликовали, это означает одно и только одно: нет индекса на rowId.

2) Вы отскочили от верхнего потолка, установленного настройкой max worker threads. Неудивительно, учитывая, что вы злоупотребляете потоками в клиенте (hundreds of concurrent threads to execute thousands of task) и умножаете это на сервере из-за нежелательного параллелизма.

Разумный дизайн будет использовать асинхронное выполнение (BeginExecuteNonQuery) на истинно асинхронном соединении (AsynchronousProcessing=true) и использовать пул ожидающих запросов, чтобы он не шел выше определенный порог. Еще более вероятно, что вы передадите весь пакет значений обновления с помощью табличного параметра *1027*, а затем обновите весь набор или строки в виде пакета в одном выражении. Я понимаю, что все мои ссылки предназначены для .Net, а не для Java, мне все равно, вы можете сами найти эквивалентную функциональность Java.

Так что, хотя интересно, что вы обнаружили такой эзотерический тупик, он появляется только потому, что ваш дизайн, ну ... отстой.

1 голос
/ 29 марта 2011

Вы не можете сделать что-либо в SQL Server без блокировок - даже самый простой запрос, оштукатуренный с помощью операторов NOLOCK, выдаст блокировку схемы и, возможно, несколько блокировок страницы по минимуму.

Для устранения тупика вам необходимо получить трассировку тупика T1204 (подробнее см. Устранение неполадок тупика, часть 1 ), в которой будут перечислены точные блокировки и объекты, задействованные в тупике - это должнобыть достаточно информации, чтобы выяснить (с соответствующим количеством царапин на голове), что именно пошло не так.

Изменение уровня изоляции без полного понимания причины тупика кажется мне немного опасным ...

Как догадка, это напоминает мне о проблеме, с которой я столкнулся несколько лет назад. Является ли утверждение UPDATE тупиковым по отношению к утверждению SELECT?(Трассировка T1024 скажет вам это) И у вас есть некластеризованный индекс на rowID?Если это так, вы можете взглянуть на эту статью MSDN , в частности, Пример 6: Некластеризованные индексы.Если нет, то по-прежнему просматривайте эту статью, поскольку она может помочь объяснить некоторые другие соответствующие сценарии взаимоблокировки, а также опубликуйте результаты трассировки T1024, если вам нужна помощь в ее анализе.

1 голос
/ 29 марта 2011

Такие взаимные блокировки / блокировки странные и указывают на что-то вне SQL-сервера. Что бы ни стоило, у нас было много тупиковых проблем, которые оказались узким местом на диске!

Я предлагаю вам запустить perfmon (и, очевидно, после этого множество других инструментов) и посмотреть, как он работает.

...