Устранение тупиковых ситуаций в Sql Server 2008 - PullRequest
16 голосов
/ 06 апреля 2009

Похоже, мой сайт не обслуживает большое количество посетителей, потому что сервер слишком прост.

2 часа назад на моем сайте было много посещений, и я заметил, что произошли 3 тупиковые ошибки, ошибка:

System.Data.SqlClient.SqlException : Транзакция (ID процесса 58) была заблокирована для ресурсов блокировки с другим процессом и была выбрана в качестве жертвы тупика. Перезапустите транзакцию.

Я не уверен, почему это произошло ... Глядя на трассировку стека, я увидел, что это произошло с запросом select.

Кто-нибудь знает, что может быть причиной этой ошибки?

Сервер работает под управлением Windows 2008 и Sql Server 2008.

Ответы [ 3 ]

11 голосов
/ 29 января 2014

SQL Server 2008 имеет несколько способов определения процессов и запросов, связанных с взаимоблокировкой.

  1. Если взаимоблокировки легко воспроизвести, частота выше, и вы можете профилировать SQL-сервер (у вас есть доступ и производительность на сервере, когда включен профилировщик), используя SQL Profiler, чтобы получить хорошее графическое представление о взаимоблокировке. Эта страница содержит всю информацию, необходимую для использования графиков взаимоблокировок http://sqlmag.com/database-performance-tuning/gathering-deadlock-information-deadlock-graph

  2. В большинстве случаев воспроизведение тупиковых ситуаций затруднено или происходит в производственной среде, где мы не хотим подключать к нему Profiler и влиять на производительность.

Я бы использовал этот запрос, чтобы получить взаимоблокировки:

SELECT
  xed.value('@timestamp', 'datetime') as Creation_Date,
  xed.query('.') AS Extend_Event
FROM
(
  SELECT CAST([target_data] AS XML) AS Target_Data
  FROM sys.dm_xe_session_targets AS xt
  INNER JOIN sys.dm_xe_sessions AS xs
  ON xs.address = xt.event_session_address
  WHERE xs.name = N'system_health'
  AND xt.target_name = N'ring_buffer'
) AS XML_Data
CROSS APPLY Target_Data.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData(xed)
ORDER BY Creation_Date DESC

Я бы НЕ пошел в направлении использования (NOLOCK) для устранения тупиков. Это скользкий уклон и скрытие исходной проблемы.

7 голосов
/ 06 апреля 2009

Операции записи будут блокировать операции чтения на SQL Server, если только у вас не включено управление версиями строк. Вы должны использовать хранимую процедуру sp_who2 и трассировку SQL Profiler. sp_who2 скажет вам, какие процессы какие блокируют, а профилировщик скажет вам, какой был последний оператор для процесса блокировки.

0 голосов
/ 06 апреля 2009

Если вы не возражаете против грязного чтения, попробуйте поставить (NOLOCK) после имен таблиц в запросах SELECT. Компромисс здесь заключается в том, что вам не гарантированы самые последние данные, поскольку выполняемые в настоящее время операторы UPDATE и INSERT игнорируются.

Как правило, это не слишком много, потому что большинство систем читают гораздо больше, чем обновляют / вставляют, но, очевидно, это зависит от характера вашего приложения.

В качестве альтернативы взгляните на http://www.sql -server-performance.com / tips / deadlocks_p1.aspx

...