Récupération de mémoire à partir de SQL Server

10

J'ai une instance SQL Server dont l'utilisation de la mémoire augmente progressivement jusqu'à ce que Windows ne lui en donne plus. Il semble logique que le résultat occasionnel d'une grande requête entraîne la croissance de l'instance.

Existe-t-il un moyen de convaincre SQL Server de libérer la mémoire dont il n'a plus besoin (autre que le redémarrage du service)?

Edit:
j'utilise SQL Server 2000 SQL Server 8.00.2039 - SP4 (Standard Edition)

J'ai pu le découvrir en utilisant la requête suivante:

SELECT 'SQL Server ' 
    + CAST(SERVERPROPERTY('productversion') AS VARCHAR) + ' - ' 
    + CAST(SERVERPROPERTY('productlevel') AS VARCHAR) + ' (' 
    + CAST(SERVERPROPERTY('edition') AS VARCHAR) + ')'
BIBD
la source

Réponses:

19

C'est exactement ainsi que SQL Server est censé fonctionner.

Si vous avez d'autres services sur cette machine et que vous ne voulez pas que SQL consomme toute la mémoire disponible, vous devrez définir la mémoire maximale du serveur. Voir Options de mémoire SQL Server sur MSDN.

Portman
la source
1
Cela ressemble plus à un bug qu'à une fonctionnalité ... ça m'arrive. SQL Server occupe 95% de la RAM disponible pour faire quelque chose et ne parvient pas à le libérer lorsqu'il est terminé.
Alchemical
1
@Alchemical Cela dépend de ce que vous entendez par " complet ". SQL Server peut utiliser toute la RAM d'un ordinateur; en l'utilisant comme cache disque. Il ne "se termine " pas en l'utilisant comme cache disque tant que vous n'avez pas utilisé SQL Server.
Ian Boyd
8

Les autres affiches sont correctes, c'est par conception, mais vous voulez absolument limiter la mémoire maximale à un peu moins que la RAM de votre serveur. Pensez à cette séquence d'événements:

  • SQL 2000 fonctionne correctement, consommant toute la RAM de votre serveur
  • Quelqu'un RDP, ou vous devez tirer IE pour télécharger un patch, ou vos sauvegardes démarrent, peu importe
  • SQL doit désallouer et libérer suffisamment de mémoire pour que le système d'exploitation fonctionne
  • Les performances sont nulles pendant la libération de la mémoire et de la pagination sur le disque
  • Les choses vont assez bien une fois qu'elles sont stables
  • L'autre opération se termine et SQL récupère progressivement la RAM libérée
  • Répéter

Pour éviter cela, configurez la limite de mémoire maximale de votre serveur à environ 80 à 90% de votre mémoire physique réelle. Instructions pour SQL 2000 à: http://msdn.microsoft.com/en-us/library/ms178067.aspx

sh-beta
la source
N'oubliez pas que ce comportement est 2005 et 2008 - 2000 ne libère pas de mémoire à la demande sur le système d'exploitation.
Paul Randal
2
Pas exactement à la demande, mais il libère de la mémoire sur le système d'exploitation. À partir du lien que j'ai publié: «Lorsque SQL Server utilise la mémoire de manière dynamique, il interroge le système périodiquement pour déterminer la quantité de mémoire physique libre. Sous Microsoft Windows 2000, SQL Server augmente ou réduit le cache de tampon pour garder la mémoire physique libre entre 4 Mo et 10 Mo selon l'activité du serveur. Le maintien de cette mémoire libre empêche la pagination de Windows 2000. S'il y a moins de mémoire libre, SQL Server libère de la mémoire pour Windows 2000. S'il y a plus de mémoire libre, SQL Server alloue de la mémoire au pool de mémoire tampon. "
sh-beta
Ah - c'est vrai - ça fait l'affaire de dégager un peu de mémoire physique - vous avez raison!
Paul Randal
4

Il ne le libérera que si le système d'exploitation signale qu'il est affamé de RAM, ou si vous arrêtez et redémarrez le service; la chose à faire est de limiter la quantité maximale que SQL utilisera en configurant la valeur de «mémoire maximale du serveur». S'il n'y a rien d'autre sur le serveur qui a besoin de RAM (et j'espère qu'il n'y en a pas), je ne m'en inquiéterais pas.

SqlACID
la source
4

Donc, pour résumer les réponses:

Il n'y a aucun moyen d'inviter MS SQL Server à libérer de la mémoire dont il n'a pas besoin immédiatement. SQL Server doit libérer automatiquement de la mémoire lorsque cela est nécessaire, mais pas avant. Et si vous rencontrez des problèmes de mémoire, vous devez réduire la valeur de l'option de mémoire "max server memory".

BIBD
la source
3

SQL Server consommera de la mémoire et ne la restituera pas, sauf si le système d'exploitation lui indique qu'il y a une pression mémoire. Comme Portman l'a indiqué, cela est voulu par la conception même du produit et si vous souhaitez limiter la consommation de mémoire, vous devez définir la mémoire maximale du serveur que SQL Server utilisera.

K. Brian Kelley
la source
2

N'oubliez pas que le comportement que vous décrivez tous est à partir de SQL Server 2005, lorsque le gestionnaire de mémoire a été réécrit pour (entre autres) répondre aux demandes de pression de mémoire du système d'exploitation.

Pour SQL Server 2000 et avant, une fois qu'il récupère de la mémoire, il ne la rendra pas, peu importe combien le système d'exploitation le crie.

CodeSlave - exécutez-vous sur 2000, 2005 ou 2008?

Paul Randal
la source
Ah ha ... oui en effet SQL 2000.
BIBD
3
Il ne le restitue pas lorsque le système d'exploitation le crie, mais il le restitue s'il constate que le système d'exploitation est en dessous d'un certain seuil de mémoire physique libre. Voir msdn.microsoft.com/en-us/library/ms178067.aspx
sh-beta
Et pour renforcer ce qu'a dit sh-beta, SQL Server 2000 ne libère de la mémoire que lorsqu'il constate que le système d'exploitation manque de mémoire physique, car ce n'est que sous Windows XP (2001) que Windows a ajouté une API pour permettre au système d'exploitation de crier pour it "( msdn.microsoft.com/en-us/library/aa366799(v=vs.85).aspx ). SQL Server 2005 tire parti de cette nouvelle fonctionnalité de Windows. Mais lorsque SQL Server 2000 a été écrit, il n'y avait aucun moyen pour le système d'exploitation de le crier, forçant SQL Server à vérifier périodiquement la pression de la mémoire.
Ian Boyd
0

Vieille question, je sais, mais un moyen de forcer (plus récent, au moins) SQL à libérer de la mémoire est d'écrire une application allouant autant de mémoire que possible en morceaux, en attendant (disons) 15 secondes (par exemple, Sleep (15000)) et la libération de la mémoire allouée et la fermeture; J'ai essayé cela et SQL libère la mémoire pour que le système récupère sa RAM; écrire du code comme ci-dessus est presque trivial en utilisant C / C ++, il suffit de mettre en place une chaîne de stucts pour contenir la chaîne de blocs de mémoire (pointeur et taille), réduire progressivement la taille lorsqu'un "malloc ()" échoue jusqu'à ce qu'il atteigne un minimum (disons moins de 1024) puis parcourez la liste chaînée pour libérer les blocs alloués

Un passant
la source