SQL Server okresowo czyści pamięć podręczną planu i statystyki wykonania

24

Po uaktualnieniu programu SQL Server 2014 do 2016 serwer co kilka godzin resetuje buforowane plany wykonania i dm*widoki (podobne dm_exec_query_stats) itp

Jakby ktoś wykonał DBCC FREEPROCCACHEi DBCC DROPCLEANBUFFERSręcznie (z wyjątkiem tego, że nikt tego nie robi, dzieje się to automatycznie).

Ta sama baza danych działała dobrze na SQL Server 2014 i Windows Server 2012, po przejściu na SQL Server 2016 (i Windows Server 2016) sytuacja poszła na południe

Rzeczy, które sprawdziłem: baza danych nie ma flagi „automatycznego zamykania”. Serwer SQL toad hoc optimized ustawiony na true(myślałem, że to pomoże, nie pomogło). „Magazyn zapytań” jest „wyłączony”. Serwer ma 16 GB pamięci.

Nic też nie jest pomocne w „dzienniku programu SQL Server”. Tylko cotygodniowa wiadomość zapasowa ...

Sprawdziłem również ten artykuł https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (przewiń w dół do sekcji „Przykłady” i tuż powyżej it) istnieje lista sytuacji, w których plan jest automatycznie czyszczony. Żadne z nich nie ma zastosowania.

AKTUALIZACJA:

Niestety żadna z sugestii nie pomogła. Udzielanie uprawnień LPIM, wykrywanie i naprawianie niesparametryzowanych zapytań, które wygenerowały mnóstwo planów dla tego samego zapytania, obniżenie „maksymalnej pamięci serwera” ... Plany ciągle resetują się losowo, z każdej pary godzin do co 5-10 minut. Jeśli serwer był „pod presją pamięci”, to dlaczego wersja 2014 działała dobrze na tym samym komputerze.

Oto wyjście sp_Blitz zgodnie z żądaniem

**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
źródło
1
Rozwiązałem ten sam problem, możesz spróbować. dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus

Odpowiedzi:

27

Najpierw uzyskaj dokładne czasy czyszczenia pamięci podręcznej planu. Oto najprostszy sposób, aby to zrobić - powinien uruchomić się niemal natychmiast i nikogo nie zablokować:

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

Jeśli ta data / godzina wydaje ci się starsza niż się spodziewałeś , to tylko część pamięci podręcznej planu jest czyszczona. Na przykład, być może ktoś wykonuje przebudowę indeksu lub aktualizuje statystyki, co opróżniłoby pamięć podręczną planu dla określonych obiektów, których to dotyczy - ale inne obiekty nadal będą się trzymać. Widzę to bardzo często, gdy zapytania systemowe (takie jak zapytania DMV) pozostają w pobliżu, ale plany użytkowników bazy danych zostają usunięte.

Jeśli ta data / godzina aktualizuje się w określonych odstępach czasu , na przykład jeśli wydaje się aktualizować dokładnie co 2 godziny, np. 6:00, 8:00, 10:00 itp., To prawdopodobnie ktoś uruchamia zadanie lub zapytanie, które powoduje, że pamięć podręczna planu pozbyć się. Gdy znasz dokładną częstotliwość, możesz:

  • Spójrz na harmonogramy zadań, aby zobaczyć, co działa w tym przedziale czasowym
  • Uruchom śledzenie Profiler lub śledzenie zdarzeń rozszerzonych w tym czasie, aby odkryć tajemnicę (zwykle nie jestem fanem śledzenia w produkcji, ale jeśli wiesz dokładnie, kiedy zabójca ma uderzyć, łatwo jest wystrzelić nisko ogólna próbka tego, co się dzieje)
  • Zaloguj się sp_WhoIsActivedo tabeli w tym czasie (najłatwiejsza metoda, ale najmniej prawdopodobne, aby zawęzić ją do dokładnego zapytania powodującego ją)

Jeśli ta data / czas będzie się zmieniać za każdym razem, gdy uruchomisz zapytanie , oznacza to, że twój serwer jest prawdopodobnie pod presją pamięci. Uruchom to, aby wygenerować podstawowe informacje o sprawdzeniu kondycji, a następnie możesz skopiować / wkleić je do pytania stosu, abyśmy mogli je zdiagnozować:

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

(Ujawnienie: Jestem jednym z autorów sp_Blitz .)

Zaktualizowano 2017/08/25 o dane sp_Blitz - dziękuję za uruchomienie sp_Blitz i dodanie go do pytania, a naprawdę pomaga pokazać kilka rzeczy. Korzystasz z programu SQL Server 2016 Enterprise Edition na maszynie wirtualnej z 2 rdzeniami i 16 GB pamięci RAM. Po pierwsze, krótka uwaga na temat licencjonowania: jeśli licencjonujesz gość, minimalny wymóg zakupu to 4 rdzenie, a nie 2. (Zobacz Podręcznik licencjonowania programu SQL Server uzyskać więcej informacji, ). 4 rdzenie w wersji Enterprise to około 28 000 USD , i to dość niezwykłe, że tak dużo pieniędzy na licencje wydano na zaledwie 16 GB pamięci RAM. Jeśli licencjonujesz SQL Server Enterprise Edition na poziomie hosta, możesz to zignorować i uruchomić mniejsze maszyny wirtualne.

