Hier, ma base de données SQL Server allait bien. Aujourd'hui, il est presque inutilisable - il est ralenti d'un facteur compris entre cinq et vingt, selon le moment où je l'ai frappé.
Certaines données ont été ajoutées au serveur lors d'un processus de chargement de nuit, mais rien de tel qu'un volume qui devrait avoir un impact important sur une base de données. Environ 50 000 enregistrements en texte brut (pas de XML ou autre frippery).
Le serveur a été corrigé ce matin avant de le redémarrer. Cependant, aucun de nos autres serveurs de base de données qui ont également été corrigés ne se comporte différemment.
Le moniteur de ressources semble suggérer que son E / S de disque est en cause. Il fonctionne à près de 100% de sa capacité sur le fichier .mdf tout le temps, même lorsqu'il ne se passe pas grand-chose dans la base de données. L'accès à Templog.ldf est également assez élevé.
Personne ici n'est un expert DBA (nous sommes tous des développeurs avec une quantité variable de compétences SQL) et nous sommes tous déconcertés par ce qui s'est passé. Nous avons essayé d'exécuter sp_updatestats et de déplacer certains des gros index vers différents disques, en vain.
Je pense que cela doit avoir quelque chose à voir avec le patch - il semble trop d'une co-incidence. Un collègue est convaincu que c'est la charge de données qui a provoqué l'augmentation de la taille du mdf à un point tel que les plans d'exécution sont devenus inefficaces.
Qu'est-ce qui a causé ça? Comment pouvons-nous le savoir et que pouvons-nous faire pour y remédier?
ÉDITER:
L'utilisation sp_WhoIsActive
ne révèle rien d'extraordinaire. Il enregistre ma propre utilisation du sproc et de certaines commandes d'un collègue qui essaie actuellement de déplacer un autre index. Cela retarde probablement la DB en ce moment, mais elle fonctionnait tout aussi mal auparavant.
Il s'agit de la version standard de SQL Server 2008 R2. SELECT @@VERSION
donne:
Microsoft SQL Server 2008 R2 (SP2) - 10.50.4033.0 (X64)
9 juillet 2014 16:04:25
Copyright (c) Microsoft Corporation Standard Edition (64 bits) sur Windows NT 6.1 (Build 7601: Service Pack 1) (Hyperviseur )
Le serveur dispose de 72 Go de RAM et de trois processeurs quad-core 2 GHz.
Le patch n'a été appliqué qu'à Windows. Il n'y a eu aucun changement autre que le patch.
Paramètres sélectionnés:
_id name value minimum maximum value_in_use description is_dynamic is_advanced
1540 min memory per query (KB) 1024 512 2147483647 1024 minimum memory per query (kBytes) 1 1
1541 query wait (s) -1 -1 2147483647 -1 maximum time to wait for query memory (s) 1 1
1543 min server memory (MB) 0 0 2147483647 16 Minimum size of server memory (MB) 1 1
1544 max server memory (MB) 65536 16 2147483647 65536 Maximum size of server memory (MB) 1 1
MISE À JOUR: Le déplacement des index et des tables vers différentes partitions de disque semble améliorer les choses. Je suis toujours confus sur la façon dont nous aurions pu atteindre un point de basculement si soudainement avec des résultats aussi drastiques.
la source
SELECT * FROM sys.configurations;
- vous voulezvalue, value_in_use
pour des choses commemax server memory (MB)
. Le numéro de build dansSELECT @@VERSION;
serait également utile, ainsi que s'il s'agit d'un hyperviseur et si quelque chose a changé sur l'hôte depuis hier (ou depuis le dernier redémarrage de SQL Server).Réponses:
Il peut arriver qu'une petite quantité de données atteigne une certaine limite dans SQL Server pour forcer un autre plan ou quelque chose comme ça. Ce n'est pas improbable. Mais le fait que votre disque semble être lourdement contraint m'amène à une autre conclusion.
Il y a 2 raisons possibles à votre ralentissement.
Jetons un coup d'œil à la partie n ° 1
Il se peut que votre configuration SQL Server soit rompue. Cela peut entraîner de graves problèmes concernant la vitesse de votre serveur et l'utilisation du disque.
Veuillez vérifier en premier lieu les paramètres de base de votre serveur. Ces réglages de base sont
max server memory
,affinity I/O mask
,affinity mask
etmax degree of parallelism
. Vous devrez peut-être activer les options avancées à l'aide deshow advanced options
.Voici un script complet:
Comparez le résultat avec vos valeurs documentées dans vos étapes d'installation. Sont-ils toujours les mêmes?
Il peut y avoir plusieurs raisons pour lesquelles votre serveur se comporte si étrangement. Je parierais normalement que vous vous
max server memory
trompez. Cela entraînera l'échange de pages de données de votre serveur SQL en permanence. Il ne peut pas tout garder en mémoire. Cela signifie qu'il doit lire les pages du disque, le mettre à jour, le réécrire instantanément. Si une autre mise à jour arrive et utilise la même page pour une mise à jour, elle ne peut pas être lue dans la mémoire. Au lieu de cela, le serveur doit le relire à partir du disque. Échange juste ...Un autre problème peut être lié à une affinité élevée sur le disque ou les processus. Si vous avez utilisé un serveur partagé (SQL Server + autres services) avec un disque dédié pour SQL Server (ce qui peut être un cas rare, mais cela pourrait l'être), cela pourrait être votre problème. Votre serveur avait normalement par exemple 3 processeurs pour les processus et un pour les E / S. Les 12 autres CPU sont utilisés pour d'autres services. Dans ce cas, votre masque d'affinité est incorrect et utilise par exemple une configuration automatique. Cela signifie que votre serveur utilise les 16 cœurs pour les processus et les E / S de manière dynamique. Si vous avez d'énormes processus en cours d'exécution, ils peuvent mettre une énorme charge sur le disque, qu'il ne peut pas gérer. Mais en fait, je ne pense pas que ce soit votre cas. Ce serait plus rapide (même si c'est juste un peu) si cela s'appliquait, mais votre cas est un ralentissement.
Un autre problème peut être un degré de parallélisme trop élevé. Ce qui signifie que vous avez trop de threads au ralenti sur une partie d'une requête. Cela pourrait également provoquer un énorme ralentissement si le parallélisme ne fonctionne pas comme prévu. Mais cela ne décrira pas votre total d'E / S élevées.
Jetons maintenant un œil à la partie n ° 2 également
Vous chargez un tas de lignes dans votre système. Même s'il s'agit d'un travail normal, cela pourrait augmenter la limite dans laquelle vos plans de requête s'intensifient. Il se peut même que votre insertion en combinaison avec SQL Server produise ce comportement.
Vous avez mentionné que vous avez déjà essayé de migrer vos index vers un autre disque, ce qui semble vous aider. Cela peut être dû au fait que vous divisez la charge sur deux disques différents.
Il se peut que vos indices aient été fracturés, que vos plans aient été fracturés ou que vos statistiques soient juste dépassées.
1. permet de vérifier les dernières mises à jour des statistiques Vous pouvez le faire manuellement via l'interface pour chaque élément statistique unique. Ce serait une douleur. Ou vous pouvez essayer ce code:
Cela vous donnera une information complète sur chaque index (et tas) et les statistiques derrière eux. Même si vous l'exécutez,
sp_updatestats
cela ne signifie pas que les statistiques ont été mises à jour. La partie lorsqu'une mise à jour est assez délicate, même si vous exécutezsp_updatestats
ou même si elleauto update statistics
est activée, les statistiques ne seront pas mises à jour juste à temps. Voici quelques points marginaux, lorsqu'une mise à jour est nécessaire / générée:Cela signifie que vos statistiques peuvent être obsolètes même si vous exécutez la mise à jour.
Vous pouvez jeter un œil à la requête ci-dessus. Si vous trouvez des statistiques assez anciennes dans certains tableaux, vous souhaiterez peut-être exécuter une mise à jour manuelle des statistiques pour ce tableau:
Après cela, vous voudrez peut-être donner un coup de pied à votre serveur pour jeter tous les anciens plans.
Si vous souhaitez simplement nettoyer tous les caches, vous pouvez exécuter ceci à la place:
Cela nettoiera tous les caches, pas seulement le cache du plan. Je préviens normalement, d'utiliser ceci sur un serveur de production en phase de production. Mais comme votre serveur ne fonctionne pas actuellement, vous ne pouvez pas trop leur faire de mal. Cela peut ralentir pendant quelques secondes, peut-être 1-2 minutes, car il doit reconstruire tous les caches, mais après cela, il devrait exécuter les bons plans.
Une autre raison peut être les indices totalement fragmentés. Cela peut être vérifié sur l'ensemble du serveur à l'aide de cette instruction:
Si la fragmentation est très élevée, vous devrez peut-être la réorganiser (fragmentation <20%) ou la reconstruire totalement (> 20%). Cela peut augmenter la pression sur votre disque et provoquer des problèmes. D'un autre côté, si les indices sont si mauvais, cela aiderait probablement à la fin plus qu'il ne nuit.
Outre ces deux raisons, il peut encore y avoir un troisième problème
Il se peut que votre serveur soit configuré probablement, vous n'avez changé aucun code dans ce temps, juste ajouté quelques lignes. Toutes les statistiques sont mises à jour et tous les caches sont reconstruits. Tous vos indices sont réorganisés comme vous en avez besoin, mais toujours - rien ne fonctionne. Il se peut que vous ayez atteint la limite de mémoire disponible dans vos processus. Vous en avez peut-être besoin de plus. Vous pouvez simplement vérifier s'il existe un processus qui tente d'obtenir plus de mémoire que vous n'en avez.
Vous pouvez vérifier cela en utilisant cette commande:
Il vous fournira une liste de toutes les sessions qui consomment de la mémoire. Il peut y avoir une requête qui attend toujours d’obtenir de la mémoire. Ces requêtes peuvent être facilement filtrées. Toutes les sessions où
granted_memory_kb IS NULL
. Ce sont des sessions qui demandaient de la mémoire mais ne l'obtiennent pas. Une autre chose peut être une mémoire accordée qui peut être trop faible. Vous pouvez comparer les colonnesrequested_memory_kb
avecgranted_memory_kb
. Required indique la quantité de mémoire dont le processus a besoin pour fonctionner de manière optimale, tandis que grant affiche la mémoire qui est activée pour le processus. Si un processus a besoin de 2 Go pour s'exécuter mais n'obtient que 2 Mo ... vous pouvez l'obtenir par vous-même. ;-)Une autre façon consiste à vérifier
RESSOURCE_SEMAPHORE
:Vous pouvez jeter un œil aux
waiter_count
etgrantee_count
. Si le serveur est au-dessus de 0, vous avez une pression sur votre mémoire, ce qui peut provoquer un échange et provoquer la pression du disque que vous voyez dans le perfmon.la source
En plus des pannes de disque possibles, vérifiez l'état de votre sous-système RAID. Nous avons vu quelque chose de similaire et il s'est avéré que la batterie du contrôleur RAID était en panne, il n'y avait donc pas de cache d'écriture disponible - toutes les écritures devaient aller directement sur le disque. Une note latérale - nous pouvions sentir le système s'arrêter pendant que le RDC y pénétrait.
la source