2014-01-13 3 views
4

У меня есть база данных LOGGIN, и она довольно большая - 400 ГБ. Он имеет миллионы строк.SQL server - Удалить оператор увеличить размер журнала

Я только что запустил инструкцию delete, которая заняла 2,5 часа и удалила, вероятно, миллионы строк.

delete FROM [DB].[dbo].[table] 
where [Level] not in ('info','error') 

Это простая базовая модель восстановления. Но когда я запустил вышеуказанный оператор, файлы журналов выросли до 800 ГБ и разбили сервер. Почему файл LOG растет для простой базы данных модели восстановления?

Как я могу избежать этого в будущем?

Спасибо за ваше время - RM

+3

http://stackoverflow.com/questions/5925471/how-can-i-delete-expired-data-from-a-huge-table-without-having- the-log-file-grow –

+0

Также см. http://dba.stackexchange.com/questions/56432/running-parallel-delete-statements/56516#56516 и http://www.sqlperformance.com/2013/03/ io-subsystem/chunk-deletes –

ответ

5

Держу пари, вы пытаетесь запустить все удалить в одной транзакции. Верный?

После завершения транзакции пространство журнала может быть восстановлено. Поскольку транзакция не была завершена, файл журнала рос до тех пор, пока он не разбил сервер.

Оформить запись в блоге на Как удалить большие данные.

http://craftydba.com/?p=3079

Ключа к решению заключается в следующем, ЛЕГКО режиме восстановления, DELETE малых партий, принимает полную резервную копию в конце продувки. Выберите модель восстановления, которую вы хотите в конце.

Вот пример кода, который поможет вам на вашем пути.

-- 
-- Delete in batches in SIMPLE recovery mode 
-- 

-- Select correct db 
USE [MATH] 
GO 

-- Set to simple mode 
ALTER DATABASE [MATH] SET RECOVERY SIMPLE; 
GO 

-- Get count of records 
SELECT COUNT(*) AS Total FROM [MATH].[dbo].[TBL_PRIMES]; 
GO 

-- Delete in batches 
DECLARE @VAR_ROWS INT = 1; 
WHILE (@VAR_ROWS > 0) 
BEGIN 
    DELETE TOP (10000) FROM [MATH].[dbo].[TBL_PRIMES]; 
    SET @VAR_ROWS = @@ROWCOUNT; 
    CHECKPOINT; 
END; 
GO 

-- Set to full mode 
ALTER DATABASE [MATH] SET RECOVERY FULL; 
GO 

И последнее, но не менее важное: если количество оставшихся данных после удаления является реальным небольшим, возможно, было бы быстрее выполнить следующее.

1 - SELECT * INTO [Temp Table] WHERE (clause = small data). 
2 - DROP [Original Table]. 
3 - Rename [Temp Table] to [Original Table]. 
4 - Add any constraints or missing objects. 

Действие таблицы DROP не записывает все удаляемые данные.

С уважением,

Джон

+2

Для вашего последнего, но не менее важного раздела вы также можете обрезать таблицу, а затем вставить обратно строки, которые хотите сохранить и временно сохранить в [Temp Table]. Тем не менее, примерно столько же работы, особенно если есть ограничения и т. Д., Но бонус будет вам не нужно повторно устанавливать разрешения. –

+0

@AaronBertrand это не вариант с fk/on-delete-cascade – mbx

+1

@mbx Конечно, нет. Но вы можете сбросить и воссоздать эти ограничения в зависимости от того, что для вас важнее. В 20 лет, работая с SQL Server по широкому спектру реализаций, мне еще предстоит принудительно включить в FKs каскад. –

Смежные вопросы