SQL Server efface périodiquement le cache du plan et les statistiques d'exécution

24

Après la mise à niveau de SQL Server 2014 vers 2016, le serveur continue de réinitialiser les plans d'exécution mis en cache et les dm*vues (comme dm_exec_query_stats), etc. toutes les deux heures

Comme si quelqu'un s'exécute DBCC FREEPROCCACHEet DBCC DROPCLEANBUFFERSmanuellement (sauf pour personne, cela se produit automatiquement).

La même base de données très bien fonctionné sur SQL Server 2014 et Windows Server 2012, les choses ont tourné au sud après avoir migré vers SQL Server 2016 (et Windows Server 2016)

Choses que j'ai vérifiées: la base de données n'a pas d' indicateur "fermeture automatique". Le serveur SQL est ad hoc optimizeddéfini sur true(je pensais que cela aiderait, ce n'est pas le cas). Le "magasin de requêtes" est "désactivé". Le serveur a 16 Go de mémoire.

Rien d'utile non plus dans le "journal SQL Server". Juste un message de sauvegarde hebdomadaire ...

J'ai également vérifié cet article https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (faites défiler jusqu'à la section "Exemples" et à droite ci-dessus it) il y a une liste de situations où le plan est effacé automatiquement. Rien de tout cela ne s'applique.

MISE À JOUR:

Malheureusement, aucune des suggestions n'a aidé. Octroi d'autorisations LPIM, détection et correction des requêtes non paramétrées qui ont généré des tonnes de plans pour la même requête, réduction de la «mémoire maximale du serveur» ... Les plans continuent de se réinitialiser de manière aléatoire, de quelques heures à toutes les 5 à 10 minutes. Si le serveur était "sous pression mémoire", comment se fait-il que la version 2014 fonctionnait bien sur la même machine.

Voici la sortie sp_Blitz comme demandé

**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
la source
1
J'ai résolu le même problème, vous pouvez essayer. dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus UYANIK

Réponses:

27

Tout d'abord, obtenez l'heure exacte à laquelle le cache du plan est effacé. Voici le moyen le plus simple de le faire - il devrait fonctionner presque instantanément et ne bloquera personne:

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

Si cette date / heure vous semble plus ancienne que prévu , alors seule une partie du cache du plan est en cours de suppression. Par exemple, quelqu'un fait peut-être une tâche de reconstruction d'index ou de mise à jour des statistiques, ce qui viderait le cache du plan pour les objets spécifiques affectés - mais d'autres objets resteront toujours. Je vois cela souvent lorsque les requêtes système (comme les requêtes DMV) restent, mais les plans de base de données utilisateur disparaissent.

Si cette date / heure est mise à jour à des intervalles spécifiques , comme si elle semble se mettre à jour toutes les 2 heures exactement, par exemple 6h00, 8h00, 10h00, etc., alors quelqu'un exécute probablement un travail ou une requête qui provoque la mise en cache du plan. évacuer. Une fois que vous connaissez la fréquence exacte, vous pouvez:

  • Regardez vos horaires de travail pour voir ce qui s'exécute à cet intervalle
  • Exécutez une trace Profiler ou une trace d'événements étendus pendant cette période pour comprendre le mystère (je ne suis généralement pas un fan du traçage en production, mais si vous savez exactement quand le tueur va frapper, il est assez facile de déclencher un faible -échantillon aérien de ce qui fonctionne)
  • Connectez-vous sp_WhoIsActiveà une table pendant ce temps (la méthode la plus simple, mais la moins susceptible de la réduire à la requête exacte qui la provoque)

Si cette date / heure continue de changer chaque fois que vous exécutez la requête , votre serveur est probablement sous pression de mémoire. Exécutez ceci pour générer des informations de base sur le bilan de santé, puis vous pouvez les copier / coller dans votre question Stack afin que nous puissions les diagnostiquer:

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

