Журнал транзакций для базы данных заполнен


109

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

Я не контролирую, как это выполняется.

Поскольку транзакция остается открытой в течение всего времени, при заполнении журнала транзакций SQL Server не может увеличить размер файла журнала.

Таким образом, процесс завершается ошибкой "The transaction log for database 'xxx' is full".

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

Не уверен, что мне делать дальше. Процесс длится несколько часов, так что играть методом проб и ошибок непросто.

Любые идеи?

Если кому интересно, процесс - это импорт организации в Microsoft Dynamics CRM 4.0.

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

- = - = - = - = - ОБНОВЛЕНИЕ - = - = - = - = -

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

Я получаю следующую ошибку ...

Import Organization (Name=xxx, Id=560d04e7-98ed-e211-9759-0050569d6d39) failed with Exception:
System.Data.SqlClient.SqlException: The transaction log for database 'xxx' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases

Итак, следуя этому совету, я пошел к " log_reuse_wait_desc column in sys.databases" и он имел ценность ACTIVE_TRANSACTION".

Согласно Microsoft: http://msdn.microsoft.com/en-us/library/ms345414(v=sql.105).aspx

Это означает следующее:

Транзакция активна (все модели восстановления). • В начале резервного копирования журнала может существовать длительная транзакция. В этом случае для освобождения места может потребоваться еще одна резервная копия журнала. Дополнительные сведения см. В разделе «Длительные активные транзакции» далее в этом разделе.

• Транзакция отложена (только для SQL Server 2005 Enterprise Edition и более поздних версий). Отложенная транзакция фактически является активной транзакцией, откат которой заблокирован из-за недоступности ресурса. Для получения информации о причинах отложенных транзакций и о том, как вывести их из отложенного состояния, см. Отложенные транзакции.

Я что-то неправильно понял?

- = - = - = - ОБНОВЛЕНИЕ 2 - = - = - = -

Просто начал процесс с начальным размером файла журнала 30 ГБ. Это займет пару часов.

- = - = - = - Окончательное ОБНОВЛЕНИЕ - = - = - = -

На самом деле проблема была вызвана тем, что файл журнала занимал все доступное дисковое пространство. В последней попытке я освободил 120 ГБ, и он все еще использовал их и в конечном итоге потерпел неудачу.

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

Спасибо всем за ваш вклад.


re "... и создали резервную копию журнала" .... если база данных находится в простом режиме, вы не сможете создать резервную копию журнала, резервные копии журналов не применимы для простого режима. Это неполный журнал?
SqlACID

1
Я сделал резервную копию всей БД и сжал ее, в результате чего размер журнала уменьшился до 1 МБ. Затем я увеличил размер файла журнала до 20 ГБ, а теперь до 30 ГБ.
Jimbo

Ответы:


19

Это разовый сценарий или регулярно выполняемая работа?

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


Я бы не сказал, что это разовая работа, но нам редко приходится ее делать. Я не создавал второй файл журнала, но увеличил начальный размер текущего файла журнала до 30 ГБ. Во время моего последнего запуска он был установлен на 20 ГБ, но все равно не работал.
Jimbo

Будет ли лучше иметь второй файл журнала, чем один большой, учитывая, что у меня есть только один диск?
Jimbo

Как я сейчас припоминаю, дополнительный файл в основном позволял нам получить доступ к другому, большему диску.
Майк Хендерсон

2
Насколько велики импортируемые данные? Если вы импортируете 30 ГБ данных, ваш файл журнала должен быть не меньше размера.
Майк Хендерсон

3
Размер журнала - это ключ. Текущая задача снова не удалась, и я не мог поверить своим глазам, когда увидел размер файла журнала в момент, когда он не удался. Он обработал только половину учетных записей и уже составлял 53 ГБ. Похоже, мне нужно будет очистить где-то около 60-70 ГБ, чтобы завершить этот процесс.
Jimbo

95

