SQL Server borra periódicamente las estadísticas de caché y ejecución del plan

24

Después de actualizar SQL Server 2014 a 2016, el servidor sigue restableciendo los planes de ejecución en caché y las dm*vistas (como dm_exec_query_stats), etc. cada dos horas

Como si alguien ejecutara DBCC FREEPROCCACHEy DBCC DROPCLEANBUFFERSmanualmente (excepto que nadie lo hace, sucede automáticamente).

La misma base de datos funcionó bien en SQL Server 2014 y Windows Server 2012, las cosas se fueron al sur después de pasar a SQL Server 2016 (y Windows Server 2016)

Cosas que verifiqué: la base de datos no tiene el indicador "cierre automático" El servidor SQL está ad hoc optimizedconfigurado en true(pensé que ayudaría, no lo hizo). El "almacén de consultas" está "apagado". El servidor tiene 16 GB de memoria.

Nada útil en el "registro de SQL Server" tampoco. Solo un mensaje de respaldo semanal ...

También revisé este artículo https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (desplácese hacia abajo a la sección "Ejemplos", y justo arriba it) hay una lista de situaciones en las que el plan se borra automáticamente. Ninguno de esos aplica.

ACTUALIZAR:

Lamentablemente, ninguna de las sugerencias ayudó. Otorgando permisos LPIM, detectando y reparando consultas no parametrizadas que generaron toneladas de planes para la misma consulta, reduciendo la "memoria máxima del servidor" ... Los planes se reinician aleatoriamente, de cada dos horas a cada 5-10 minutos. Si el servidor estaba "bajo presión de memoria", ¿cómo es que la versión 2014 funcionaba bien en la misma máquina?

Aquí está la salida de sp_Blitz según lo solicitado

**Priority 10: Performance**:

- Query Store Disabled - The new SQL Server 2016 Query Store feature has not been enabled on this database.

    * xxx


**Priority 50: Server Info**:

- Instant File Initialization Not Enabled  - Consider enabling IFI for faster restores and data file growths.


**Priority 100: Performance**:

- Resource Governor Enabled  - Resource Governor is enabled.  Queries may be throttled.  Make sure you understand how the Classifier Function is configured.


**Priority 120: Query Plans**:

- Implicit Conversion Affecting Cardinality - One of the top resource-intensive queries has an implicit conversion that is affecting cardinality estimation.

    * 

- Missing Index - One of the top resource-intensive queries may be dramatically improved by adding an index.

    * 

- RID or Key Lookups - One of the top resource-intensive queries contains RID or Key Lookups. Try to avoid them by creating covering indexes.

    * 

**Priority 170: File Configuration**:

- System Database on C Drive
    * master - The master database has a file on the C drive.  Putting system databases on the C drive runs the risk of crashing the server when it runs out of space.

    * model - The model database has a file on the C drive.  Putting system databases on the C drive runs the risk of crashing the server when it runs out of space.

    * msdb - The msdb database has a file on the C drive.  Putting system databases on the C drive runs the risk of crashing the server when it runs out of space.


**Priority 200: Backup**:

- MSDB Backup History Not Purged msdb - Database backup history retained back to Jun 10 2017  9:47PM


**Priority 200: Informational**:

- Backup Compression Default Off  - Uncompressed full backups have happened recently, and backup compression is not turned on at the server level. Backup compression is included with SQL Server 2008R2 & newer, even in Standard Edition. We recommend turning backup compression on by default so that ad-hoc backups will get compressed.


**Priority 200: Non-Default Server Config**:

- Agent XPs  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.

- max server memory (MB)  - This sp_configure option has been changed.  Its default value is 2147483647 and it has been set to 15000.

- optimize for ad hoc workloads  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.

- show advanced options  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.

- xp_cmdshell  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.


**Priority 200: Performance**:

- Buffer Pool Extensions Enabled  - You have Buffer Pool Extensions enabled, and one lives here: Z:\sql_buffer_pool.BPE. It's currently 60.00000000000 GB. Did you know that BPEs only provide single threaded access 8KB (one page) at a time?

- cost threshold for parallelism  - Set to 5, its default value. Changing this sp_configure setting may reduce CXPACKET waits.

**Priority 240: Wait Stats**:

- No Significant Waits Detected  - This server might be just sitting around idle, or someone may have cleared wait stats recently.

**Priority 250: Informational**:

- SQL Server Agent is running under an NT Service account  - I'm running as NT Service\SQLSERVERAGENT. I wish I had an Active Directory service account instead.