(Divulgation: je suis l'un des auteurs de sp_Blitz.)

Mise à jour 2017/08/25 avec vos données sp_Blitz - merci d'avoir exécuté sp_Blitz et de l'ajouter à votre question, et cela aide vraiment à montrer quelques choses. Vous exécutez SQL Server 2016 Enterprise Edition sur une machine virtuelle avec 2 cœurs et 16 Go de RAM. Tout d'abord, une note rapide sur les licences: si vous octroyez une licence par le client, l'achat minimum requis est de 4 cœurs, pas 2. (Voir le Guide de licence SQL Server pour plus de détails.) 4 cœurs d'Enterprise Edition coûte environ 28 000 USD , et il est assez inhabituel de voir autant d'argent de licence dépensé sur seulement 16 Go de RAM. Si vous accordez une licence à SQL Server Enterprise Edition au niveau de l'hôte, vous pouvez ignorer cela et exécuter des machines virtuelles plus petites, cependant.

Il semble que votre serveur SQL soit soumis à une pression de mémoire externe. Vous avez 16 Go de RAM et vous avez défini la mémoire maximale du serveur à 15 Go. Malheureusement, 1 Go n'est pas suffisant pour le système d'exploitation (plus tout ce que vous allez y exécuter, comme le logiciel de sauvegarde et SSMS.) Dans notre Guide de configuration de SQL Server, nous vous suggérons de laisser 4 Go ou 10% de libre, selon le cas est supérieur - dans votre cas, ce serait 4 Go, donc la configuration maximale de la mémoire du serveur devrait être de 12 Go au lieu de 15 Go.

Plus de preuves apparaissent dans vos allocations de mémoire actuelles: vous avez activé les pages verrouillées en mémoire (LPIM), mais vous n'avez que 12,02 Go de pages verrouillées en mémoire. Cela signifie probablement (mais non garanti) qu'une autre application avait besoin de mémoire, donc Windows a envoyé une notification de pression de mémoire, et SQL Server a renoncé aux 3 Go de mémoire restants pour laisser l'autre application faire son travail. C'est une preuve supplémentaire que vous ne pouvez pas vraiment aller avec un maximum de 15 Go - vous avez besoin de mémoire pour d'autres choses.

Lorsque votre serveur SQL subit cette pression de mémoire externe et doit libérer de la mémoire pour d'autres applications, le cache de votre plan en souffrira.

Vous avez donc quelques options:

  • Définissez la mémoire maximale de manière appropriée - par exemple, 12 Go (ou même moins si vous souhaitez exécuter d'autres applications sur le serveur.) De cette façon, SQL Server n'aura pas à vendre de mémoire en mémoire et à vider les choses simplement parce que d'autres l'application a besoin de 2 à 3 Go de RAM - elle sera déjà disponible
  • Arrêtez d'exécuter d'autres applications sur le serveur - cela peut être difficile s'il s'agit d'autres applications de bureau à distance et d'exécution de systèmes sysadmins comme SSMS. J'ai mis en place des contre-alarmes Perfmon pour le nombre de sessions RDP ouvertes, et alerté lorsque c'est autre chose que 0 - cela peut aider à attraper le coupable en action.
  • Ajoutez plus de mémoire à la machine virtuelle - mais je ne pense pas que vous en ayez vraiment besoin. Certaines preuves sont montrées par le rapport sp_Blitz de "aucune attente significative détectée." Je ne pense pas que vous subissiez de fréquentes pressions sur la mémoire, d'autant plus que vous signalez que cela ne se produit que de temps en temps. Il s'agit de l'option la moins rentable.
Brent Ozar
la source
5

OK, OP ici, j'ai finalement résolu ce problème en mettant à jour SQL Server 2016 vers la dernière version. J'avais SP1et hier j'ai installé Cumulative Update 6.

J'ai également défini la «mémoire maximale» de manière appropriée, comme le suggère la réponse de Brent. Excellente réponse au fait, j'exhorte tout le monde à le voter.

Cela fait 36 ​​heures et compte, les plans ne sont pas réinitialisés.

Brent Ozar a également un très beau site Web ici: https://sqlserverupdates.com/ pour vous aider à déterminer les mises à jour dont vous avez besoin.

Une autre chose qui a aidé à détecter et résoudre le problème des "clés étrangères non fiables". Brent a un très bel article (hahah, ouais, Brent encore, je sais bien) sur la façon de le résoudre, juste google, il est le résultat n ° 1

jitbit
la source
1

J'ai eu ce problème dans ma boîte de test à domicile et j'ai découvert qu'en ajoutant l'autorisation `` Verrouiller les pages en mémoire '' au compte de service SQL Server a résolu le problème, mais je ne suis pas sûr que ce soit le meilleur conseil.

Voir Activer l'option de verrouillage des pages en mémoire (Windows)

MrKudz
la source
Verrouiller les pages en mémoire ne le réparera pas si seul le cache du plan est effacé (pas le pool de tampons).
Brent Ozar