MS SQL Server ralentit avec le temps?


8

Avez-vous vécu l'un des problèmes suivants et avez-vous trouvé une solution:

Une grande partie du back-end de notre site Web est MS SQL Server 2005. Chaque semaine ou deux semaines, le site commence à fonctionner plus lentement - et je vois des requêtes de plus en plus longues à terminer en SQL. J'ai une requête que j'aime utiliser:

USE master
select text,wait_time,blocking_session_id AS "Block",
percent_complete, * from sys.dm_exec_requests 
CROSS APPLY sys.dm_exec_sql_text(sql_handle)  AS s2 order by start_time asc

Ce qui est assez utile ... il donne un instantané de tout ce qui fonctionne à ce moment précis sur votre serveur SQL. Ce qui est bien, c'est que même si votre processeur est fixé à 100% pour une raison quelconque et que le moniteur d'activité refuse de se charger (je suis sûr que certains d'entre vous y ont été), cette requête revient toujours et vous pouvez voir quelle requête tue votre base de données.

Lorsque j'exécute ceci, ou le moniteur d'activité pendant les périodes où SQL a commencé à ralentir, je ne vois aucune requête spécifique à l'origine du problème - elles s'exécutent toutes plus lentement sur toute la ligne. Si je redémarre le service MS SQL, tout va bien, il accélère - pendant une semaine ou deux jusqu'à ce que cela se reproduise.

Rien à quoi je peux penser n'a changé, mais cela vient de commencer il y a quelques mois ... Des idées?

--Ajoutée

Veuillez noter que lorsque ce ralentissement de la base de données se produit, peu importe si nous obtenons 100 000 pages vues par heure (heure la plus occupée) ou 10 000 pages vues par heure (temps lent), toutes les requêtes prennent plus de temps que d'habitude. Le serveur n'est pas vraiment stressé - le CPU n'est pas élevé, l'utilisation du disque ne semble pas être hors de contrôle ... cela ressemble à une fragmentation d'index ou quelque chose du genre, mais cela ne semble pas être le Cas.

En ce qui concerne le collage des résultats de la requête que j'ai collée ci-dessus, je ne peux vraiment pas le faire. La requête ci-dessus répertorie la connexion de l'utilisateur effectuant la tâche, l'intégralité de la requête, etc., et je ne voudrais vraiment pas distribuer les noms de mes bases de données, tables, colonnes et les connexions en ligne:) ... I peut vous dire que les requêtes en cours d'exécution à ce moment-là sont des requêtes normales et standard pour notre site qui s'exécutent tout le temps, rien hors de la norme.

- 24 mars

Cela fait environ deux semaines depuis le dernier redémarrage. J'ai apporté plusieurs modifications: j'ai trouvé quelques requêtes où nous faisions un usage intensif de tables temporaires qui étaient totalement inutiles et ont demandé à nos développeurs de changer la façon dont ils le faisaient. J'ai ajusté la taille de certaines des bases de données en croissance constante (lente mais sûre) à une taille intelligente pour leur croissance. J'ai également ajusté les paramètres de croissance automatique pour tout pour être plus intelligent (ils étaient tous définis sur une croissance de 1 Mo). Enfin, j'ai un peu nettoyé MSDB. Nous faisons des expéditions de journaux et nous n'avions vraiment pas besoin de conserver des années et des années de points de sauvegarde, j'ai écrit quelques scripts qui ne limitent cela qu'à quelques mois. Je continuerai à mettre à jour ce fil, car il est trop tôt pour dire si le problème est encore résolu.


Si vous exécutez les mêmes requêtes via Management Studio, voyez-vous les mêmes problèmes de performances que s'ils étaient exécutés via l'application? Qu'est-ce qui fait que la dégradation des performances s'arrête ou disparaît? Redémarrez-vous le serveur? S'agit-il d'un serveur physique ou d'une machine virtuelle? A-t-il son propre stockage ou fait-il partie d'un SAN?
DCNYAM

Network Attached Storage, un MD 3000 pour être exact. Le redémarrage du service SQL le fait disparaître. Oui, vous voyez les mêmes temps de réponse plus lents du studio pendant ce temps.
Dave Holland

Réponses:


3

Nous l'avons trouvé. Il s'est avéré que c'était en fait un serveur Web qui avait un problème avec l'un de ses pools d'applications. Il resterait bloqué en exécutant le même ensemble de requêtes encore et encore (ce qui arrivait dans les tables temporaires). Cela ferait juste une boucle et une boucle et finirait par rendre le serveur SQL triste. Une fois que ce pool de machines / applications incriminé a été trouvé et «déposé», tout a été résolu.


2

Vous devez vous demander, que se passe-t-il lors d'un redémarrage du service SQL? Beaucoup de choses, mais deux points pertinents me viennent à l'esprit:

1) La mémoire SQL est libérée.

