L'attivazione di un WAITFOR indefinito aumenta le dimensioni del file di registro?


16

Nell'ultima versione della mia app, ho aggiunto un comando che dice di attendere quando arriva qualcosa nella coda di Service Broker:

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

I DBA mi dicono che dall'aggiunta, le dimensioni del tronco sono passate attraverso il tetto. Potrebbe essere corretto? O dovrei cercare altrove?

Risposte:


17

Qualsiasi transazione aperta attiva bloccherà il registro, impedendo il troncamento e infine causando la crescita. Se avvii una transazione, scrivi nel registro e attendi per sempre nella speranza che un messaggio alla fine ti svegli, hai appena bloccato il registro e lo fai crescere.

Ultimamente ho iniziato a raccomandare alle persone di evitare il WAITFOR nella procedura attivata, insieme al loop. Basta emettere un RECIEVe ed essere fatto, lasciare che il meccanismo di attivazione esegua il ciclo per te (lo fa) e non ATTENDERE, semplicemente RECEIVE.

Il sapore WAITFOR di RECEIVE crea internamente un punto di salvataggio. Questo genera log (almeno 3 record di log) e in effetti blocca il log in posizione durante l'attesa. Avere un lungo timeout WAITFOR (o peggio, infinito) sarebbe una pessima pratica.


1
Sarebbe WAITFOR (...) TIMEOUT 3600000risolvere il problema? Ad esempio rilascio ogni ora.
AngryHacker,

2
Il tuo registro crescerà molto in un'ora. WAITFOR (REC EIVE) è pensato per intervalli di 5 secondi ...
Remus Rusanu,

1
Dovresti anche scoprire perché la tua transazione è effettivamente attiva (ha un registro scritto). Il tipico modello di Service Broker non emette alcuna scrittura prima di RECEIVE.
Remus Rusanu,

1
Non capisco il tuo ultimo commento. La transazione è attiva perché ho emesso un messaggio WAITFOR (RECEIVE...Potresti espandere? Forse ho frainteso.
AngryHacker,

8
begin transaction; waitfor(receive...)non genererà alcun record di registro (non "attiverà" la transazione) durante l'attesa e quindi non bloccherà il registro. Solo begin transaction;[insert|update|delete];waitfor(receive...)la transazione si "attiverà" (genererà i record del registro) e quindi bloccherà effettivamente il registro durante l'attesa.
Remus Rusanu,

5

Su SQL Server 2008 R2, se eseguo un WAITFOR (RECEIVE), quindi eseguo DBCC OPENTRAN, mostra la transazione come attiva, anche in assenza di eventuali aggiornamenti precedenti.


2
Corretto, WAITFOR crea internamente un punto di salvataggio e ciò innesca la scrittura del registro in modo da bloccare il registro in posizione.
Remus Rusanu,

@RemusRusanu non contraddice i tuoi precedenti commenti sull'altra risposta ?
binki,

@binki quel commento si riferisce a SQL Server 2005. Questo è per 2008 R2. Si comportano in modo diverso rispetto a questo problema, se ricordo bene.
Remus Rusanu,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.