Не удалось продолжить сканирование с NOLOCK из-за перемещения данных

10

Мы запускаем SQL Server 2000 и каждый вечер получаем несколько таких ошибок.

Could not continue scan with NOLOCK due to data movement

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

Культурная «лучшая практика» заключается в том, что в прошлом введение NOLOCKподсказок увеличивало производительность и улучшало параллелизм. Этот запрос не должен быть точным на 100%, то есть мы допустим грязное чтение и т. Д. Однако мы пытаемся понять, почему база данных выдает эту ошибку, даже если у нас есть все эти подсказки блокировки.

Может ли кто-нибудь пролить свет на это - будьте осторожны, я на самом деле программист, а не администратор базы данных :)

PS: Мы применили исправление, упомянутое ниже: http://support.microsoft.com/kb/815008

Ciaran Archer
источник
3
Я бы бросил NOLOCK и исправил бы запрос / индексы / процесс. Мы можем помочь, конечно ... Также смотрите en.wikipedia.org/wiki/Halloween_Problem
ГБН
3
@SQLKiwi: SQL 2012 корректно восстанавливается во многих случаях перемещения данных при грязном сканировании (продолжение на следующей странице в порядке выделения).
Ремус Русану
1
@SQLKiwi: да, еще есть. К хорошим новостям: курсоры, поддерживаемые грязными скансами, должны обрабатывать это более изящно.
Ремус Русану

Ответы:

7

Это достаточно известная проблема с SQL Server 2000 - по сути, происходит, если строка удаляется процессом A, в то время как процесс B выполняет сканирование (либо в, READ UNCOMMITTEDлибо в WITH (NOLOCK)), а затем процесс B говорит: «Что случилось с этими данными? «когда он пытается это прочитать. Точнее, строка должна быть удалена после того, как процесс B прочитает индекс, но до того, как попытается прочитать строку данных.

Крейг Фридман дает хорошую запись здесь

К счастью, это относительно простое решение: http://support.microsoft.com/kb/815008

Если это не сработает, у вас есть немного более болезненный вариант - убрать все ваши WITH (NOLOCK)подсказки и установить уровень изоляции транзакции выше READ UNCOMMITTED.

Саймон Ригартс
источник
Мы в курсе этого исправления - мы применили флаг, перезапустили и все еще получаем эти ошибки.
Кьяран Арчер