Увеличивает ли запуск неопределенного WAITFOR размер файла журнала?

16

В последнем выпуске моего приложения я добавил команду, которая заставляет его ждать, когда что-то приходит в очередь компонента Service Broker:

WAITFOR (RECEIVE CONVERT(int, message_body) AS Message FROM MyQueue)

Администраторы баз данных говорят мне, что с момента добавления размеры бревен прошли через крышу. Может ли это быть правильно? Или я должен искать в другом месте?

AngryHacker
источник

Ответы:

17

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

В последнее время я начал рекомендовать людям избегать ОЖИДАНИЯ в активированной процедуре вместе с петлей. Просто выдайте RECIEVe и все будет готово, позвольте механизму активации зацикливаться для вас (он делает это), а не WAITFOR, просто просто RECEIVE.

Вариант WAITFOR для RECEIVE создает точку сохранения внутри. Это создает журнал (как минимум 3 записи журнала) и действительно фиксирует журнал на месте во время ожидания. Длинный тайм-аут WAITFOR (или, что еще хуже, бесконечный) был бы очень плохой практикой.

Ремус Русану
источник
1
Решил бы WAITFOR (...) TIMEOUT 3600000проблему? Например, ежечасно.
AngryHacker
2
Ваш журнал значительно вырастет за один час. WAITFOR (REC EIVE) предназначен для интервалов, таких как 5 секунд ...
Remus Rusanu
1
Вам также следует выяснить, почему ваша транзакция действительно активна (имеет записанный журнал). Типичный шаблон Service Broker не дает никаких записей до получения.
Ремус Русану
1
Я не понимаю ваш последний комментарий. Транзакция активна, потому что я выпустил. WAITFOR (RECEIVE...Не могли бы вы расширить? Возможно, я неправильно понял.
AngryHacker
8
begin transaction; waitfor(receive...)не будет генерировать какие-либо записи в журнале (не будет «активировать» транзакцию) во время ожидания и, следовательно, не будет закреплять журнал. Только begin transaction;[insert|update|delete];waitfor(receive...)заставит транзакцию «активировать» (генерировать записи журнала) и, таким образом, фактически закрепит журнал во время ожидания.
Ремус Русану
5

В SQL Server 2008 R2, если я выполняю WAITFOR (RECEIVE), а затем запускаю DBCC OPENTRAN, транзакция отображается как активная даже при отсутствии каких-либо предыдущих обновлений.

Найджел Паттинсон
источник
2
Правильно, WAITFOR создает точку сохранения внутри, и это запускает запись журнала, поэтому он фиксирует журнал на месте.
Ремус Русану
@RemusRusanu не противоречит вашим предыдущим комментариям к другому ответу ?
Бинки
@binki этот комментарий относится к SQL Server 2005. Это для 2008 R2. Они ведут себя по-разному в отношении этого вопроса, если я правильно помню.
Ремус Русану