Як відтворити "Неможливо продовжити сканування за допомогою NOLOCK через рух даних"


10

Іноді я отримую "Не вдалося продовжити сканування NOLOCKчерез рух даних" з деякими великими завданнями, які є WITH (NOLOCK)у вибраних запитах.

Я розумію, що це має щось спільне із спробою вибору даних, коли відбувся розкол сторінки, що призвело до того, що дані вже не там, де повинні були бути - я припускаю, що це відбувається в моєму середовищі.

Як би я відтворив це?

Я намагаюся зробити короткочасний спосіб вирішити помилку та повторити спробу, коли це трапиться, але я не можу перевірити її, якщо я не можу її відтворити. Чи є досить надійний спосіб викликати це?

Коли це все-таки відбувається, виконання запиту знову призводить до успіху - тому я насправді не маю жодних побоювань щодо того, що фактичні дані чи база даних постійно пошкоджуються. Деякі таблиці запиту (разом з їх індексами) часто випадають, відтворюються та повторно заселяються, тому я припускаю, що це щось пов’язане з цим.

Видалення NOLOCK- це моя довгострокова проблема, яку потрібно вирішити. Причина, NOLOCKв першу чергу, полягала в тому, що запити настільки погані, що вони ставали в глухий кут із щоденними транзакціями, настільки, що NOLOCKце допомога, щоб зупинити тупики (що спрацювало). Тому мені потрібна допомога на бандажі, поки ми не зможемо вирішити постійне рішення.

Якби я міг відтворити це за допомогою Hello World, я б запланував, щоб, ймовірно, заштрихувати допомогу в роботі менше ніж за годину. Неможливо виконати пошук і заміну видалення NOLOCK, тому що я б знову почав отримувати тупики програми, які для мене гірші, ніж випадкові збої в роботі.

Використання зчитуваного виділеного знімка знімків є хорошою можливістю - мені доведеться співпрацювати з нашою командою бази даних, щоб отримати детальнішу інформацію про це. Частина нашої проблеми полягає в тому, що у нас немає експерта SQL Server, який би займався подібними питаннями, і я не розумію рівня ізоляції достатньо добре, щоб зробити цю зміну зараз.


1
Ви думали про просто усунення NOLOCKз цих робочих місць? 601 має бути найменшим, що турбується, якщо результати цих запитів повинні бути точними . Пол Уайт показує особливо жахливий приклад читання даних, які тут не повинні бути можливими .
Аарон Бертран

3
Ви можете налаштувати DEADLOCK_PRIORITYна LOWзавдання, так що, якщо існують тупикові місця, завдання будуть виходити з ладу, а не програми. Після цього ви можете дослідити тупикові місця та дізнатись, чому вони відбуваються, та виправити цю проблему. Це може бути дуже просте виправлення, як-от заміна порядку двох висловлювань. Якою б не була проблема, NOLOCKце не вирішення , так перестати намагатися змусити його бути просто тому , що це найпростіший.
Аарон Бертран

@AaronBertrand Спасибі, не знав про DEADLOCK_PRIORITY - я розберуся в цьому. Ми намагалися відстежувати тупикові місця, але це траплялося в різні, здавалося б, випадкові часи, і лише один-два рази на день, і вони ніколи не відтворюються на вимогу - наші заплановані завдання виконують десятки тисяч запитів щогодини, а наш додаток виконує сотні запитів, коли він просто завантажує сторінку або щось зберігає, і ми не відслідковували, який запит з будь-якої сторони задіяний у тупику. Я не мав наміру залишати NOLOCK назавжди, саме тому ми досліджуємо кращі довгострокові рішення.
wookie23

1
Ви згадали, що вам було важко відстежувати тупики. Зважаючи на те, що ви перебуваєте у 2008 році, ви можете подивитися тут: sqlservercentral.com/articles/deadlock/65658 Джонатан Кехаяс перетягує інформацію про тупик із буфера дзвінка.
Кеннет Фішер

Відповіді та коментарі добре вирішують основну проблему, але ви все ще зацікавлені у пошуку способу відтворити це як інтелектуальну вправу?
Джеймс Л

Відповіді:


8

Оскільки однією з потенційних «допомог у діапазоні» для проблем NOLOCK є припинення використання NOLOCK та початок використання ізоляції READ_COMMITTED_SNAPSHOT, я хочу вказати на публікацію в блозі на веб- сайті http://www.brentozar.com від Kendra Little: Реалізація знімка або Читання прихильне Ізоляція знімків у SQL сервері: Посібник .

Кендра надає досить детальну інформацію про переваги та ризики, використовуючи рівень ізоляції READ_COMMITTED_SNAPSHOT.

  1. Цей рівень ізоляції стає типовим рівнем ізоляції для коду бази даних.
  2. Щоб внести зміни до рівня ізоляції READ_COMMITTED_SNAPSHOT, у базі даних повинен бути лише один користувач.
  3. Навіть якщо ви використовуєте ізоляцію READ_COMMITTED_SNAPSHOT, вам все одно доведеться видалити підказки NOLOCK, оскільки вони замінюють за замовчуванням.
  4. Деякі з вашого коду можуть мати проблеми, які потребують лікування.

Деякі роки тому ми реалізували ізоляцію READ_COMMITTED_SNAPSHOT на базі даних, яка сильно страждала від блокування . Але як тільки ми змінили рівень ізоляції, ми почали отримувати тупики в декількох критичних місцях.

Чому так сталося? Оскільки попередній рівень ізоляції спричинив сильне блокування, код не міг "ніколи" дійти до точки глухого блокування. Однак, із ізоляцією READ_COMMITTED_SNAPSHOT, запити можуть продовжувати рухатися вперед. Однак деякий відсоток транзакцій, які не чекають, почав тупик.

На щастя, наш випадок був вирішений швидко шляхом визначення точок тупику та коригування індексів на пару таблиць, щоб мати більш раціональний порядок стовпців. Це значно зменшило наші проблеми із блокуванням.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.