Environ une fois par semaine, je dois résoudre une chaîne de blocage sur une base de données SQL Server 2005, causée par un verrou de lecture de longue durée à partir d'un frontal Access 2003. Le verrou est retiré chaque fois qu'un utilisateur ouvre un certain formulaire et est libéré une fois que l'utilisateur a fini de parcourir le formulaire ou de le fermer. Étant donné que beaucoup de nos utilisateurs ouvrent ce formulaire comme référence, ces verrous restent en place pendant un certain temps. Toute mise à jour de la table provoque le blocage, et soudainement, personne ne peut sélectionner dans cette table car ils attendent tous le premier verrou. C'est tout à fait un problème pour nous, car de nombreuses applications s'appuient sur ces données. Je comprends que ce comportement de verrouillage fait partie de la façon dont Access fonctionne avec les tables liées.
J'ai résolu le problème à partir du moniteur d'activité, en tuant le processus SELECT qui est le bloqueur de tête chaque fois que je le découvre. C'est un problème non seulement parce qu'il me faut du temps pour le faire manuellement, mais aussi parce qu'il est réactif. Au moment où j'en entends parler, cela a déjà été un problème pour beaucoup de gens.
Je voudrais savoir s'il existe un moyen automatique de vérifier ces chaînes de blocage durables et de recevoir un e-mail ou de résoudre le problème automatiquement. La logique semble assez simple ("si un processus correspondant à cette requête SELECT bloque depuis plus d'une minute, informez-moi / tuez-le") mais je ne sais pas comment l'implémenter avec SQL Server.
Pour ce que ça vaut, je pense que la bonne solution est de réparer ou de réécrire l'application. Cependant, en raison de la politique ministérielle, ce n'est pas une option pour les prochains mois, donc je cherche un bouche-trou.
la source
Réponses:
Avez-vous envisagé d'utiliser l' isolement d'instantané ? L'activation de read_committed_snapshot dans la base de données entraînera le verrouillage de toutes les lectures (sélections):
Aucune modification d'application. Certaines sémantiques changent sous l'instantané et votre application peut réagir bizarrement, mais ce n'est pas l'exception, mais la norme. La grande majorité des applications ne remarquent aucune différence, elles bénéficient simplement d'une amélioration gratuite des performances.
Quoi qu'il en soit, j'ai pensé à répondre également à la question d' origine : comment détecter (et éventuellement tuer) une requête de longue durée. En fait, le moteur le fait déjà pour vous. Un événement est déclenché lorsqu'un seuil est dépassé: Classe d'événements de rapport de processus bloqué . Le seuil est configuré via l' option de seuil de processus bloqué . Tout événement de trace peut être transformé en notification d'événement et les notifications d'événement peuvent activer des procédures . Connectez les points et vous disposez d'un code activé à la demande qui s'exécute lorsque le moteur détecte une requête qui a franchi un seuil de temps d'exécution. Pas de sondage, pas de surveillance. Notez cependant que la notification est asynchrone, au moment où vous le traitez, il se peut que la requête soit terminée, ce qui doit être pris en compte.
Voici un exemple:
Maintenant, dans une nouvelle requête, configurez une
WAITFOR
attente de notification:Et allez-y et provoquez un blocage. J'ai utilisé un processus qui a créé une table et n'a pas validé, et à partir d'une autre fenêtre de requête, j'ai essayé de sélectionner dans la table. En 20 secondes (mon seuil configuré ci-dessus), j'ai reçu le rapport de blocage:
Je laisserai au lecteur le soin d'en faire un processus automatisé. Et oui, la file d'attente / service / procédure activée doit être en
[msdb]
.la source
Vous pouvez soit créer votre propre outil de surveillance, soit rechercher une solution tierce qui peut vous en fournir un. Si vous souhaitez créer le vôtre, cela dépend de la version de SQL Server avec laquelle vous travaillez. S'il s'agit de 2005, vous pouvez utiliser l' événement de trace Rapport de processus bloqué . Si vous utilisez 2008 ou une version ultérieure, je vous suggère d'utiliser l'événement étendu équivalent, block_process_report. Jonathan Kehayias a une bonne écriture sur la façon de l'utiliser.
Si vous regardez des produits tiers, le moniteur SQL du logiciel Red Gate a bloqué les alertes de processus et de processus de longue durée.
la source
Bien que cela ne traite pas de la façon de vous informer du problème, cette procédure vous montrera comment interroger pour voir si un blocage existe. Il générera également des commandes kill pour vous, si vous passez le paramètre correct.
J'espère que cela vous donnera quelques idées.
la source
Je suggère de lire le sujet de forum MSDN suivant . Il s'agit du verrouillage provoqué par l'accès à une base de données SQL Server. La suggestion est principalement d'accéder aux tables par des requêtes à l'aide de l'indicateur NOLOCK, afin que cela ne cause aucun problème de verrouillage. NOLOCK n'est pas la meilleure solution, car il peut causer d'autres problèmes, mais réduira la plupart de vos problèmes de verrouillage.
La meilleure solution serait d'implémenter l'idée de Remus, de configurer l'isolement des instantanés sur votre base de données. Ou implémentez le niveau d'isolement d'instantané uniquement pour certaines connexions qui provoquent un blocage.
Afin de surveiller correctement votre serveur pour les problèmes de blocage, je suggère:
Si vous souhaitez une réponse proactive à ce problème, au lieu d'avoir un travail toutes les heures pour surveiller les traces, faites-le s'exécuter toutes les minutes et supprimez toute session d'accès bloquante principale.
la source
Suite à l'excellente réponse de @Remus Rusanu, j'ai effectué la tâche du lecteur pour connecter l'événement à une procédure stockée.
Dans mon cas, le sp écrira le xml de l'événement de blocage dans une table, mais vous êtes libre de faire ce que vous voulez à cette position.
Alors, suivez le code de Remus et créez le
queue
, leservice
et lenotification
avec un simple copier / coller d'en haut. Ajoutez lessp_configure
options et vous êtes fondamentalement défini.Il ne reste plus qu'à faire
queue
Dès que vous avez activé le SP, les événements commencent à affluer dans votre table.
J'ai découvert que la file d'attente se désactive immédiatement si le SP a une erreur. Dans ce cas, vous devez aller dans Server Studio et le réactiver dans le menu contextuel de l'entrée de file d'attente (
[msdb]->Service Broker->Warteschlangen
en version allemande).Il m'a fallu un certain temps pour que cela fonctionne et pour trouver les bons endroits dans la documentation, donc je suppose que cela est également utile pour les autres. J'utilise SQLServer 2005.
Créez le SP sans arguments
Créer la
pdix_lock_events
tableActivez le SP sur le
queue
la source