Disparar um WAITFOR indefinido aumenta o tamanho do arquivo de log?

16

Na última versão do meu aplicativo, adicionei um comando que diz para aguardar quando algo chegar na fila do Service Broker:

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

Os DBAs dizem que, desde a adição, os tamanhos dos toros passaram do teto. Isso pode estar correto? Ou devo procurar em outro lugar?

AngryHacker
fonte

Respostas:

17

Qualquer transação aberta ativa fixará o log, impedindo o truncamento e, eventualmente, causando crescimento. Se você iniciar uma transação, escreva no log e espere eternamente na esperança de que uma mensagem eventualmente acorde, você acabou de fixar o log e fazer com que ele cresça.

Ultimamente, comecei a recomendar que as pessoas evitassem o WAITFOR no procedimento ativado, junto com o loop. Apenas emita um RECIEVe e pronto, deixe o mecanismo de ativação girar para você (ele faz) e não espere, simplesmente RECEIVE.

O sabor WAITFOR de RECEIVE cria um ponto de salvamento internamente. Isso gera log (pelo menos 3 registros de log) e, de fato, fixa o log no local enquanto aguarda. Ter um tempo limite longo do WAITFOR (ou pior, um tempo infinito) seria uma prática muito ruim.

Remus Rusanu
fonte
11
Iria WAITFOR (...) TIMEOUT 3600000resolver o problema? Por exemplo, liberar a cada hora.
AngryHacker
2
Seu log crescerá muito em uma hora. WAITFOR (REC EIVE) destina-se a intervalos como 5 segundos ...
Remus Rusanu
11
Você também deve investigar por que sua transação está realmente ativa (possui registro escrito). O padrão típico do Service Broker não emite nenhuma gravação antes do RECEIVE.
Remus Rusanu
11
Não entendo seu último comentário. A transação está ativa porque emiti um WAITFOR (RECEIVE...Você poderia expandir? Talvez eu tenha entendido errado.
AngryHacker
8
begin transaction; waitfor(receive...)não gerará nenhum registro de log (não 'ativará' a transação) enquanto aguarda e, portanto, não fixará o log. Somente begin transaction;[insert|update|delete];waitfor(receive...)fará com que a transação seja 'ativada' (gerar registros de log) e, portanto, realmente fixará o log enquanto aguarda.
Remus Rusanu
5

No SQL Server 2008 R2, se eu executar um WAITFOR (RECEIVE) e executar o DBCC OPENTRAN, ele mostrará a transação como ativa, mesmo na ausência de atualizações anteriores.

Nigel Pattinson
fonte
2
Correto, o WAITFOR cria um ponto de salvamento internamente e isso aciona a gravação do log para fixar o log no local.
Remus Rusanu
@RemusRusanu não contradiz seus comentários anteriores sobre a outra resposta ?
binki
@binki esse comentário se refere ao SQL Server 2005. Isso é para 2008 R2. Eles se comportam de maneira diferente em relação a esse problema, se bem me lembro.
Remus Rusanu