web-dev-qa-db-fra.com

Latch_ex attend la ressource MetaData_Efence_Generator

Nous avons un processus qui génère un rapport d'inventaire. Du côté du client, le processus se divise d'un nombre configurable de threads de travailleurs pour créer un morceau de données pour le rapport qui correspond à un magasin de plusieurs (potentiellement des milliers, des dizaines typiquement). Chaque fil de travail appelle un service Web qui exécute une procédure stockée.

Le processus de base de données de traitement de chaque morceau recueille un tas de données dans une table #Temporary. À la fin de chaque morceau de traitement, les données sont écrites sur une table permanente dans TEMPDB. Enfin, à la fin du processus, un fil du côté client demande toutes les données de la table permanente TEMPDB.

Plus il y a plus d'utilisateurs qui gèrent ce rapport, plus il est lent. J'ai analysé l'activité dans la base de données. À un moment donné, j'ai vu 35 demandes distinctes toutes bloquées à un moment donné dans le processus. Tous ces spids ont eu sur l'ordre de 50 ms attend de type LATCH_EX Sur la ressource METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8). Une SPID a cette ressource et tous les autres bloquent. Je n'ai rien trouvé sur cette ressource d'attente sur une recherche sur le Web.

La table dans TEMPDB que nous utilisons a une colonne IDENTITY(1,1). Ces spids attendent-ils la colonne d'identité? Quelles méthodes pourrions-nous utiliser pour réduire ou éliminer le blocage?

Le serveur fait partie d'un cluster. Le serveur exécute 64 bits SQL Server 2012 Standard Standard SP1 sur Windows 2008 R2 Enterprise 64 bits. Le serveur a 64 gb RAM et 48 processeurs, mais la base de données ne peut qu'utiliser 16 car il s'agit de l'édition standard.

(Notez que je ne suis pas ravi de la conception d'utiliser une table permanente dans TEMPDB pour contenir toutes ces données. Changer ce serait un défi technique et politique intéressant, mais je suis ouvert aux suggestions.)

Mise à jour 4/23/201

Nous avons ouvert un cas de support avec Microsoft. Je tiendrai cette question à jour comme nous en apprenons plus.

Mise à jour 5/10/201

L'ingénieur de support SQL Server a convenu que les attentes ont été causées par la colonne d'identité. Supprimer l'identité éliminé les attentes. Nous ne pouvions pas dupliquer la question sur SQL 2008 R2; Cela ne s'est produit que sur SQL 2012.

11
Paul Williams

En supposant que vous puissiez isoler le problème à la génération de valeurs d'identité (essayez de supprimer cette colonne comme test), ce que je recommanderais est-ce:

  1. Supprimer la propriété IDENTITY de la colonne de la table finale.
  2. Générez des valeurs d'identité dans chacune des tables #Temporary.
  3. Lors du chargement de la table finale, combinez un identifiant numérique pour le magasin particulier avec les valeurs d'identité à partir de l'étape 2.

Donc, si vous avez des identifiants de stockage 3 et 4, vous vous retrouveriez avec des valeurs d'identification finales comme celle-ci:

3000000001
3000000002
3000000003
...
4000000001
4000000002
...

Ou quelque chose de similaire à celui-là. Vous avez eu l'idée.

Cela éliminera la nécessité de sérialiser sur IDENTITY génération tout en préservant l'unicité dans le résultat final.

Selon la manière dont le processus fonctionne, insérez les valeurs d'identification calculées finales dans les tables #Temporary. Ensuite, vous pouvez créer une vue que UNION ALLs les ensemble, éliminant la nécessité de copier les données du tout.

4
Jon Seigel

(Mise à jour février 2019)

C'est un ancien poste qui a dit que j'ai finalement réussi à convaincre Microsoft que ce fait que cela se produit est effectivement un défaut.

-(( Mise à jour: MS a confirmé le défaut et l'a attribué un numéro de bogue de 12628722.

J'avais vu ce poste au cours du dernier novembre 2018 lorsque nous avons commencé à souffrir de la même chose après notre mise à niveau de SQL Server 2005 à SQL Server 2017. Une table de 3,3 millions de lignes qui prenait 10 secondes à l'insert en vrac a soudainement commencé à prendre 10 minutes sur des tables avec Identity colonnes.

S'avère qu'il y a deux problèmes derrière cela:

  1. Microsoft a modifié le comportement dans SQL Server 2014 pour forcer les inserts en vrac à exécuter parallèle - dans les versions antérieures des insertions en vrac ont reçu un plan sérialisé.
  2. Une fois en parallèle parallèlement sur notre boîte de 32 noyau, le moteur a passé plus de temps avec les noyaux se verrouillant que de faire le travail.

Cela m'a pris 4 semaines, mais juste après les vacances, j'ai eu un cadeau tardif de Santa - Confirmation selon laquelle la question était en effet un défaut.

Il y a quelques solutions de contournement possibles que nous avons trouvées jusqu'à ce que cela soit corrigé:

  1. Utilisez Option (MaxDop 1) dans la requête pour revenir à l'insertion en vrac dans un plan sérialisé.
  2. Masquer la colonne d'identité en la coulant (par exemple Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn)
    • cela empêche la copie de la propriété d'identité lors de l'utilisation de SELECT...INTO
  3. Supprimez la colonne d'identité comme décrit ci-dessus.
  4. Modifiez le mode de compatibilité de la base de données sur SQL Server 2012 ou plus bas pour rétablir un plan sérialisé.

(( mise à jour: La MS Fix sera mise en œuvre pour renvoyer ces sortes d'insertions Retour à l'aide d'un Serialized Plan. Ceci est prévu pour SQL Server 2017 CU14 (aucune nouvelle sur d'autres versions de SQL Server - Désolé!). Lors de la mise en œuvre, le drapeau de trace 9492 devra être activé, soit au niveau du serveur, soit via DBCC TraceOn.

7
Rachel Ambler