Question

Sur notre base de données live / production, j'essaie d'ajouter un déclencheur à une table, mais j'ai échoué. J'ai essayé plusieurs fois, mais il a fallu plus de 30 minutes pour que l'instruction create trigger se termine et je l'ai annulée.

La table est une table dans laquelle on lit / écrit souvent par deux processus différents. J'ai désactivé les travaux planifiés qui mettent à jour la table et tenté parfois lorsqu'il y a moins d'activité sur la table, mais je ne peux pas arrêter tout ce qui accède à la table.

Je ne crois pas qu'il y ait un problème avec l'instruction create trigger elle-même. L'instruction create trigger a abouti et a été rapide dans un environnement de test, et le déclencheur fonctionne correctement lorsque des lignes sont insérées / mises à jour dans la table. Bien que, lors de la création du déclencheur sur la base de données de test, la table n’était pas chargée et comportait beaucoup moins de lignes, ce qui diffère de la base de données live / production (100 contre 13 000 000 +).

Voici la déclaration de déclencheur de création que j'essaie d'exécuter

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

Peut-il y avoir des problèmes avec la création d'un déclencheur sur une table pendant la mise à jour des lignes ou si celle-ci comporte plusieurs lignes?

Dans SQLServer, les déclencheurs sont créés activés par défaut. Est-il possible de créer le déclencheur désactivé par défaut?

Avez-vous d'autres idées?

Était-ce utile?

La solution

Le problème ne réside peut-être pas dans la table elle-même, mais dans les tables système qui doivent être mises à jour pour créer le déclencheur. Si vous utilisez un autre type de DDL dans le cadre de vos processus habituels, il se peut qu’il l’arrête.

Utilisez sp_who pour savoir d’où vient le bloc puis recherchez-le à partir de là.

Autres conseils

Je pense que CREATE Trigger va tenter de verrouiller la table entière.

Si vous avez beaucoup d'activité sur cette table, vous devrez peut-être attendre longtemps et vous pourriez créer une impasse.

Pour tout changement de schéma, vous devriez vraiment récupérer tout le monde dans la base de données.

Cela dit, il est tentant de mettre dans "petit". changements avec les connexions actives. Vous devriez jeter un coup d’œil sur les verrous / connexions pour voir où est le conflit de verrous.

C'est étrange. Un déclencheur AFTER UPDATE ne devrait pas obligatoirement vérifier les lignes existantes de la table. Je suppose qu'il est possible que vous ne puissiez pas obtenir un verrou sur la table pour ajouter le déclencheur.

Vous pouvez essayer de créer un déclencheur qui ne fait fondamentalement rien. Si vous ne pouvez pas créer cela, alors c'est un problème de verrouillage. Si vous le pouvez, vous pouvez désactiver ce déclencheur, ajouter le code souhaité au corps et l'activer. (Je ne pense pas que vous puissiez désactiver un déclencheur lors de la création.)

Une partie du problème peut également être le déclencheur lui-même. Votre déclencheur pourrait-il mettre à jour accidentellement toutes les lignes de la table? Il existe une grande différence entre 100 lignes dans une base de test et 13 000 000. C'est une très mauvaise idée de développer du code sur un ensemble aussi petit lorsque vous avez un ensemble de données aussi volumineux, car vous ne pouvez pas prévoir les performances. SQL qui fonctionne bien pour 100 enregistrements peut complètement verrouiller un système avec des millions d’individus pendant des heures. Vous voulez vraiment savoir cela en développement, pas lorsque vous faites la promotion de prod.

Appeler un processus stocké dans un déclencheur est généralement un très mauvais choix. Cela signifie également que vous devez parcourir des enregistrements, ce qui est un choix encore pire en cas de déclenchement. Les déclencheurs doivent toujours avoir un compte pour plusieurs insertions, mises à jour ou suppressions d'enregistrements. Si quelqu'un insère 100 000 lignes (ce qui est peu probable si vous avez 13 000 000 enregistrements), alors le bouclage d'un processus stocké basé sur un enregistrement peut prendre des heures, verrouiller la table entière et inciter tous les utilisateurs à traquer le développeur et à tuer (ou au moins à mutiler). car ils ne peuvent pas faire leur travail.

Je n’envisagerais même pas d’appliquer ce déclencheur à la production tant que vous n’auriez pas testé contre un jeu d’enregistrements de taille similaire à la production.

Mon ami Dennis a écrit cet article qui illustre pourquoi le fait de tester un petit volume d'informations lorsque vous avez un grand volume d'informations peut créer des difficultés sur prd que vous n'avez pas remarquées dans 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

Exécutez DISABLE TRIGGER sur triggername ON nom de table avant de modifier le déclencheur, puis réactivez-le avec ENABLE TRIGGER triggername ON nom de table

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top