La latence du réseau accrue entraînera-t-elle des verrous de table dans MS SQL Server?

16

Si j'effectue un seul appel vers une base de données SQL Server sur un réseau à latence élevée, des verrous de table se produiront-ils en raison de cette latence? Supposons que j'interroge la table A pour certains enregistrements, et SQL Server doit renvoyer ces données sur un réseau lent - y aura-t-il un verrou de lecture sur la table A pendant que le serveur envoie la réponse sur le réseau, ou SQL Server libère-t-il le verrou avant d'envoyer la réponse?

De plus, la réponse varierait-elle en fonction de la taille de la réponse? S'il suffit de renvoyer quelques Ko contre plusieurs centaines de Mo, cela ferait-il une différence?

La création d'une transaction explicite, l'exécution de requêtes et la fermeture de la transaction entraîneraient évidemment le verrouillage des tables, car la durée de la transaction est corrélée avec ma latence.

Evan M
la source
Sauf si vous spécifiez un nolockindice, il y aura toujours un verrou . La latence détermine simplement la durée du verrouillage.
Brandon
3
Et même avec nolock, vous obtiendrez toujours des verrous
billinkc
@brandon Est-ce documenté par Microsoft quelque part? Mes recherches sont vides.
Evan M
1
@Brandon NOLOCK ne signifie pas ce que vous pensez que cela signifie.
Aaron Bertrand
3
@Brandon Unless you specify a nolock hint, there will always be a lock.<- cela implique que si vous utilisez nolock, il pourrait ne pas y avoir de verrous. Je clarifiais simplement.
Aaron Bertrand

Réponses:

15

Si le client met longtemps à recevoir des données et à son tour envoyer un accusé de réception à SQL Server qu'il a reçu les données que SQL Server doit attendre, en raison de cette attente, SQL Server ne libérera pas les verrous détenus par la requête à moins que l'accusé de réception ne soit reçu du client.

Ce n'est pas précis, cela dépend du niveau d'isolement.

Par défaut, les READ COMMITTEDverrous ne sont pas maintenus pendant la durée de l'exécution des instructions. READ COMMITTEDne fournit pas de cohérence de lecture au niveau de l'instruction, la seule garantie est que vous ne pouvez pas lire les données non validées. Un verrou partagé est acquis et maintenu pour lire la ligne, puis libéré.

Sauf si vous avez des types de LOB.

Les types de LOB, étant potentiellement très volumineux, ne peuvent pas être mis en mémoire tampon. Un verrou partagé doit être acquis et maintenu jusqu'à la fin de l'instruction, ce qui vous donne essentiellement un REPEATABLE READcomportement à READ COMMITTED.

Si j'effectue un seul appel vers une base de données MSSQL sur un réseau à latence élevée, des verrous de table se produiront-ils en raison de cette latence?

La latence ne provoque pas le verrouillage de la table, non. Cependant, si un verrou de table a été acquis, la latence va le prolonger.

Pour citer quelqu'un qui connaît mieux la mécanique que moi ( @RemusRusanu ):

Les résultats sont renvoyés au programme client au fur et à mesure de l'exécution. Lorsque les lignes «bouillonnent» dans l'arbre d'exécution, l'opérateur supérieur est généralement chargé d'écrire ces lignes dans des tampons réseau et de les renvoyer au client. Le résultat n'est pas créé d'abord dans un stockage intermédiaire (mémoire ou disque), puis renvoyé au client, il est renvoyé à la création (lors de l'exécution de la requête). Le renvoi du résultat au client est, bien entendu, soumis au protocole de contrôle de flux réseau. Si le client ne consomme pas activement le résultat (par exemple en appelant SqlDataReader.Read ()), le contrôle de flux devra finalement bloquer le côté d'envoi (la requête en cours d'exécution), ce qui suspendra à son tour l'exécution de la commande requete.[la source]

Lorsque les résultats ne sont pas consommés aussi rapidement que SQL Server peut les fournir, que ce soit à cause du client ou du réseau, nous voyons des ASYNC_NETWORK_IOattentes s'accumuler. Pour le répéter, cela n'influencera pas les verrous acquis, mais uniquement la durée de leur maintien.

Mark Storey-Smith
la source
9

La réponse de Mark a dissipé une grande partie de ma confusion, mais je voulais publier mes résultats après avoir testé cela en utilisant NetBalancer pour émuler la latence.

J'ai demandé à ma machine locale d'appeler un serveur SQL distant et d'exécuter les sélections et les insertions sur une table au sein d'une petite transaction. Sur la machine distante, je me suis connecté à l'instance SQL locale et j'ai utilisé une boucle WHILE pour répéter de manière répétée la table sys.dm_tran_locks, à la recherche de verrous sur la table que je modifiais et lisais. J'ai installé NetBalancer sur le serveur et l'ai utilisé pour émuler la latence du réseau sur la connexion réseau du serveur.