Il est possible (pas sûr de la probabilité) que si votre paramètre MaxMemory est trop élevé, que le service SQL se développe pour utiliser toute la mémoire disponible et que Windows commence à échanger des éléments importants vers le fichier d'échange. Vérifiez que MaxMemory est défini sur une valeur raisonnable, laissant suffisamment de mémoire supplémentaire pour tout ce qui doit être exécuté sur cette boîte (s'agit-il d'un serveur SQL dédié? Ou s'agit-il également du serveur d'application?)

2) TempDB est reconstruit à partir des tailles par défaut.

Vérifiez vos tailles de fichier tempdb par défaut, en particulier la taille par défaut et l'intervalle de croissance du fichier journal TempDB. Si l'intervalle de croissance est trop faible, le journal peut créer une incroyable fragmentation interne, ce qui peut considérablement ralentir l'utilisation normale. Voir ces deux excellents articles de blog de Kimberly Tripp.


1) La machine est un serveur SQL dédié avec 16 Go de mémoire, avec 14 Go alloués à SQL. 2) Je n'ai pas eu à redémarrer depuis que j'ai ajusté la taille et la croissance de la base de données. La table de température a été incluse dans les ajustements que j'ai faits, il est donc possible qu'elle ait eu un certain impact. Cela ne fait que quelques semaines que j'attends de voir si la situation se reproduira.
Dave Holland

1

Faites-vous un usage intensif de tables ou de curseurs temporaires? Vérifiez que tous les curseurs sont fermés et désalloués correctement. Faites également attention aux serveurs liés - nous devons utiliser un pilote de bug pour un ancien serveur Informix lié et cela signifie périodiquement que nous devons redémarrer le serveur.


Nous utilisons pas mal d'appels de tables temporaires, curseurs, j'espère que nous n'utilisons pas trop souvent, mais je suppose qu'il est possible de connaître certaines de nos "normes" de codage plus anciennes, je vais donc examiner cela. Nous n'utilisons cependant qu'un seul serveur lié, et son à une autre DB 2005 sql.
Dave Holland

0

Si ça a l'air bizarre, cherchez le bizarre.

Si l'ajustement des paramètres du serveur SQL n'aide pas à essayer le gestionnaire de tâches Windows: allez dans l'onglet Processus, puis Options> Colonnes> Ajouter le temps CPU, les poignées, la lecture, l'écriture, d'autres et les options de mémoire.

Revenez à la liste des processus. Pour chaque colonne, triez par ordre décroissant et examinez les 5 premiers processus. Quelque chose qui sort de l'ordinaire? Par exemple, une fuite de mémoire sur un processus aura un nombre bizarre de poignées. Nous avons des imprimantes * ki qui ajoutent une poignée au processus DCSLoader toutes les 2 secondes. Après quelques semaines, une machine répertorie beaucoup de mémoire libre et de CPU, mais un processus avec 100 000 poignées et déplace à peine le pointeur de la souris.

Vérifiez également votre liste de tâches planifiées. Dites à votre AV de ne pas numériser les fichiers .mdf.