Чтобы решить эту проблему, измените Модель восстановления на Простую, а затем Сжать журнал файлов.

1. Свойства базы данных> Параметры> Модель восстановления> Простой

2. Задачи базы данных> Сжать> Файлы> Журнал

Готово.

Затем проверьте размер файла журнала db в Свойства базы данных> Файлы> Файлы базы данных> Путь.

Чтобы проверить полный журнал сервера sql: откройте средство просмотра файлов журнала в SSMS> База данных> Управление> Журналы SQL Server> Текущий


10
Нет, это не решает проблемы. Проблема заключалась в том, что файл журнала увеличивался в течение длительного процесса, пока не закончилось свободное место на диске. Это было исправлено путем временного перемещения файла журнала на другой диск, на котором было доступно 1 ТБ свободного места. Вы не можете сжать файл журнала, пока выполняется длительный процесс, который удерживает транзакцию открытой. Этот процесс несет полную ответственность за рост файла.
Джимбо

Как уже сказал @Jimbo, это не решает проблему OP. Это может освободить часть неиспользуемого в настоящее время пространства, но как только длинная транзакция снова будет запущена, пространство будет занято снова (и, вероятно, потерпит неудачу даже раньше)
Марсель

Отлично! Спасибо!
Юрий Монтейро

Это не устранило проблему. В моем журнале всего 500 байт. Я думаю, эта проблема началась после того, как я вчера сделал резервную копию.
Ricardo França

Это определенно исправление, если у вас осталось несколько мегабайт на полном диске.
Стив Бауман

36

Однажды у меня была эта ошибка, и в итоге на жестком диске сервера закончилось место.


1
Прочтите обновления OP. Это оказалось проблемой.
Colm

18

Включены ли для файла журнала оба параметра Enable Autogrowth и Unrestricted File Growth ? Вы можете редактировать их через SSMS в «Свойства базы данных> Файлы».


Да. Он настроен на автоматический рост 10%, без ограничений. Проблема в том, что автоматическое увеличение не будет работать, пока есть открытая транзакция.
Jimbo

1
Вы хоть представляете, насколько крупной будет сделка? попробуйте установить размер журнала транзакций больше, чем эта оценка, в любом случае, если выделение диска не является проблемой, выделите вначале достаточно места для данных и журнала. Повышает производительность. Не используйте автоматический рост на 10% , сделайте это на несколько гигабайт, чтобы производительность была достаточно хорошей.
Luis LL

3
SQL Server будет автоматически увеличивать журнал во время транзакции, если ему требуется больше места для завершения этой транзакции.
Росс Макнаб

Привет, Росс, я представил свою логику, позволяющую думать, что открытая транзакция предотвращает рост обновления вопроса. Я ошибаюсь в своих рассуждениях?
Jimbo

1
@Jimbo SQL Server не требует, чтобы вы зарезервировали его. Если у вас есть автоматическое увеличение, SQL Server выполняет автоматический рост во время транзакции. Достаточно большой он может сэкономить много времени, но не должен влиять на процесс.
Luis LL

10

Это старый подход, но если вы выполняете итеративную операцию обновления или вставки в SQL, которая выполняется в течение длительного времени, рекомендуется периодически (программно) вызывать «контрольную точку». Вызов «контрольной точки» заставляет SQL записывать на диск все эти изменения, связанные только с памятью (они называются грязными страницами), и элементы, хранящиеся в журнале транзакций. Это позволяет периодически очищать журнал транзакций, предотвращая таким образом проблемы, подобные описанной.


1
К сожалению, я не могу контролировать, как выполняется этот процесс. Dynamics CRM - это приложение Microsoft, и процесс импорта организации является частью этого приложения.
Jimbo

1

Следующее приведет к усечению журнала.

USE [yourdbname] 
GO

-- TRUNCATE TRANSACTION LOG --
DBCC SHRINKFILE(yourdbname_log, 1)
BACKUP LOG yourdbname WITH TRUNCATE_ONLY
DBCC SHRINKFILE(yourdbname_log, 1)
GO

