web-dev-qa-db-fra.com

Comment éviter une requête de sélection pour maintenir un verrou Sch-S

Je recherche une option pour éviter les verrous Sch-S lors de l'exécution d'une requête Select.

J'ai une base de données qui est contrôlée par une application écrite par d'autres ainsi que ma propre application. L'une des tables contient des millions de lignes. Je n'ai aucun problème avec les lectures incorrectes, etc. mais je ne fais pas ma requête de sélection pour verrouiller les autres requêtes d'indexation ou de modification d'application qui doivent attendre en raison des verrous Sch-S de ma requête.

J'ai essayé de définir un instantané du niveau d'isolement avant d'appeler ma requête, mais cela ne faisait aucune différence non plus AVEC l'option NOLOCK qui acquiert toujours un verrou Sch-S.

Je cherche une option pour exécuter une sélection sur une table sans acquérir Sch-S ou tout type de verrou, peut-être si nous pouvons rapidement avoir un instantané/vue ou une copie temporaire (cela fonctionnera-t-il car il a des millions de lignes de données?) de la table sans acquérir aucun type de verrou du tout.

4
AKS

Un verrou Sch-S est un verrou de stabilité du schéma. Il est pris pour s'assurer que la structure de la table ne change pas. Cela inclut l'ajout/la suppression de colonnes, etc. Les astuces NOLOCK et les niveaux d'isolement affectent le verrouillage et la gestion des versions des données dans la table, pas la structure de la table elle-même.

Même une opération d'indexation en ligne devra prendre brièvement les verrous Sch-S et Sch-M. Vous ne pouvez pas éviter cela pour les requêtes d'indexation ou de modification de schéma.

5
StrayCatDBA

D'accord avec StrayCatDBA et leur réponse.

Les verrous de stabilité de schéma sont l'une des parties nécessaires de SQL Server. Bien que vous puissiez absorber une lecture sale (ou l'un des problèmes liés aux lectures non validées), vous ne pouvez vraiment pas absorber l'impact d'un changement de schéma sous-jacent sur votre requête intermédiaire. Vraiment, SQL ne pouvait pas le gérer non plus. C'est donc un verrou dont vous ne pouvez pas vous débarrasser.

Je pense, cependant, qu'il peut y avoir une question sous-jacente plus profonde ici. Pourquoi dis-je cela? Parce qu'en travaillant avec SQL Server depuis 20 ans maintenant, j'ai été parfois frustré par le verrouillage impliquant des verrous SCH-S ou SCH-M, mais je ne me suis jamais trouvé à dire: "Oh! Si seulement je pouvais supprimer cette stabilité embêtante du schéma ou des verrous de modification de schéma, tout serait résolu !! "

Deux sélections détenant chacune un verrou SCH-S ne nuiront pas à vos requêtes. Une mise à jour ne bloquera pas une sélection avec car elle contient un verrou SCH-S, elle le bloquerait si vous étiez au niveau d'isolement validé en lecture (par défaut) et les verrous nécessaires au niveau de la table ou de la page sont incompatibles avec ceux pour la mise à jour, par exemple.

Je voudrais donc vous retourner la question et vous demander ce que vous faites pour être brûlé par les serrures SCH-S. Votre verrou SCH-S ne pose normalement pas de problème sauf si quelque chose d'autre essaie de tronquer une table, de modifier une table, de modifier une colonne, etc. Ou pendant les opérations de reconstruction d'index.

Vous pouvez donc soit avoir une situation où vous devez (1) analyser le DML se produisant par rapport à votre table pendant les charges de travail de production; (2) ou une situation où un autre type de verrou est le vrai problème; (3) ou une situation où peut-être vous faites vraiment quelque chose qui rend en quelque sorte un bloc le long de ce type de verrouillage logique.

Pour ceux que je commencerais probablement par l'un des chemins:

  1. Découvrez pourquoi vous faites du DML en direct sur une table que vous essayez de lire en direct et arrêtez de le faire ou proposez un meilleur processus pour mettre ces lectures ailleurs.
  2. C'est ce que je soupçonne. Essayez de trouver votre blocage SQL (essayez d'utiliser SP_Whoisactive et attrapez un bloc - qu'est-ce que le blocage session_id? Que fait-il? Regardez cela et voyez si c'est vraiment votre problème). Traitez la véritable cause de blocage.
  3. Si ce comportement était vraiment attendu. Vous devrez trier une autre manière de récupérer des données sur une copie de la table. Beaucoup d'approches ici. Le diffuser sur deux tables, ETL, Readable AG secondaire, réplication, etc. Mais attention, toutes ces techniques impliqueront un verrou SCH-S. En bref - la SEULE opération qui devrait bloquer un verrou maintenu SCH-S serait un verrou SCH-M. Ainsi, la seule façon dont cela se produirait serait que quelqu'un modifie la STRUCTURE d'une table pendant que vous interrogez les données de la table.

Je suppose que vous êtes vraiment sur une chasse aux oies, et le problème est n ° 2, cependant.

MISE À JOUR - En relisant votre question, je suis plus convaincu que vous êtes probablement soit A.) dans une bonne situation sans problème et simplement proactif/inquiet ou B.) votre application fait une fréquence d'index ou de table très élevée modifications en milieu de journée de production. Je suis plus convaincu que vous allez bien ici. Et la réponse de copier toutes les données pour éviter un verrou SCH-S ne convient pas vraiment - car vous aurez probablement plus de problèmes de performances en copiant ces données et en les mettant à jour et en générant des verrous SCH-S Là.

La vraie réponse serait de regarder quelles sont les opérations dans l'application du fournisseur qui provoquent les verrous SCH-M qui sont bloqués par vos verrous SCH-S. Peut-être en regardant les reconstructions d'index en ligne si l'entreprise, peut-être moins de fréquence, etc.

4
Mike Walsh

Je suis tombé sur la même situation où j'avais besoin d'une requête SELECT sur une table de partition pour ne pas prendre le verrou sch-s afin qu'une autre requête TRUNCATE sur une partition différente puisse continuer à fonctionner. Étonnamment, il s'avère que si j'exécute mon sélectionnez la requête par petits lots, le verrouillage sch-s est réduit à 99,99%. ce qui était parfait pour ma situation car Truncate avait juste besoin de quelques millisecondes pour se terminer. mais avec le SELECT complet sur toute la partition, le sch-s a été maintenu pendant toute la durée de select et donc TRUNCATE a été bloqué pendant toute la durée de select.

1
Anup Shah