Oui, j'ai fait tout cela, rien dans les listes de processus ne sort de l'ordinaire, et comme je l'ai dit, je ne redémarre pas la machine .. redémarrez uniquement le service SQL et le problème est résolu, il est donc peu probable que je parte pour rechercher le problème en dehors des processus SQL Server. Regarder les poignées est une bonne idée, je vérifierai cela la prochaine fois.
Dave Holland

0

Dave,

Avez-vous vérifié les statistiques d'attente? la requête que vous avez donnée ci-dessus répertorie la colonne "last_wait_type". cette colonne peut avoir quelques détails concernant ce que les requêtes attendent (réseau, cpu, etc.)


Je ne l'ai pas fait, mais je devrais. Je vérifierai que la prochaine fois que cela se produira.
Dave Holland

0

Si votre «modèle de récupération» de sauvegarde est PLEIN, la prise de sauvegarde de la base de données puis la sauvegarde des journaux de transactions améliorent-elles les choses? Sur un système qui manque d'espace disque, ce genre de chose pourrait expliquer le problème.


Toutes les bases de données sont enregistrées et expédiées toutes les 15 minutes - ce qui signifie que les journaux de base de données et de trans sont sauvegardés en permanence, donc ce n'est pas le problème .... ils fonctionnent également tous sur un md3K avec environ un téraoctet d'espace libre.
Dave Holland

bon à savoir. en utilisant quelle méthode vos clients SQL se connectent-ils au serveur SQL? encore, beaucoup de questions. Le serveur est-il 64 bits?
djangofan

Les clients sont des sites Web .net (toolbox.com) et oui 64 bits.
Dave Holland

alors, vos clients .net utilisent-ils le pilote jdbc2.x et utilisent-ils ou non l'authentification intégrée?
djangofan

0

Je semble avoir une configuration très similaire à la vôtre (16 Go, mise à niveau vers 32 Go et MD1000 avec un téraoctet de disques, double quadcore xeon).

La seule chose qui m'a aidé à diagnostiquer des problèmes bizarres comme celui-là dans le passé est beta_lockinfo par Erland Sommarskog. Exécutez-le lorsque le temps est lent et comparez.

J'ai également eu énormément de problèmes avec SQL 2005 avant SP2, mais SP3 est vraiment stable.


En fait, je me souviens juste. Essayez d'utiliser "Verrouiller les pages en mémoire". Avec CU4 pour SP3, même SQL 2005 Standard peut l'utiliser. Voir blogs.msdn.com/suhde/archive/2009/05/20/…
Ricardo Pardini

0

J'espère que cela donne des informations plus utiles:

SELECT  D.text SQLStatement,
        A.Session_ID SPID,
        C.BlkBy,
        ISNULL(B.status, A.status) Status,
        A.login_name Login,
        A.host_name HostName,
        DB_NAME(B.Database_ID) DBName,
        B.command,
        ISNULL(B.cpu_time, A.cpu_time) CPUTime,
        ISNULL((B.reads + B.writes), (A.reads + A.writes)) DiskIO,
        A.last_request_start_time LastBatch,
        A.program_name
FROM    sys.dm_exec_sessions A
        LEFT JOIN sys.dm_exec_requests B
        ON A.session_id = B.session_id
        LEFT JOIN (
                   SELECT   A.request_session_id SPID,
                            B.blocking_session_id BlkBy
                   FROM     sys.dm_tran_locks AS A
                            INNER JOIN sys.dm_os_waiting_tasks AS B
                            ON A.lock_owner_address = B.resource_address
                  ) C
        ON A.Session_ID = C.SPID
        OUTER APPLY sys.dm_exec_sql_text(sql_handle) D
WHERE   DB_NAME(B.Database_ID) = 'YourDBName' -- Comment out line for all db's
ORDER BY ISNULL(B.cpu_time, A.cpu_time) + ISNULL((B.reads + B.writes), (A.reads + A.writes)) DESC

Assurez-vous que db est d'accord avec:

DBCC CHECKDB -- Checks the allocation and structural integrity of all the objects in the specified database.
DBCC UPDATEUSAGE (bybox) -- Reports and corrects pages and row count inaccuracies in the catalog views

