Recuperando memoria de SQL Server

10

Tengo una instancia de SQL Server cuyo uso de memoria crece gradualmente hasta que Windows ya no le dé más. Parece lógico que el resultado de consultas grandes ocasionales haga que la instancia crezca.

¿Hay alguna manera de convencer a SQL Server para que libere la memoria que ya no necesita (aparte de reiniciar el servicio)?

Editar:
estoy usando SQL Server 2000 SQL Server 8.00.2039 - SP4 (Standard Edition)

Pude averiguarlo usando la siguiente consulta:

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

Respuestas:

19

Así es exactamente como se supone que funciona SQL Server .

Si tiene otros servicios en esa máquina y no desea que SQL consuma toda la memoria disponible, deberá configurar la memoria máxima del servidor. Consulte las Opciones de memoria de SQL Server en MSDN.

Portman
fuente
1
Suena más como un error que como una característica ... me está sucediendo a mí. SQL Server ocupa el 95% de la RAM disponible para hacer algo, y no puede liberarlo cuando está completo.
Alchemical
1
@Alchemical Depende de lo que quieras decir con " completo ". SQL Server puede hacer uso de toda la RAM en una computadora; usándolo como caché de disco. No se " completa " usándolo como caché de disco hasta que haya terminado de usar SQL Server.
Ian Boyd
8

Los otros carteles están en lo cierto al decir que esto es así por diseño, pero desea limitar la memoria máxima a un poco menos que la RAM de su servidor. Piensa en esta secuencia de eventos:

  • SQL 2000 se ejecuta correctamente, consumiendo toda la RAM de su servidor
  • Alguien ingresó RDP, o tiene que abrir IE para descargar un parche, o sus copias de seguridad comienzan, lo que sea
  • SQL tiene que desasignar y liberar suficiente memoria para que el sistema operativo funcione
  • El rendimiento apesta mientras libera memoria y paginación al disco
  • Las cosas van bien una vez que es estable
  • La otra operación se completa y SQL recupera gradualmente la RAM liberada
  • Repetir

Para evitar esto, configure el límite máximo de memoria del servidor en algo alrededor del 80-90% de su memoria física real. Instrucciones para SQL 2000 en: http://msdn.microsoft.com/en-us/library/ms178067.aspx

sh-beta
fuente
Recuerde que este comportamiento es 2005 y 2008 - 2000 no libera memoria bajo demanda al sistema operativo.
Paul Randal
2
No exactamente a pedido, pero libera memoria al sistema operativo. Desde el enlace que publiqué: "Cuando SQL Server está usando la memoria dinámicamente, consulta periódicamente el sistema para determinar la cantidad de memoria física libre. En Microsoft Windows 2000, SQL Server aumenta o reduce el caché del búfer para mantener la memoria física libre entre 4 MB y 10 MB dependiendo de la actividad del servidor. Mantener esta memoria libre evita que Windows 2000 pagine. Si hay menos memoria libre, SQL Server libera memoria a Windows 2000. Si hay más memoria libre, SQL Server asigna memoria al grupo de búferes ".
sh-beta
Ah, es cierto, hace el truco de liberar un poco de memoria física, ¡tienes razón!
Paul Randal
4

Solo lo liberará si el sistema operativo indica que no tiene RAM o si detiene y reinicia el servicio; lo que hay que hacer es limitar la cantidad máxima que SQL usará configurando el valor de "memoria máxima del servidor". Si no hay nada más en el servidor que necesite la RAM (y espero que no), no me preocuparía.

SqlACID
fuente
4

Entonces, para resumir las respuestas:

No hay forma de solicitar a MS SQL Server que libere memoria que no necesita de inmediato. SQL Server debería liberar automáticamente la memoria cuando sea necesario, pero no antes. Y si tiene problemas de memoria, debe reducir el valor de la opción de memoria "memoria máxima del servidor".

BIBD
fuente
3

SQL Server consumirá memoria y no la devolverá a menos que el sistema operativo le indique que hay presión de memoria. Como Portman ha indicado, esto es por diseño, y si desea limitar el consumo de memoria, debe establecer la memoria máxima del servidor que utilizará SQL Server.

K. Brian Kelley
fuente
2

Recuerde que el comportamiento que está describiendo es a partir de SQL Server 2005 en adelante, cuando el administrador de memoria fue reescrito para (entre otras cosas) responder a las solicitudes de presión de memoria del sistema operativo.

Para SQL Server 2000 y versiones anteriores, una vez que toma la memoria, no la devolverá, sin importar cuánto grite el sistema operativo.

CodeSlave: ¿está ejecutando en 2000, 2005 o 2008?

Paul Randal
fuente
Ah, ja ... sí, de hecho, SQL 2000.
BIBD
3
No lo devuelve cuando el sistema operativo lo grita, pero lo devuelve si ve que el sistema operativo está por debajo de un cierto umbral para la memoria física libre. Consulte msdn.microsoft.com/en-us/library/ms178067.aspx
sh-beta
Y para reforzar lo que dijo sh-beta, SQL Server 2000 solo libera memoria cuando se da cuenta de que el sistema operativo tiene poca memoria física porque no fue hasta Windows XP (2001) que Windows agregó una API para permitir que " el sistema operativo grite por it "( msdn.microsoft.com/en-us/library/aa366799(v=vs.85).aspx ). SQL Server 2005 aprovecha esa nueva característica de Windows. Pero cuando se escribió SQL Server 2000 no había forma de que el sistema operativo lo gritara, lo que obligó a SQL Server a verificar periódicamente la presión de la memoria.
Ian Boyd
0

Antigua pregunta, lo sé, pero una forma de forzar (al menos más reciente) SQL para liberar memoria es escribir una aplicación que asigne tanta memoria como sea posible en trozos, esperando (digamos) 15 segundos (por ejemplo, Suspensión (15000)) y liberar la memoria asignada y salir; Intenté esto y SQL libera la memoria para que el sistema recupere su RAM; escribir código como el anterior es casi trivial usando C / C ++, solo es cuestión de configurar una cadena de elementos para mantener la cadena de bloque de memoria (puntero y tamaño), reducir progresivamente el tamaño cuando un "malloc ()" falla hasta que alcanza un mínimo (digamos menos de 1024) y luego recorra la lista vinculada para liberar los bloques asignados

Un transeúnte
fuente