Voici ce que j'ai trouvé:

  • Pour les instructions qui ne renvoient pas beaucoup de données au client, la latence n'a aucun effet sur le verrouillage. Je ne retournais que quelques centaines d'octets de données au maximum. La transaction sur ma machine avait un WAITFOR de 250 ms qui gardait les verrous, et lorsque j'ai augmenté la latence du réseau à 5000 ms, la durée du verrouillage est restée proche de 250 ms.
  • Pour les instructions qui renvoient beaucoup de données, la latence affecte définitivement le verrouillage J'ai renvoyé des dizaines de milliers de lignes au client, et sans latence, la durée du verrouillage était courte. Lorsque j'ai augmenté la latence, les verrous ont continué jusqu'à ce que je reçoive toutes les données.

De cela, je conclus que la latence n'a pas d'importance tant que les données tiennent dans la mémoire tampon du réseau. Si SQL doit mettre beaucoup de données dans le tampon réseau, la latence entraînera la sauvegarde de ce tampon et SQL maintiendra les verrous de table jusqu'à ce qu'il puisse placer tous les résultats de la requête dans le tampon.

Evan M
la source
Des résultats intéressants. Avec quel programme / bibliothèque client s'agit-il?
James L
Bon produit. Y a-t-il une chance que vous puissiez passer un peu plus de temps à ce sujet et voir si vous pouvez déterminer la taille du résultat à laquelle cela se produit?
Mark Storey-Smith,
@ MarkStorey-Smith Je ne pense pas pouvoir obtenir une valeur précise, et cela varierait sans aucun doute selon la machine. Sur vircom.com/security/improve-sql-nic-performance , il semble que ce soit un paramètre sur votre carte réseau locale, et celui sur mon serveur de base de données a été défini sur «auto»
Evan M
@James Je viens d'utiliser SSMS sur les deux machines
Evan M
0

Si j'effectue un seul appel vers une base de données MSSQL sur un réseau à latence élevée, des verrous de table se produiront-ils en raison de cette latence?

Lorsqu'une requête est déclenchée et terminée par SQL Server, elle produit les résultats, la place dans le tampon de sortie et l'envoie au client qui récupère ensuite le résultat dans le tampon de sortie. SQL Server ne libérera pas les verrous détenus par la requête à moins que l'accusé de réception ne soit reçu du client. Ce qui pourrait provoquer un blocage.

Edit: Evan vous pouvez vous référer à cet article de support MS

Dans la section 3

Blocage provoqué par un SPID dont l'application cliente correspondante n'a pas récupéré toutes les lignes de résultats jusqu'à la fin

Après avoir envoyé une requête au serveur, toutes les applications doivent immédiatement récupérer toutes les lignes de résultat jusqu'à leur achèvement. Si une application ne récupère pas toutes les lignes de résultats, des verrous peuvent être laissés sur les tables, bloquant les autres utilisateurs. Si vous utilisez une application qui soumet de manière transparente des instructions SQL au serveur, l'application doit récupérer toutes les lignes de résultat. Si ce n'est pas le cas (et s'il ne peut pas être configuré pour le faire), vous ne pourrez peut-être pas résoudre le problème de blocage. Pour éviter le problème, vous pouvez restreindre les applications mal comportées à une base de données de génération de rapports ou d'aide à la décision.

Shanky
la source
Merci pour votre réponse Shanky! Savez-vous si cela est documenté quelque part?
Evan M
5
Ce n'est pas correct.
Mark Storey-Smith,
C'est correct, il semble que «l'application ne récupère pas toutes les lignes de résultat, des verrous peuvent être laissés sur les tables, bloquant les autres utilisateurs. Si vous utilisez une application qui soumet de manière transparente des instructions SQL au serveur, l'application doit récupérer toutes les lignes de résultat. Si ce n'est pas le cas (et s'il ne peut pas être configuré pour le faire), vous ne pourrez peut-être pas résoudre le problème de blocage. Pour éviter le problème, vous pouvez restreindre les applications mal comportées à une base de données de rapports ou d'aide à la décision. ' De plus, je parlais en termes généraux. Vous pouvez lire ici support2.microsoft.com/kb/224453
Shanky
4
@Shanky Créez une grande table. SELECT *à partir de celui-ci dans READ COMMITTEDune connexion SSMS, le moniteur se verrouille d'une autre. À tout moment, combien de verrous voyez-vous?
Mark Storey-Smith,