¿Disparar un WAITFOR indefinido aumenta el tamaño del archivo de registro?
16
En la última versión de mi aplicación, agregué un comando que le dice que espere cuando algo llega a la cola de Service Broker:
WAITFOR(RECEIVE CONVERT(int, message_body)AS Message FROM MyQueue)
Los DBA me dicen que desde la adición, los tamaños de los registros se han ido por las nubes. ¿Podría ser esto correcto? ¿O debería estar buscando en otro lado?
Cualquier transacción abierta activa fijará el registro, evitando el truncamiento y eventualmente causando crecimiento. Si comienza una transacción, escriba en el registro y luego espere para siempre con la esperanza de que finalmente le despierte un mensaje, simplemente fijó el registro y lo hizo crecer.
Últimamente comencé a recomendar a las personas que evitaran el WAITFOR en el procedimiento activado, junto con el bucle. Solo emite un RECIEVe y listo, deja que el mecanismo de activación se repita por ti (lo hace) y no ESPERES, simplemente RECIBE.
El sabor WAITFOR de RECEIVE crea un punto de guardado internamente. Esto genera un registro (al menos 3 registros) y, de hecho, fija el registro en su lugar mientras espera. Tener un tiempo de espera largo de WAITFOR (o peor, uno infinito) sería una muy mala práctica.
¿ WAITFOR (...) TIMEOUT 3600000Resolvería el problema? Por ejemplo, liberar cada hora.
AngryHacker
2
Su registro crecerá mucho en una hora. WAITFOR (REC EIVE) está destinado a intervalos de 5 segundos ...
Remus Rusanu
1
También debe investigar por qué su transacción está realmente activa (tiene un registro escrito). El patrón típico de Service Broker no emite ninguna escritura antes de RECIBIR.
Remus Rusanu
1
No entiendo tu último comentario. La transacción está activa porque emití un WAITFOR (RECEIVE...mensaje ¿Podría expandirse? Quizás, entendí mal.
AngryHacker
8
begin transaction; waitfor(receive...)no generará ningún registro (no "activará" la transacción) mientras espera y, por lo tanto, no fijará el registro. Solo begin transaction;[insert|update|delete];waitfor(receive...)hará que la transacción se 'active' (genere registros de registro) y, por lo tanto, anclará el registro mientras espera.
Remus Rusanu
5
En SQL Server 2008 R2, si ejecuto un WAITFOR (RECEIVE), luego ejecuto DBCC OPENTRAN, muestra la transacción como activa, incluso en ausencia de actualizaciones anteriores.
@binki ese comentario se refiere a SQL Server 2005. Esto es para 2008 R2. Se comportan de manera diferente con respecto a este problema, si no recuerdo mal.
WAITFOR (...) TIMEOUT 3600000
Resolvería el problema? Por ejemplo, liberar cada hora.WAITFOR (RECEIVE...
mensaje ¿Podría expandirse? Quizás, entendí mal.begin transaction; waitfor(receive...)
no generará ningún registro (no "activará" la transacción) mientras espera y, por lo tanto, no fijará el registro. Solobegin transaction;[insert|update|delete];waitfor(receive...)
hará que la transacción se 'active' (genere registros de registro) y, por lo tanto, anclará el registro mientras espera.En SQL Server 2008 R2, si ejecuto un WAITFOR (RECEIVE), luego ejecuto DBCC OPENTRAN, muestra la transacción como activa, incluso en ausencia de actualizaciones anteriores.
fuente