SQL Server cancella periodicamente la cache del piano e le statistiche di esecuzione


24

Dopo aver aggiornato SQL Server 2014 a 2016, il server continua a reimpostare i piani di esecuzione memorizzati nella cache e le dm*visualizzazioni (come dm_exec_query_stats), ecc. Ogni due ore

Come se qualcuno eseguisse DBCC FREEPROCCACHEe DBCC DROPCLEANBUFFERSmanualmente (tranne che per nessuno, succede automaticamente).

Lo stesso database ha funzionato bene su SQL Server 2014 e Windows Server 2012, le cose sono andate a sud dopo essere passati a SQL Server 2016 (e Windows Server 2016)

Cose che ho controllato: il database non ha il flag "chiusura automatica". Il server SQL è ad hoc optimizedimpostato su true(ho pensato che sarebbe stato d'aiuto, non è stato così). "Query store" è "off". Il server ha 16 GB di memoria.

Nulla di utile neanche nel "registro di SQL Server". Solo un messaggio di backup settimanale ...

Ho anche controllato questo articolo https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (scorrere verso il basso fino alla sezione "Esempi" e proprio sopra esso) c'è un elenco di situazioni in cui il piano viene cancellato automaticamente. Nessuno di questi si applica.

AGGIORNARE:

Sfortunatamente, nessuno dei suggerimenti ha aiutato. Concessione di autorizzazioni LPIM, rilevamento e correzione di query non parametrizzate che hanno generato tonnellate di piani per la stessa query, riduzione della "memoria massima del server" ... I piani continuano a reimpostarsi in modo casuale, da un paio d'ore a ogni 5-10 minuti. Se il server era "sotto pressione della memoria", come mai la versione 2014 funzionava perfettamente sulla stessa macchina.

Ecco l'output di sp_Blitz come richiesto

**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...

1
Ho risolto lo stesso problema, puoi provare. dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus UYANIK

Risposte:


27

Innanzitutto, ottieni gli orari esatti in cui viene cancellata la cache del piano. Ecco il modo più semplice per farlo: dovrebbe funzionare quasi istantaneamente e non bloccherà nessuno:

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

Se quella data / ora ti sembrano più vecchie del previsto , solo una parte della cache del piano viene cancellata. Ad esempio, forse qualcuno sta eseguendo un processo di ricostruzione dell'indice o di aggiornamento delle statistiche, che svuoterebbe la cache del piano per gli oggetti specifici interessati, ma altri oggetti rimarranno comunque bloccati. Lo vedo molto quando le query di sistema (come le query DMV) restano in sospeso, ma i piani del database degli utenti scompaiono.

Se quella data / ora si aggiorna a intervalli specifici , come se sembra aggiornarsi esattamente ogni 2 ore per dire 6:00, 8:00, 10:00, ecc., Probabilmente qualcuno sta eseguendo un lavoro o una query che causa la cache del piano cancella. Una volta che conosci la frequenza esatta, puoi:

  • Guarda i tuoi programmi di lavoro per vedere cosa viene eseguito a tale intervallo
  • Esegui una traccia del profiler o degli eventi estesi durante tale periodo di tempo per capire il mistero (di solito non sono un fan della traccia in produzione, ma se sai esattamente quando il killer sta per colpire, è abbastanza facile accendere un basso -overhead campione di ciò che è in esecuzione)
  • Accedere sp_WhoIsActivea una tabella durante quel periodo (il metodo più semplice, ma il meno probabile per restringerlo alla query esatta che lo causa)

Se tale data / ora continua a cambiare ogni volta che si esegue la query , probabilmente il server è sotto pressione della memoria. Esegui questo per generare informazioni di base sullo stato di salute, quindi puoi copiarlo / incollarlo nella tua domanda Stack in modo che possiamo diagnosticare:

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

(Divulgazione: sono uno degli autori di sp_Blitz.)

Aggiornato 2017/08/25 con i tuoi dati sp_Blitz - grazie per aver eseguito sp_Blitz e averlo aggiunto alla tua domanda, e ti aiuta davvero a mostrare alcune cose. Stai eseguendo SQL Server 2016 Enterprise Edition su una macchina virtuale con 2 core e 16 GB di RAM. Innanzitutto, una breve nota sulla licenza: se si dispone di una licenza da parte dell'ospite, il requisito minimo di acquisto è di 4 core, non di 2. (Per ulteriori dettagli, consultare la Guida alle licenze di SQL Server .) 4 core di Enterprise Edition sono circa $ 28.000 USD ed è abbastanza insolito vedere quei soldi in licenza spesi per soli 16 GB di RAM. Se stai concedendo una licenza a SQL Server Enterprise Edition a livello di host, puoi ignorarlo ed eseguire VM più piccole.

Sembra che il tuo SQL Server sia sottoposto alla pressione della memoria esterna. Hai 16 GB di RAM e hai impostato la memoria massima del server su 15 GB. Sfortunatamente, 1 GB non è abbastanza per il sistema operativo (oltre a qualsiasi altra cosa che verrà eseguita lì, come software di backup e SSMS.) Nella nostra Guida all'installazione di SQL Server, ti suggeriamo di lasciare 4 GB o il 10% gratis, a seconda di è maggiore - nel tuo caso, sarebbe 4 GB, quindi l'impostazione di memoria massima del server dovrebbe essere 12 GB anziché 15 GB.

Altre prove vengono visualizzate nelle attuali allocazioni di memoria: hai attivato le pagine bloccate in memoria (LPIM), ma hai solo 12,02 GB di pagine bloccate in memoria. Ciò probabilmente (ma non è garantito) significa che alcune altre applicazioni necessitavano di memoria, quindi Windows ha inviato una notifica di pressione della memoria e SQL Server ha rinunciato agli altri 3 GB di memoria per consentire all'altra app di fare le sue cose. Questa è una prova in più che non puoi davvero andare con un massimo di 15 GB - hai bisogno di memoria per altre cose.

Quando SQL Server viene sottoposto a tale pressione di memoria esterna e deve liberare memoria per altre app, la cache del piano ne risentirà.

Quindi hai alcune opzioni:

  • Imposta la memoria massima in modo appropriato , ad esempio 12 GB (o anche inferiore se eseguirai altre app sul server). In questo modo, SQL Server non dovrà avere una vendita al fuoco in memoria e svuotare le cose solo perché alcuni altri l'app ha bisogno di 2-3 GB di RAM: sarà già disponibile
  • Smetti di eseguire altre app sul server - questo può essere difficile se si tratta di altri amministratori di sistema remoti che eseguono operazioni di desktop deskingpping ed eseguono cose come SSMS. Ho impostato gli allarmi contatore Perfmon per il numero di sessioni RDP aperte e avvisato quando è diverso da 0 - che può aiutare a catturare il colpevole in azione.
  • Aggiungi più memoria alla VM , ma non credo che ne abbia davvero bisogno. Alcune prove sono mostrate dal rapporto sp_Blitz di "nessuna attesa significativa rilevata". Non credo che tu sia sottoposto a frequenti pressioni di memoria, soprattutto perché dici che succede solo ogni tanto. Questa è l'opzione meno conveniente.

5

OK, OP qui, ho finalmente risolto questo problema aggiornando SQL Server 2016 all'ultima versione. Avevo SP1e ieri ho installato Cumulative Update 6.

Ho anche impostato la "memoria massima" in modo appropriato, come suggerisce la risposta di Brent. Ottima risposta a proposito, esorto tutti a votarlo.

Sono passate 36 ore e oltre, i piani non sono stati ripristinati.

Brent Ozar ha anche un sito Web molto carino qui: https://sqlserverupdates.com/ per determinare quali aggiornamenti sono necessari.

Un'altra cosa che ha aiutato è stata la rilevazione e la risoluzione del problema "chiavi esterne non attendibili". Brent ha un bellissimo articolo (hahah, sì, ancora Brent, lo so bene) su come risolverlo, basta Google, è il risultato numero 1


1

Ho avuto questo problema nella mia casella di test a casa e ho scoperto che aggiungendo l'autorizzazione "Blocca pagine in memoria" all'account del servizio SQL Server ho risolto il problema, ma non sono sicuro che questo sia il miglior consiglio.

Vedere Abilitare l'opzione Blocca pagine in memoria (Windows)


Il blocco delle pagine in memoria non lo risolverà se viene cancellata solo la cache del piano (non il pool di buffer).
Brent Ozar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.