Je recherche les meilleures pratiques pour traiter les travaux d'agent SQL Server planifiés dans les groupes de disponibilité SQL Server 2012. Peut-être ai-je manqué quelque chose, mais à l'état actuel, je pense que SQL Server Agent n'est pas vraiment intégré à cette excellente fonctionnalité SQL2012.
Comment puis-je rendre un travail d'agent SQL planifié conscient d'un commutateur de noeud? Par exemple, j'ai un travail en cours sur le nœud principal qui charge les données toutes les heures. Maintenant, si le primaire tombe en panne, comment puis-je activer le travail sur le secondaire qui devient maintenant principal?
Si je planifie le travail toujours sur le secondaire, il échoue car le secondaire est en lecture seule.
Réponses:
Dans votre travail d'agent SQL Server, disposez d'une logique conditionnelle à tester pour déterminer si l'instance actuelle remplit le rôle particulier que vous recherchez dans votre groupe de disponibilité:
Tout cela consiste à extraire le rôle actuel du réplica local et, s'il en fait partie
PRIMARY
, vous pouvez faire ce que votre travail doit faire s'il s'agit du réplica principal. leELSE
bloc est facultatif, mais il permet de gérer la logique possible si votre réplica local n'est pas primaire.Bien entendu, remplacez
'YourAvailabilityGroupName'
la requête ci-dessus par le nom de votre groupe de disponibilité réel.Ne confondez pas les groupes de disponibilité avec les instances de cluster de basculement. Que l'instance soit le réplica principal ou secondaire d'un groupe de disponibilité donné n'affecte pas les objets de niveau serveur, tels que les travaux de l'Agent SQL Server, etc.
la source
Plutôt que de procéder de la sorte à chaque travail (en vérifiant l'état de chaque serveur pour chaque travail avant de décider de continuer), j'ai créé un travail en cours d'exécution sur les deux serveurs afin de vérifier l'état du serveur.
Cette approche fournit un certain nombre de choses
le script vérifie la base de données dans le champ ci-dessous
Ce proc est exécuté toutes les 15 minutes sur chaque serveur. (avec en prime l'ajout d'un commentaire pour informer les gens des raisons pour lesquelles l'emploi a été désactivé)
Ce n'est pas infaillible, mais pour les chargements de nuit et les travaux horaires, le travail est fait.
Mieux encore que d'exécuter cette procédure selon un planning, exécutez-la plutôt en réponse à l'alerte 1480 (alerte de changement de rôle de l'AG).
la source
Je suis conscient de deux concepts pour accomplir cela.
Prérequis: Sur la base de la réponse de Thomas Stringer, j'ai créé deux fonctions dans la base de données principale de nos deux serveurs:
Mettre fin à un travail s'il n'est pas exécuté sur le réplica principal
Dans ce cas, chaque travail sur les deux serveurs nécessite l'un des deux extraits de code suivants en tant qu'Étape 1:
Vérifier par nom de groupe:
Vérifier par nom de base de données:
Cependant, si vous utilisez ce second, méfiez-vous des bases de données système. Par définition, elles ne peuvent faire partie d'aucun groupe de disponibilité. Par conséquent, elles échoueront toujours.
Ces deux solutions sont prêtes à l'emploi pour les utilisateurs administrateurs. Pour les utilisateurs non-administrateurs, vous devez ajouter des autorisations supplémentaires, l'une d'entre elles suggérée ici :
Si vous définissez l'action d'échec sur Quitter le signalement du travail lors de cette première étape, le journal des travaux ne sera pas rempli de signes de croix rouges, mais pour le travail principal, ils deviendront des signes d'alerte jaunes.
D'après notre expérience, ce n'est pas idéal. Nous avons d’abord adopté cette approche, mais avons rapidement perdu le fil de la recherche des travaux qui posaient problème, car tous les travaux de réplicas secondaires encombraient le journal des travaux avec des messages d’avertissement.
Nous sommes ensuite allés chercher:
Proxy jobs
Si vous adoptez ce concept, vous devrez en fait créer deux tâches par tâche à exécuter. Le premier est le "travail proxy" qui vérifie s'il est exécuté sur le réplica principal. Si tel est le cas, il lance le "job worker", sinon, il se termine normalement sans encombrer le journal de messages d'avertissement ou d'erreur.
Personnellement, je n’aime pas l’idée d’avoir deux tâches par tâche sur chaque serveur, mais je pense que c’est nettement plus facile à gérer, et vous n’aurez pas à définir l’action en cas d’échec de l’étape Fin du rapport de tâche , ce qui est un peu gênant.
Pour les emplois, nous avons adopté un schéma de nommage. Le travail proxy est appelé
{put jobname here}
. Le travail de travailleur s'appelle{put jobname here} worker
. Cela permet d'automatiser le démarrage du travail de travail à partir du proxy. Pour ce faire, j'ai ajouté la procédure suivante aux deux dbs maîtres:Ceci utilise la
svf_AgReplicaState
fonction montrée ci-dessus, vous pouvez facilement changer cela pour vérifier en utilisant le nom de la base de données à la place en appelant l'autre fonction.À partir de la seule étape du travail de proxy, vous l'appelez comme suit:
Ceci utilise les jetons comme indiqué ici et ici pour obtenir l'identifiant du travail en cours. La procédure récupère ensuite le nom du travail actuel auprès de msdb, y est ajoutée
worker
et démarre le travail de travail avecsp_start_job
.Bien que cela ne soit toujours pas idéal, les journaux de travail sont plus propres et faciles à gérer que l’option précédente. En outre, le travail de proxy peut toujours être exécuté avec un utilisateur sysadmin. Il n'est donc pas nécessaire d'ajouter des autorisations supplémentaires.
la source
Si le processus de chargement de données est un simple appel de requête ou de procédure, vous pouvez créer le travail sur les deux nœuds et le laisser déterminer s'il s'agit du nœud principal en fonction de la propriété Updateability de la base de données, avant d'exécuter le processus de chargement de données:
la source
Il est toujours préférable de créer une nouvelle étape de travail qui vérifie s'il s'agit d'un réplica principal, alors tout va bien pour continuer l'exécution du travail, s'il s'agit d'un réplica secondaire, puis arrêter le travail. N'échouez pas le travail sinon il continuera d'envoyer des notifications inutiles. Au lieu de cela, arrêtez le travail pour qu'il soit annulé et qu'aucune notification ne soit envoyée chaque fois que ces travaux sont exécutés sur le réplica secondaire.
Voici le script pour ajouter une première étape pour un travail spécifique.
Note pour exécuter le script:
S'il existe plusieurs groupes de disponibilité, définissez le nom de l'AG dans la variable @AGNameToCheck_IfMoreThanSingleAG afin de déterminer quel AG doit être vérifié pour son état de réplique.
Notez également que ce script devrait bien fonctionner même sur les serveurs ne disposant pas de groupes de disponibilité. S'exécutera uniquement pour les versions SQL Server 2012 et ultérieures.
la source
Une autre méthode consiste à insérer une étape dans chaque travail, qui doit s'exécuter en premier, avec le code suivant:
Définissez cette étape pour passer à l'étape suivante en cas de succès et pour quitter le travail en signalant le succès en cas d'échec.
Je trouve plus propre d'ajouter une étape supplémentaire au lieu d'ajouter de la logique à une étape existante.
la source
Une autre option, plus récente, utilise master.sys.fn_hadr_is_primary_replica ('DbName'). J'ai trouvé cela très utile lors de l'utilisation de SQL Agent pour la maintenance de la base de données (associée à un curseur que j'avais utilisé pendant des années), ainsi que lors de l'exécution d'une tâche ETL ou d'une autre tâche spécifique à la base de données. L'avantage est que la base de données est isolée plutôt que de regarder l'ensemble du groupe de disponibilité ... si c'est ce dont vous avez besoin. Cela rend également beaucoup plus improbable qu'une commande soit exécutée sur une base de données qui "était" sur la base principale, mais supposons qu'un basculement automatique s'est produit lors de l'exécution du travail et qu'il s'agit maintenant d'un réplica secondaire. Les méthodes ci-dessus, qui examinent le réplica principal, ne font qu'une mise à jour. N'oubliez pas qu'il s'agit simplement d'une manière différente d'obtenir des résultats très similaires et de donner un contrôle plus granulaire, si vous en avez besoin. De plus, la raison pour laquelle cette méthode n'a pas été abordée lorsque cette question a été posée est que Microsoft n'a pas publié cette fonction avant la publication de SQL 2014. Voici quelques exemples d'utilisation de cette fonction:
Si vous souhaitez utiliser ceci pour la maintenance de la base de données utilisateur, voici ce que j'utilise:
J'espère que c'est un conseil utile!
la source
J'utilise ceci:
la source