Pregunta

En nuestra base de datos en vivo / de producción, estoy tratando de agregar un disparador a una tabla, pero no he tenido éxito. Lo he intentado varias veces, pero ha tardado más de 30 minutos en completarse la instrucción de creación de activador y la he cancelado.

La tabla es aquella que se lee / escribe a menudo mediante un par de procesos diferentes. He desactivado los trabajos programados que actualizan la tabla y he intentado en ocasiones cuando hay menos actividad en la tabla, pero no puedo detener todo lo que accede a la tabla.

No creo que haya un problema con la propia instrucción de creación de activador. La declaración de creación de desencadenador fue exitosa y rápida en un entorno de prueba, y el desencadenador funciona correctamente cuando se insertan / actualizan filas en la tabla. Aunque cuando creé el disparador en la base de datos de prueba, no había carga en la tabla y tenía considerablemente menos filas, que es diferente que en la base de datos en vivo / producción (100 frente a 13,000,000+).

Aquí está la declaración de creación de activador que estoy tratando de ejecutar

CREATE TRIGGER [OnItem_Updated] 
    ON  [Item]
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF update(State)
    BEGIN
        /* do some stuff including for each row updated call a stored 
          procedure that increments a value in table based on the 
          UserId of the updated row */
    END
END

¿Puede haber problemas con la creación de un activador en una tabla mientras se actualizan las filas o si tiene muchas filas?

En SQLServer, los activadores se crean habilitados de forma predeterminada. ¿Es posible crear el disparador deshabilitado por defecto?

¿Alguna otra idea?

¿Fue útil?

Solución

El problema puede no estar en la tabla en sí, sino en las tablas del sistema que deben actualizarse para crear el desencadenador. Si está haciendo cualquier otro tipo de DDL como parte de sus procesos normales, podrían estar retrasándolo.

Use sp_who para averiguar de dónde viene el bloque y luego investigue desde allí.

Otros consejos

Creo que el gatillo CREATE intentará poner un candado en toda la mesa.

Si tiene mucha actividad en esa mesa, puede que tenga que esperar mucho tiempo y podría estar creando un punto muerto.

Para cualquier cambio de esquema, realmente debería obtener todos los datos de la base de datos.

Dicho esto, es tentador poner " pequeño " Cambios con conexiones activas. Debería echar un vistazo a las cerraduras / conexiones para ver dónde está la contención de la cerradura.

Eso es extraño. Un activador DESPUÉS DE LA ACTUALIZACIÓN no debería tener que verificar las filas existentes en la tabla. Supongo que es posible que no pueda obtener un bloqueo en la tabla para agregar el disparador.

Puede intentar crear un disparador que básicamente no haga nada. Si no puede crear eso, entonces es un problema de bloqueo. Si puede, puede deshabilitar ese disparador, agregar el código deseado al cuerpo y habilitarlo. (No creo que pueda deshabilitar un activador durante la creación).

Parte del problema también puede ser el propio disparador. ¿Podría su activador estar actualizando accidentalmente todas las filas de la tabla? Hay una gran diferencia entre 100 filas en una base de datos de prueba y 13,000,000. Es una muy mala idea desarrollar código contra un conjunto tan pequeño cuando tiene un conjunto de datos tan grande que no puede tener forma de predecir el rendimiento. SQL que funciona bien para 100 registros puede bloquear completamente un sistema con millones por horas. Realmente quieres saber eso en el desarrollo, no cuando promueves a prod.

Por lo general, llamar a un proceso almacenado en un activador es una muy mala elección. También significa que tiene que recorrer los registros, lo cual es una elección aún peor en un disparador. Los activadores deben tener en cuenta las inserciones / actualizaciones o eliminaciones de múltiples registros. Si alguien inserta 100,000 filas (no es improbable si tiene 13,000,000 de registros), recorrer un proceso almacenado basado en registros puede llevar horas, bloquear toda la tabla y hacer que todos los usuarios quieran perseguir al desarrollador y matar (o al menos mutilar) Él porque no pueden hacer su trabajo.

Ni siquiera consideraría poner este activador en prod hasta que pruebe con un conjunto de registros similar en tamaño a prod.

Mi amigo Dennis escribió este artículo que ilustra por qué probar un pequeño volumen de información cuando tienes un gran volumen de información puede crear dificultades en el PRD que no notaste en el Dev: http://blogs.lessthandot.com/index.php/DataMgmt/?blog=3&title=your-testbed-has-to-have-the-same-volume& disp = single & amp; more = 1 & amp; c = 1 & amp; tb = 1 & amp; pb = 1 # c1210

Ejecute DISABLE TRIGGER triggername ON nombre de tabla antes de modificar el activador, luego vuelva a habilitarlo con ENABLE TRIGGER triggername ON nombre de tabla

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top