2013-09-24 2 views
0

У меня возникли проблемы с некоторой древней базой данных, которую я должен поддерживать. Это было уже целую вечность (нет, я его не проектировал, нет, никаких изменений на нем не было)Ошибка SQL Server 2008 Ошибка 1204 Блокировка

он выглядит примерно так: Есть 2 таблицы, «Документы» и «Версии». Документы - довольно простая таблица, просто первичный ключ, varchar, хранящий имя документа и пользователя, создавшего этот документ. У Versions есть внешний ключ к документу, к которому он принадлежит, поле изображения, в котором хранится фактический документ (в основном слово документы и pdf-файлы), расширение и другое поле, которое поддерживает номер версии.

Всякий раз, когда приложение (приложение ANCIENT VB6) использует документ, создается новая версия.

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

DELETE FROM t_ad_Versions WHERE VersionNumber < dbo.MaxVersion(codDocument)-4 

Проблема, Eventhough каждый день таблица версий имеет эту работу работает, чтобы discar самые старые записи, база данных достигает тревожную размер (В настоящее время 300+ ГБ).

Чтобы уменьшить упомянутый размер, кто-то в конце концов понял, что нет необходимости хранить версии pdf-элементов. Итак, мне было предложено применить простую модификацию:

задание удалит старые версии текстовых документов, сохраняя последние 5 версий. Для любого другого типа файлов ВСЕ версии, кроме последней, будут удалены. Таким образом, я изменил хранимую процедуру задания, связанная с этим:

DELETE FROM t_ad_Versions WHERE VersionNumber < dbo.MaxVersion(codDocument)-4 
AND extension LIKE 'do%'; 

DELETE FROM t_ad_Versions WHERE VersionNumber < dbo.MaxVersion(codDocument) 
AND extension NOT LIKE 'do%'; 

Однако после применения изменений, на следующий день история работы уведомлена следующее сообщение об ошибке

«экземпляр SQL Server Database Engine не может получить ресурс LOCK в это время. Перезапустите свой оператор, когда число активных пользователей меньше. Попросите администратора базы данных проверить конфигурацию блокировки и памяти для этого экземпляра или проверить длительные транзакции. [SQLSTATE HY000] (Ошибка 1204).

Я сейчас потерял все идеи?

+0

Как долго работает этот запрос? (SELECT COUNT (*) FROM t_ad_Versions WHERE VersionNumber sqlint

+0

Вероятно, попытался удалить слишком много вещей сразу. см. http://social.msdn.microsoft.com/Forums/sqlserver/en-US/4419eab8-7e35-492f-9a12-0c56932d702a/sql-jobs-cannot-obtain-a-lock-resource-at-this-time –

ответ

1

Вы можете попробовать удалить строку по 100 или любое число, которое работает быстро.

declare @rows int 
set @rows = 1 
while @rows > 0 
BEGIN 
DELETE TOP (100) FROM t_ad_Versions WHERE VersionNumber < dbo.MaxVersion(codDocument)-4 AND extension LIKE 'do%'; 
set @rows = @@ROWCOUNT 
END 
+0

Ну, dunnot, если есть более ортодоксальное решение для работы с блокировками sql-сервера, но это сделало трюк. Фактически, из-за изменения политики, то, что задание было поручено удалить все предыдущие версии для документов без слова, означало, что было удалено более 200 000 строк, очевидно, это было слишком много для обработки. Работа началась в 2 часа ночи, с тех пор прошло 7 часов и до сих пор работает, до базы данных до 230 ГБ. – Hobbes

+0

. Вы можете увеличить TOP (100) до 1000. Он должен ускорить процесс удаления, но увеличивает вероятность ошибки блокировки. – sqlint

+0

Вы можете создать один NONCLUSTERED INDEX для MaxVersion, столбцы расширения для инструкции delete. – sqlint