- SQL Server is running under an NT Service account  - I'm running as NT Service\MSSQLSERVER. I wish I had an Active Directory service account instead.

**Priority 250: Server Info**:

- Default Trace Contents  - The default trace holds 125 hours of data between Aug 19 2017 11:55AM and Aug 24 2017  4:59PM. The default trace files are located in: C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Log

- Hardware  - Logical processors: 2. Physical memory: 15GB.

- Hardware - NUMA Config  - Node: 0 State: ONLINE Online schedulers: 2 Offline schedulers: 0 Processor Group: 0 Memory node: 0 Memory VAS Reserved GB: 29

- Locked Pages In Memory Enabled  - You currently have 12.02534484863 GB of pages locked in memory.

- Memory Model Unconventional  - Memory Model: LOCK_PAGES

- Server Last Restart  - Aug 20 2017 12:32PM

- Server Name  - xx

- Services
 - Service: SQL Full-text Filter Daemon Launcher (MSSQLSERVER) runs under service account NT Service\MSSQLFDLauncher. Last startup time: not shown.. Startup type: Manual, currently Running.

 - Service: SQL Server (MSSQLSERVER) runs under service account NT Service\MSSQLSERVER. Last startup time: Aug 20 2017 12:32PM. Startup type: Automatic, currently Running.

 - Service: SQL Server Agent (MSSQLSERVER) runs under service account NT Service\SQLSERVERAGENT. Last startup time: not shown.. Startup type: Automatic, currently Running.

- SQL Server Last Restart  - Aug 20 2017 12:33PM

- SQL Server Service  - Version: 13.0.4446.0. Patch Level: SP1. Edition: Enterprise Edition (64-bit). AlwaysOn Enabled: 0. AlwaysOn Mgr Status: 2

- Virtual Server  - Type: (HYPERVISOR)

- Windows Version  - You're running a pretty modern version of Windows: Server 2012R2 era, version 6.3


**Priority 254: Rundate**:

 - Captain's log: stardate something and something...
jitbit
fuente
1
He resuelto el mismo problema, puedes intentarlo. dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus UYANIK

Respuestas:

27

Primero, obtenga las horas exactas en que se está borrando el caché del plan. Esta es la forma más fácil de hacerlo: debería ejecutarse casi instantáneamente y no bloqueará a nadie:

SELECT TOP 1 creation_time
FROM sys.dm_exec_query_stats WITH (NOLOCK)
ORDER BY creation_time;

Si esa fecha / hora le parece más antigua de lo que esperaba , solo se está borrando parte del caché del plan. Por ejemplo, tal vez alguien está haciendo un trabajo de reconstrucción de índice o actualización de estadísticas, lo que eliminaría la memoria caché del plan para los objetos específicos afectados, pero otros objetos aún se quedarán. Veo esto mucho cuando las consultas del sistema (como las consultas del DMV) se quedan, pero los planes de la base de datos del usuario se despejan.

Si esa fecha / hora se actualiza a intervalos específicos , como si parece actualizarse exactamente cada 2 horas para decir 6:00, 8:00, 10:00, etc., entonces alguien probablemente esté ejecutando un trabajo o consulta que hace que el caché del plan aclarar. Una vez que sepa la frecuencia exacta, puede:

  • Mira tus horarios de trabajo para ver qué se ejecuta en ese intervalo
  • Ejecute un rastreo de Profiler o de eventos extendidos durante ese período de tiempo para descubrir el misterio (generalmente no soy un fanático del rastreo en la producción, pero si sabe exactamente cuándo atacará el asesino, es bastante fácil disparar un bajo muestra general de lo que se está ejecutando)
  • Inicie sesión sp_WhoIsActiveen una tabla durante ese tiempo (el método más fácil, pero el menos probable que lo reduzca a la consulta exacta que lo causa)

Si esa fecha / hora sigue cambiando cada vez que ejecuta la consulta , entonces su servidor probablemente esté bajo presión de memoria. Ejecute esto para generar información básica de comprobación de estado, y luego puede copiarla / pegarla en su pregunta de Pila para que podamos diagnosticarla:

sp_Blitz @OutputType = 'markdown', @CheckServerInfo = 1, @CheckUserDatabaseObjects = 1

(Divulgación: soy uno de los autores de sp_Blitz.)

