Le fait de déclencher une WAITFOR indéfinie augmente la taille du fichier journal?

16

Dans la dernière version de mon application, j'ai ajouté une commande qui lui indique d'attendre lorsque quelque chose arrive dans la file d'attente Service Broker:

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

Les administrateurs de base de données me disent que depuis l'ajout, les tailles de bûches ont traversé le toit. Serait-ce correct? Ou devrais-je chercher ailleurs?

AngryHacker
la source

Réponses:

17

Toute transaction ouverte active épinglera le journal, empêchant la troncature et éventuellement entraînant une croissance. Si vous démarrez une transaction, écrivez dans le journal et attendez éternellement dans l'espoir qu'un message finira par vous réveiller, vous venez d'épingler le journal et de le faire grossir.

Dernièrement, j'ai commencé à recommander aux gens d'éviter la WAITFOR en procédure activée, avec la boucle. Émettez simplement un RECIEVe et faites-le, laissez le mécanisme d'activation boucler pour vous (il le fait) et n'ATTENDEZ PAS, RECEVEZ simplement.

La saveur WAITFOR de RECEIVE crée un point de sauvegarde en interne. Cela génère un journal (au moins 3 enregistrements de journal) et épingle le journal en place en attendant. Avoir un long délai d'attente WAITFOR (ou pire, infini) serait une très mauvaise pratique.

Remus Rusanu
la source
1
Résoudrait WAITFOR (...) TIMEOUT 3600000le problème? Par exemple, libération toutes les heures.
AngryHacker
2
Votre journal augmentera beaucoup en une heure. WAITFOR (REC EIVE) est conçu pour des intervalles comme 5 secondes ...
Remus Rusanu
1
Vous devez également rechercher pourquoi votre transaction est réellement active (a un journal écrit). Le modèle typique de Service Broker n'émet aucune écriture avant la RÉCEPTION.
Remus Rusanu
1
Je ne comprends pas votre dernier commentaire. La transaction est active car j'ai émis un WAITFOR (RECEIVE...message Pouvez-vous développer? Peut-être que j'ai mal compris.
AngryHacker
8
begin transaction; waitfor(receive...)ne générera aucun enregistrement de journal (n'activera pas la transaction) pendant l'attente et n'épinglera donc pas le journal. Seul begin transaction;[insert|update|delete];waitfor(receive...)provoquera l'activation de la transaction (générer des enregistrements de journal) et épinglera donc réellement le journal en attendant.
Remus Rusanu
5

Sur SQL Server 2008 R2, si j'exécute un WAITFOR (RECEIVE), puis que j'exécute DBCC OPENTRAN, il indique que la transaction est active, même en l'absence de toute mise à jour préalable.

Nigel Pattinson
la source
2
Correct, WAITFOR crée un point de sauvegarde en interne et cela déclenche l'écriture du journal afin qu'il épingle le journal en place.
Remus Rusanu
@RemusRusanu cela ne contredit-il pas vos commentaires précédents sur l'autre réponse ?
binki
@binki ce commentaire fait référence à SQL Server 2005. Il s'agit de 2008 R2. Ils se comportent différemment en ce qui concerne cette question, si je me souviens bien.
Remus Rusanu