Проблема блокировки базы данных - PullRequest
0 голосов
/ 11 ноября 2009

Pls. мы получили ЛОТ блокировок в производственной базе данных, которая недавно стала свидетелем значительного увеличения трафика. Мы используем IdeaBlade для большей части доступа к данным.

Я получил следующую трассировку с помощью Sql Profiler:

deadlock victim="process84af28"
  resource-list
    keylock hobtid="72057594096451584" dbid="6" objectname="cpc_db.dbo.Prefix_ChildTableName" indexname="PK_Prefix_ChildTableName" id="lock45982ac0" mode="X" associatedObjectId="72057594096451584"
      owner-list
owner id="processb852e8" mode="X" 
   owner-list
   waiter-list
    waiter id="process84af28" mode="S" requestType="wait" 
    waiter id="processb855b8" mode="RangeS-U" requestType="wait" 
   waiter-list
  keylock
  keylock hobtid="72057594096451584" dbid="6" objectname="cpc_db.dbo.Prefix_ChildTableName" indexname="PK_Prefix_ChildTableName" id="lock513c3bc0" mode="RangeS-U" associatedObjectId="72057594096451584"
   owner-list
    owner id="processb855b8" mode="RangeS-U" 
   owner-list
   waiter-list
    waiter id="processb852e8" mode="RangeS-U" requestType="wait" 
   waiter-list
  keylock
 resource-list
deadlock

Идеи кому-нибудь?

Я не администратор базы данных, но этот след, кажется, указывает на то, что:

  1. Процесс с исключительной блокировкой X для строки в дочерней таблице пытается получить блокировку Select-Update для того же ресурса (кажется, не имеет смысла)

  2. Другой процесс с блокировкой Select-Update все еще пытается получить блокировку Select-Update

Разъяснения кому-нибудь?

Как мы можем минимизировать или устранить тупики?

Ответы [ 4 ]

1 голос
/ 11 ноября 2009

Несколько вещей, на которые стоит обратить внимание:

  1. Вы используете сериализуемые транзакции , наиболее строгую форму пессимистической блокировки. Скорее всего, вам это не нужно (мы знаем, что вы используете сериализуемые транзакции, поскольку блокировки KEY применяются только к этому уровню изоляции). Как упомянул выше Ремус, вам, скорее всего, стоит поискать другие варианты.

  2. Кажется, что вышеприведенный вывод немного урезан, у вас должны быть разделы, называемые process-list, с информацией, отображающей информацию о процессе в spids и запросы

Из того, что вы можете сказать в выводе выше:

processb852e8 owns an exclusive lock on index "cpc_db.dbo.Prefix_ChildTableName.PK_Prefix_ChildTableName"
    process84af28 is waiting for a shared KEY lock
    processb855b8 is also waiting for a Shared Range-Update KEY lock

processb855b8 owns Shared Range-Update lock on index "cpc_db.dbo.Prefix_ChildTableName.PK_Prefix_ChildTableName" (the same index)
    processb852e8 is waiting on a Shared Range-Update KEY lock

Эксклюзивная блокировка - это запись некоторого вида (т.е. обновление, удаление, вставка), блокировки RangeS-U, скорее всего, являются обновлением, но невозможно узнать, не увидев отображенную информацию.

У Барта Дункана есть пара отличных постов по расшифровке вывода трассировки, если у вас есть все, см. часть 1 и часть 2 . Вы также можете просмотреть обзор параллелизма и сценариев в целом здесь .

0 голосов
/ 11 ноября 2009

Я видел эту проблему взаимоблокировки с другим продуктом (не IdeaBlade). По моему опыту, это не проблема базы данных; возможно, это проблема с программным обеспечением, взаимодействующим с базой данных.

Мои проблемы были связаны с настройкой компонентов, взаимодействующих с базой данных.

В первый раз для COM + по умолчанию установлено значение SERIALIZABLE, и для него необходимо было установить значение READ COMMITTED по умолчанию.

Во второй раз условие взаимодействия COM + с .NET привело к тому, что для соединения с базой данных по умолчанию было установлено значение SERIALIZABLE.

Для нас быстрым и грязным решением было добавить префикс SQL-команд к «SET TRANSACTION ISOLATION LEVEL READ COMMITTED», чтобы переопределить SERIALIZABLE до тех пор, пока проблема ядра не будет решена.

0 голосов
/ 11 ноября 2009

виновник, кажется,: -

owner id="processb855b8" mode="RangeS-U"

Казалось бы, это заблокировало ряд строк. Ожидание, пока не будет обработан ряд с помощью process84af28, который ожидает, чтобы строка была повторно выпущена processb852e8 которая ожидает освобождения строки первым процессом.

SQLServer устраняет тупик, убивая процесс в середине, позволяя двум другим завершиться.

Ты должен посмотреть на свои уровни изоляции. Лучшая практика - использовать самые низкие доступный уровень блокировки при «выделении» нескольких строк. Используйте более высокий уровень в строке «select» ed, только если вы с большой вероятностью обновите строку в текущей транзакции.

И НИКОГДА, никогда, не оставляйте строку заблокированной во время ожидания внешней службы или действия пользователя.

0 голосов
/ 11 ноября 2009

mode="RangeS-U"

Замки дальности? Прекратите использовать высокие уровни изоляции транзакций. Палка для чтения совершена. Если вы используете объект CLR TransactionScope, заставьте их использовать изоляцию Read Commited (по умолчанию они используют Seralizable, да). Попробуйте включить изоляцию моментального снимка в базе данных. См. Использование изоляции моментального снимка .

...