Actualizado el 25/08/2017 con sus datos de sp_Blitz : gracias por ejecutar sp_Blitz y agregarlo a su pregunta, y realmente ayuda a mostrar algunas cosas. Está ejecutando SQL Server 2016 Enterprise Edition en una máquina virtual con 2 núcleos y 16 GB de RAM. Primero, una nota rápida sobre la licencia: si el cliente lo autoriza, el requisito mínimo de compra es de 4 núcleos, no 2. (Consulte la Guía de licencias de SQL Server para obtener más detalles). 4 núcleos de Enterprise Edition cuestan aproximadamente $ 28K USD , y es bastante inusual ver que se gasta tanto dinero de licencias en solo 16 GB de RAM. Sin embargo, si está licenciando SQL Server Enterprise Edition a nivel de host, puede ignorar eso y ejecutar máquinas virtuales más pequeñas.

Parece que su SQL Server está bajo presión de memoria externa. Tiene 16 GB de RAM y ha configurado la memoria máxima del servidor en 15 GB. Desafortunadamente, 1GB no es suficiente para el sistema operativo (más cualquier otra cosa que vaya a ejecutar allí, como software de respaldo y SSMS). En nuestra Guía de configuración de SQL Server, sugerimos dejar 4GB o 10% libre, lo que sea es mayor: en su caso, serían 4 GB, por lo que la configuración de memoria máxima del servidor debería ser de 12 GB en lugar de 15 GB.

Aparece más evidencia en sus asignaciones de memoria actuales: tiene las páginas bloqueadas en la memoria (LPIM) activadas, pero solo tiene 12.02GB de páginas bloqueadas en la memoria. Eso probablemente (pero no garantizado) significa que alguna otra aplicación necesitaba memoria, por lo que Windows envió una notificación de presión de memoria y SQL Server renunció a los otros 3 GB de memoria para que la otra aplicación hiciera lo suyo. Esa es una prueba más de que realmente no puedes ir con un máximo de 15 GB: necesitas memoria para otras cosas.

Cuando su SQL Server se ve sometido a esa presión de memoria externa y necesita liberar memoria para otras aplicaciones, su caché del plan se verá afectado.

Entonces tienes algunas opciones:

  • Establezca la memoria máxima de manera apropiada , digamos, 12 GB (o incluso menos si va a ejecutar otras aplicaciones en el servidor). De esa manera, SQL Server no tendrá que tener una venta de liquidación en la memoria y eliminar las cosas solo porque algunos otros la aplicación necesita 2-3 GB de RAM: ya estará disponible
  • Deje de ejecutar otras aplicaciones en el servidor ; sin embargo, esto puede ser difícil si se trata de otros sistemas de escritorio remotos y ejecutar cosas como SSMS. Configuré alarmas de contador de Perfmon para el número de sesiones RDP abiertas y alerté cuando no es 0, lo que puede ayudar a atrapar al culpable en acción.
  • Agregue más memoria a la VM , pero no creo que realmente la necesite. El informe sp_Blitz muestra que "no se detectaron esperas significativas". No creo que esté bajo presión de memoria frecuente, especialmente porque informa que solo sucede de vez en cuando. Esta es la opción menos rentable.
Brent Ozar
fuente
5

OK, OP aquí, finalmente solucioné este problema actualizando SQL Server 2016 a la última versión. Tenía SP1y ayer instalé Cumulative Update 6.

También configuré "memoria máxima" de manera apropiada, como sugiere la respuesta de Brent. Gran respuesta por cierto, insto a todos a votarla.

Han pasado 36 horas y contando, los planes no se reinician.

Brent Ozar también tiene un sitio web muy agradable aquí: https://sqlserverupdates.com/ para ayudar a determinar qué actualizaciones necesita.

Otra cosa que ayudó fue detectar y resolver el problema de "claves externas no confiables". Brent tiene un muy buen artículo (jaja, sí, Brent nuevamente, lo sé bien) sobre cómo resolverlo, solo google, él es el resultado número 1

jitbit
fuente
1

He tenido este problema en el cuadro de prueba de mi casa y descubrí que al agregar el permiso 'Bloquear páginas en memoria' a la cuenta de servicio de SQL Server se resolvió el problema, pero no estoy seguro de que este sea el mejor consejo.

Consulte Habilitar la opción Bloquear páginas en la memoria (Windows)

MrKudz
fuente
El bloqueo de páginas en la memoria no lo solucionará si solo se borra el caché del plan (no el grupo de búferes).
Brent Ozar