Un bon moyen d'appeler plusieurs travaux de l'Agent SQL Server de manière séquentielle à partir d'un seul travail principal?


11

J'ai plusieurs travaux d'agent SQL Server qui devraient s'exécuter de manière séquentielle. Pour garder une bonne vue d'ensemble des travaux qui devraient s'exécuter, j'ai créé un travail principal qui appelle les autres travaux avec un appel à EXEC msdb.dbo.sp_start_job N'TEST1'. Le se sp_start_jobtermine instantanément (Étape 1 du travail), mais je veux que mon travail principal attende la fin du travail TEST1avant d'appeler le prochain travail.

J'ai donc écrit ce petit script qui commence à s'exécuter juste après l'appel du travail (étape 2 du travail) et force le travail principal à attendre la fin du sous-travail:

WHILE 1 = 1
  BEGIN
    WAITFOR DELAY '00:05:00.000';

    SELECT *
    INTO   #jobs
    FROM   OPENROWSET('SQLNCLI', 'Server=TESTSERVER;Trusted_Connection=yes;',
           'EXEC msdb.dbo.sp_help_job @job_name = N''TEST1'',
           @execution_status = 0, @job_aspect = N''JOB''');

    IF NOT (EXISTS (SELECT top 1 * FROM #jobs))
      BEGIN
        BREAK
      END;

    DROP TABLE #jobs;

  END;

Cela fonctionne assez bien. Mais j'ai l'impression que des WHILE 1 = 1solutions plus intelligentes et / ou plus sûres ( ?) Devraient être possibles.

Je suis curieux de savoir ce qui suit, j'espère que vous pourrez me fournir quelques informations:

  • Quels sont les problèmes avec cette approche?
  • Pouvez-vous suggérer une meilleure façon de procéder?

(J'ai d'abord posé cette question sur StackOverflow , parce que je me concentrais sur l'amélioration du code. Toujours valide. Mais je suppose que les gens ici auront en général des choses plus intelligentes à dire sur les raisons pour lesquelles je ne devrais pas essayer de le faire comme je le fais. Je le fais maintenant ou offre de bonnes alternatives.)

EDIT (25 juillet)
Apparemment, il n'y a pas trop de problème avec mon script, selon le faible nombre de réponses signalant des problèmes avec celui-ci :-) L'alternative à ce type de script semble être d'utiliser un outil conçu pour ces (comme SQL Sentry Event Manager ou ...) - ou pour écrire un tel outil vous-même. Nous n'achèterons pas un tel outil dans mon entreprise actuelle, donc pour l'instant je vais simplement m'en tenir au script.


Avez-vous envisagé d'avoir ces emplois comme étapes de l'emploi principal au lieu d'emplois indépendants? Cela réduirait la complexité, surtout s'ils ne sont jamais appelés ensemble dans une séquence de cette façon ...
Aaron Bertrand

C'est un équilibre. Ce serait une maintenance «plus propre» si nous ajoutions tous les travaux en tant qu'étapes au travail principal, mais nous perdrions beaucoup de vue d'ensemble et la possibilité d'exécuter manuellement des travaux spécifiques lorsque nous le ferions. Je l'ai donc certainement envisagé, mais la «solution» actuelle présente trop d'avantages - tant qu'elle fonctionne.

Réponses:


9

Avertissement: je travaille pour SQL Sentry.

Notre produit SQL Sentry Event Manager a une fonctionnalité conçue spécialement pour cela: pour enchaîner les tâches et les organiser dans divers ordres de workflow.

J'ai commencé à utiliser SQL Sentry il y a des années, avant de rejoindre l'entreprise, pour faire exactement cela. Ce que je voulais, c'était un moyen de démarrer un travail de restauration sur notre serveur de test immédiatement après la fin de la sauvegarde en production.

Ce que j'avais initialement implémenté n'était qu'un tampon substantiel entre l'heure de début du travail de sauvegarde et l'heure de début de la restauration. Ce n'était pas vraiment infaillible; comme les temps de sauvegarde variaient, le tampon nous laissait souvent du temps perdu où une restauration n'avait pas commencé même si elle aurait pu. Et parfois, le tampon n'était pas suffisant.

Ce que j'ai implémenté ensuite était similaire à ce que vous avez - j'ai écrit un travail sur le serveur de test qui a commencé peu de temps après la sauvegarde planifiée et j'ai continué à interroger pour voir quand le travail était terminé. Cela a été modifié par la suite pour n'avoir qu'une deuxième étape dans le travail de sauvegarde qui a mis à jour une table sur le serveur de test. Pas vraiment très différent, sauf que le travail de restauration n'avait qu'à regarder une table localement au lieu de surveiller l'historique des travaux à distance. En y repensant, cela aurait pu être un déclencheur sur cette table qui a appelé sp_start_jobafin que le travail n'ait pas à s'exécuter toutes les n minutes (ou à être planifié du tout).

La solution finale était de chaîner les travaux ensemble ... lorsque la sauvegarde sur le serveur A se termine, Event Manager démarre le travail de restauration sur le serveur B. Et s'il y avait un troisième travail et un quatrième travail, ou une logique conditionnelle basée sur ce qu'il faut faire quand un travail échoue vs réussit, etc., tout cela peut être expliqué. Le concepteur de workflow vous rappellera un peu SSIS:

entrez la description de l'image ici

La mécanique sous-jacente de ce que je décris n'est pas la chirurgie à la fusée, bien sûr. Vous pouvez écrire vous-même ce type d'encapsuleur de chaînage si vous vous asseyez et le faites. Vous offrant simplement une alternative là où vous n'avez pas à le faire.


2

Le principal problème avec votre approche est que vous devez continuellement boucler jusqu'à ce que quelque chose se produise (ce qui pourrait être terriblement long ou même jamais) et cela ne vous semble pas tout à fait correct. C'est pourquoi je suppose que vous posez la question.

Alors, que diriez-vous d'utiliser une approche basée sur les données pour votre problème? Par exemple, créez une table «d'audit» dans laquelle chaque travail écrit au début et à la fin:

Nom du poste | Heure de début | Heure de fin
--------- + ------------------- + ------------------
Test1 2012-07-26 07:30 2012-07-26 07:35

Créez une table de «traitement» qui répertorie tous les travaux et l'ordre dans lequel ils doivent être exécutés:

Nom du poste | Exécuter l'ordre
--------- + ---------
Test1 | 1
Test2 | 2
Test3 | 3

Créez un déclencheur d'insertion sur la table d'audit, de sorte que lorsqu'un travail se termine et que l'enregistrement d'audit soit inséré, le déclencheur interroge la table de traitement pour le travail suivant (par ordre d'exécution), puis le lance.

Les avantages de cette approche sont:

  1. Il est assez simple à développer et à entretenir.
  2. Il donne la possibilité d'ajouter de nouveaux travaux ou de changer l'ordre des travaux existants via la table de traitement sans avoir à changer une ligne de code.
  3. La table d'audit donne une certaine visibilité sur le moment où les choses se sont produites.
  4. Il ne gaspille pas les cycles CPU. Le déclencheur ne se déclenche que lorsque quelque chose s'est produit.
  5. Ça fait du bien 😉

HTH


1
Merci beaucoup, aimez votre réponse! Je vais certainement essayer!
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.