-- CHECK DATABASE HEALTH --
ALTER FUNCTION [dbo].[checker]() RETURNS int AS BEGIN  RETURN 0 END
GO

4
Привет, Пиналь, эта функция была полностью удалена из SQL Server 2008 и более поздних версий
Конор

3
В более поздних версиях попробуйте BACKUP LOG <myDB> TO DISK = N'NUL: '
HansLindgren

1

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

Это предотвратит любые действия с этой базой данных (например, сжатие), и ядро ​​СУБД SQL Server вызовет ошибку 9002.

Чтобы преодолеть это поведение, я советую вам проверить это. Журнал транзакций для базы данных «SharePoint_Config» заполнен из-за LOG_BACKUP, который показывает подробные шаги для решения проблемы.


0

Я обнаружил ошибку: «Журнал транзакций для базы данных '...' заполнен из-за 'ACTIVE_TRANSACTION' при удалении старых строк из таблиц моей базы данных для освобождения дискового пространства. Я понял, что эта ошибка возникнет, если количество строк будет В моем случае было удалено больше 1000000. Поэтому вместо использования одного оператора DELETE я разделил задачу удаления с помощью оператора DELETE TOP (1000000) ....

Например:

вместо использования этого оператора:

DELETE FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())

многократно используя следующий оператор:

DELETE TOP(1000000) FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())

0

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

Перед

DELETE FROM TableName WHERE Condition

После

DELETE TOP(1000) FROM TableName WHERECondition

-1

Ответ на вопрос заключается не в удалении строк из таблицы, а в том, что пространство tempDB занято из-за активной транзакции. это происходит в основном, когда выполняется слияние (upsert), когда мы пытаемся вставить обновление и удалить транзакции. Единственный вариант - убедиться, что БД настроена на простую модель восстановления, а также увеличить размер файла до максимального объема (добавить другую группу файлов). Хотя у этого есть свои преимущества и недостатки, это единственные варианты.

Другой вариант, который у вас есть, - разделить слияние (upsert) на две операции. один выполняет вставку, а другой - обновление и удаление.


Если вы прочитаете вопрос, то узнаете, что БД уже находилась в режиме простого восстановления, когда это происходило. Это не помогает, если у вас есть одна длительная открытая транзакция. Файл продолжает расти до тех пор, пока транзакция не будет зафиксирована или откат. Прочтите первую строку вопроса «У меня есть длительный процесс, который удерживает транзакцию открытой в течение всего времени».
Джимбо

-1

Попробуй это:

USE YourDB;  
GO  
-- Truncate the log by changing the database recovery model to SIMPLE.  
ALTER DATABASE YourDB
SET RECOVERY SIMPLE;  
GO  
-- Shrink the truncated log file to 50 MB.  
DBCC SHRINKFILE (YourDB_log, 50);  
GO  
-- Reset the database recovery model.  
ALTER DATABASE YourDB
SET RECOVERY FULL;  
GO 

Я надеюсь, что это помогает.


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

-1

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

 USE master;

    SELECT 
        name, log_reuse_wait, log_reuse_wait_desc, is_cdc_enabled 
    FROM 
        sys.databases 
    WHERE 
        name = 'XX_System';

    SELECT DATABASEPROPERTYEX('XX_System', 'IsPublished');


    USE XX_System;
    EXEC sp_repldone null, null, 0,0,1;
    EXEC sp_removedbreplication XX_System;


    DBCC OPENTRAN;
    DBCC SQLPERF(LOGSPACE);
    EXEC sp_replcounters;



    DBCC SQLPERF(LOGSPACE);

Пожалуйста, всегда помещайте свой ответ в контекст, а не просто вставляйте код. Подробнее см. Здесь .
gehbiszumeis

-1

Попробуй это:

По возможности перезапустите службы MSSQLSERVER и SQLSERVERAGENT .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.