Gardez un œil sur l'espace journal avec:

DBCC SQLPERF(LOGSPACE)

Si vous voyez une expansion en cours, cela ralentira définitivement les choses. Si vous exécutez cela, vous verrez votre espace journal de plus en plus proche de 100%, puis le journal augmentera et le pourcentage diminuera à mesure qu'il aura de l'espace. J'espère que vous ne pourrez jamais le voir se développer avant que votre sauvegarde ne démarre et n'efface le journal.


Lorsque j'exécute la première requête, je n'obtiens aucun résultat - principalement parce qu'il n'y a vraiment pas de sessions de blocage qui se produisent pendant ces temps lents ... c'est juste que les requêtes s'exécutent toutes plus lentement en général. J'ai parcouru tous les contrôles DBCC et les mises à jour et ils avaient l'air bien. En ce qui concerne DBCC SQLPERF (LOGSPACE), la seule base de données qui soit même proche de 100% (à 75%) est un modèle et il ne change jamais de manière significative, les sauvegardes de livraison de journaux prennent soin de la taille du journal.
Dave Holland

-1

Configuration principalement idiote. Arrive.

  • Tout d'abord, vous devez en fait exécuter régulièrement la défragmentation d'index lors d'une maintenance. Planifiez-le en tant qu'activité, juste avant ou après avoir effectué des sauvegardes.

  • Deuxièmement, ne développez pas automatiquement votre base de données et surtout ne la rétrécissez pas automatiquement. Selon la charge, la croissance automatique / rétrécissement automatique sont essentiellement des paramètres de suicide.

Pas vu un ralentissement de SQL Server comme ça à peu près jamais. Pouvez-vous publier les résultats de cette requête en période de stress intense? Bien sûr, rien ne vous empêche de surcharger SQL Server à ce moment-là?


À votre premier point: nous avons des travaux de maintenance hebdomadaires (et certains quotidiennement selon les tables) qui indexent la défragmentation et mettent à jour les statistiques. Si vous retirez des informations dans les index, même lorsqu'ils sont lents, ils sont fragmentés à moins de 2 à 3%. Pour votre deuxième point: nous ne rétrécissons pas automatiquement - à coup sûr. Ces bases de données contiennent des informations sur les utilisateurs / le contenu du site, etc. qui augmente constamment (pas d'une tonne ... ce ne sont pas d'énormes bases de données), mais si je ne les laisse pas se développer automatiquement, comment sont-elles censées être suffisamment grandes? Je vais ajouter quelques détails à la fin de mon message pour répondre au dernier de vos propos.
Dave Holland

3
La croissance automatique n'est pas vraiment une mauvaise chose. S'appuyer sur elle est, mais l'avoir activée est beaucoup mieux que toutes les modifications apportées à votre base de données étant arrêtées car elles sont à la taille maximale.
Sean Howat

2
La croissance en pourcentage n'est généralement pas une bonne chose non plus. Lorsque votre base de données devient volumineuse, une croissance de 5% sera beaucoup plus importante qu'au début de la base de données. 1 Mo est trop petit, mais vous devez décider d'un taux de croissance de Mo fixe en fonction de la taille et de l'utilisation de votre base de données.
DCNYAM

1
La croissance automatique est mauvaise car elle regroupe le fichier avec un journal de petits incréments. A beaucoup d'implications négatives. support.microsoft.com/kb/315512 Plutôt: définissez les fichiers à une taille appropriée, puis exécutez des vérifications régulières avec un rapport de remplissage. Assurez-vous qu'ils ne prolifèrent pas. 1 Mo pourrait être le coupable possible, au fait ... s'il doit s'arrêter / croître / s'arrêter / croître pendant la maintenance, vous ne voulez pas connaître les performances.
TomTom

1
La croissance automatique est inoffensive à condition qu'elle se produise rarement. Quand ça devient mauvais, c'est quand il est utilisé comme substitut pour un bon dimensionnement, ce que je pense que TomTom signifie vraiment . Sinon, utilisez-le par tous les moyens.
Maximus Minimus
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.