Wygląda na to, że twój SQL Server jest pod presją pamięci zewnętrznej. Masz 16 GB pamięci RAM i ustawiłeś maksymalną pamięć serwera na 15 GB. Niestety, 1 GB to za mało dla systemu operacyjnego (plus cokolwiek, co chcesz tam uruchomić, takie jak oprogramowanie do tworzenia kopii zapasowych i SSMS). W naszym Przewodniku instalacji programu SQL Server sugerujemy pozostawienie 4 GB lub 10% wolnego miejsca, w zależności od tego, co nastąpi jest większa - w twoim przypadku byłoby to 4 GB, więc maksymalne ustawienie pamięci serwera powinno wynosić 12 GB, a nie 15 GB.

Więcej dowodów pojawia się w bieżącym przydziale pamięci: masz zablokowane strony w pamięci (LPIM), ale masz tylko 12,02 GB stron zablokowanych w pamięci. To prawdopodobne (ale nie gwarantowane) oznacza, że ​​niektóre inne aplikacje potrzebowały pamięci, więc system Windows wysłał powiadomienie o ciśnieniu pamięci, a SQL Server zrezygnował z pozostałych 3 GB pamięci, aby umożliwić drugiej aplikacji wykonanie tej czynności. To kolejny dowód na to, że tak naprawdę nie możesz iść z 15 GB maksimum - potrzebujesz pamięci na inne rzeczy.

Gdy SQL Server znajdzie się pod presją pamięci zewnętrznej i będzie musiał zwolnić pamięć dla innych aplikacji, ucierpi pamięć podręczna planu.

Masz więc kilka opcji:

  • Ustaw odpowiednio maksymalną pamięć - powiedzmy, 12 GB (lub nawet mniej, jeśli zamierzasz uruchamiać inne aplikacje na serwerze). W ten sposób SQL Server nie będzie musiał sprzedawać się w pamięci i wypłukać rzeczy tylko dlatego, że niektóre inne aplikacja potrzebuje 2-3 GB pamięci RAM - będzie już dostępna
  • Przestań jednak uruchamiać inne aplikacje na serwerze - może to być trudne, jeśli jest to inny sysadmin zdalny pulpit i uruchamianie rzeczy takich jak SSMS. Skonfigurowałem alarmy licznika Perfmon dla liczby otwartych sesji RDP i ostrzegałem, gdy jest to coś innego niż 0 - które mogą pomóc złapać sprawcę w akcji.
  • Dodaj więcej pamięci do maszyny wirtualnej - ale nie sądzę, że naprawdę jej potrzebujesz. Niektóre dowody pokazuje raport sp_Blitz, że „nie wykryto znaczących oczekiwań”. Nie sądzę, żebyś był pod częstą presją pamięci, zwłaszcza, że ​​donosisz, że zdarza się to tylko od czasu do czasu. Jest to najmniej opłacalna opcja.
Brent Ozar
źródło
5

OK, OP tutaj, w końcu naprawiłem ten problem, aktualizując SQL Server 2016 do najnowszej wersji. Miałem SP1i wczoraj zainstalowałem Cumulative Update 6.

Ustawiłem również „maksymalną pamięć” odpowiednio, jak sugeruje odpowiedź Brenta. Nawiasem mówiąc, świetna odpowiedź, wzywam wszystkich, aby ją głosowali.

Minęło 36 godzin i wciąż trwa, plany nie są resetowane.

Brent Ozar ma również bardzo fajną stronę internetową: https://sqlserverupdates.com/, która pomaga ustalić, które aktualizacje są potrzebne.

Kolejną rzeczą, która pomogła, było wykrycie i rozwiązanie problemu „niezaufanych kluczy obcych”. Brent ma bardzo fajny artykuł (hahah, tak, znowu Brent, wiem dobrze), jak go rozwiązać, po prostu google, jest numerem 1

jitbit
źródło
1

Miałem ten problem w moim domowym oknie testowym i dowiedziałem się, że dodanie uprawnienia „Zablokuj strony w pamięci” do konta usługi SQL Server rozwiązało problem, ale nie jestem pewien, czy to najlepsza rada.

Zobacz Włączanie opcji Blokuj strony w pamięci (Windows)

MrKudz
źródło
Blokowanie stron w pamięci nie naprawi tego, jeśli tylko pamięć podręczna planu zostanie usunięta (nie pula buforów).
Brent Ozar