Назад | Перейти на главную страницу

sql взаимоблокировка и тайм-аут почти постоянно

Похоже, сегодня будет еще одна чушь. Недавно мы обновили наш sql-бокс полным монстром, с множеством ядер и оперативной памяти, однако мы застряли на нашей старой схеме БД, которая является crapola.

У нашего старого sql-бокса были проблемы, но ничего похожего на то, что мы испытываем с новым, хотя в день развертывания он работал очень быстро, через неделю это полный беспорядок ...

Наше приложение .net, используемое парой сотен человек или около того, генерирует огромное количество взаимоблокировок и таймаутов в блоке SQL, и мы изо всех сил пытаемся понять, почему. Мы проверили все индексы, и сейчас они настолько хороши, насколько это возможно. Некоторые из основных таблиц слишком широки и имеют огромное количество включенных триггеров, но сейчас мы ничего не можем с этим поделать.

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

Так, например ...

User: user1
Time: 09:21
Error Message: Transaction (Process ID 76) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

User: user1
Time: 09:22
Error Message: Transaction (Process ID 76) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

и т.д....

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

Если у кого-то есть предложения, что мы можем сделать, я куплю им несколько пинт.

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

Уровень изоляции Microsoft SQL Server по умолчанию - зафиксирован на чтение. Разработчик должен знать и устанавливать соответствующий уровень для транзакции. Обычно рекомендуется использовать минимально возможный уровень изоляции и по возможности избегать использования уровней изоляции Repeatable Read и Serializable.

Если они используют более строгий уровень изоляции, чем установленный по умолчанию, такой как Repeatable Read или Serializable, то приложение будет более предрасположено к проблемам с блокировкой. Если они используют более строгий уровень изоляции, чем по умолчанию, и не знают об этом, это еще хуже.

Основная технология доступа к данным Microsoft, Entity Framework, по умолчанию использует уровень изоляции Serializable. Это не очень хорошо задокументировано или раскрыто. Если приложение использует Entity Framework и разработчик не знает об этом факте, разработчик может захотеть проверить структуру базы данных, чтобы определить, могут ли они установить уровень изоляции транзакции на Read Committed.

Больше информации:

УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ ТРАНЗАКЦИИ (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms173763.aspx

Транзакции и соединения в Entity Framework 4.0
http://blogs.u2u.be/diederik/post/2010/06/29/Transactions-and-Connections-in-Entity-Framework-40.aspx

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

На эту тему написано множество статей, вот этот достаточно всеобъемлющий. В официальная документация в MSDN также содержит некоторую информацию, хотя и не так красиво.

Если у вас есть правильные индексы, нет хорошего способа решить эту проблему без исправления схемы базы данных и / или запросов: в частности, тестирование с помощью SNAPSHOT ISOLATION и READ COMMITTED SNAPSHOT. Это не быстрые решения.

Если вы не против превратить нового зверя в тушенку, вы можете отключить параллелизм. Неизвестно, насколько это поможет.

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

Удалось ли вам хотя бы записать запросы, вызывающие проблемы? По моему опыту, очень мало запросов отвечает за подавляющее большинство проблем.

Судя по сообщениям об ошибках, похоже, что вы используете SQL Server. Если вы используете 2005 или лучше, включите Trace Flag 1222 DBCC TRACEON (1222, -1) он должен дать вам некоторую информацию о запросах. Дрянная схема может вызвать проблемы, но я никогда не видел, чтобы дрянная схема напрямую вызывала взаимоблокировки. Обычно есть обходной путь. Медленный запрос намного лучше, чем запрос, вызывающий постоянные взаимоблокировки.

Удалите некоторые из запросов, которые мешают, и мы могли бы предложить некоторые изменения в них.