SQL Server періодично очищає кеш плану та статистику виконання


24

Після оновлення SQL Server 2014 до 2016 року сервер продовжує скидати кешовані плани виконання та dm*перегляди (як dm_exec_query_stats) тощо кожні пару годин

Наче хтось виконує DBCC FREEPROCCACHEі DBCC DROPCLEANBUFFERSвручну (крім того, що ніхто не робить, це відбувається автоматично).

Ця сама база даних працювала чудово на SQL Server 2014 та Windows Server 2012, після переходу на SQL Server 2016 (і Windows Server 2016) все пішло на південь.

Речі , які я перевірив: база даних не НЕ має «автоматичний закрити» прапор. На сервері SQL ad hoc optimizedвстановлено значення true(я думав, що це допоможе, не вдалося). "Магазин запитів" "вимкнено". Сервер має 16 ГБ пам'яті.

Немає нічого корисного і в "Журналі SQL Server". Просто щотижневе резервне повідомлення ...

Я також перевірив цю статтю https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (прокрутіть униз до розділу "Приклади" та праворуч зверху це) є перелік ситуацій, коли план очищається автоматично. Жодне з них не застосовується.

ОНОВЛЕННЯ:

На жаль, жодна з пропозицій не допомогла. Надання дозволів LPIM, виявлення та виправлення непараметризованих запитів, які генерували тонни планів для одного запиту, знижуючи "максимальну пам'ять сервера" ... Плани тримати скидання випадковим чином, кожні пару годин до кожні 5-10 хвилин. Якщо сервер був «під тиском пам’яті», наскільки версія 2014 року працювала на тій же машині.

Ось результат виведення sp_Blitz за запитом

**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
Я вирішив ту саму проблему, ви можете спробувати. dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus UYANIK

Відповіді:


27

Спочатку знайдіть точні часи, коли очищається кеш плану. Ось найпростіший спосіб зробити це - він повинен працювати майже миттєво і нікого не блокувати:

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

Якщо ця дата / час здається вам старшою, ніж ви очікували , тоді очищається лише частина кешу плану. Наприклад, можливо, хтось виконує роботу з відновлення індексу або оновлення статистики, яка б змила кеш плану для конкретних постраждалих об'єктів - але інші об'єкти все одно будуть триматися. Я бачу це багато, коли системні запити (як-от запити DMV) тримаються навколо, але база даних користувачів очищає плани.

Якщо ця дата / час оновлюється через певні проміжки часу , наприклад, якщо здається, що вона оновлюється рівно кожні 2 години, наприклад, 6:00, 8:00, 10:00 тощо, то хтось, ймовірно, виконує завдання або запит, який спричиняє кеш плану прибирати. Як тільки ви дізнаєтеся точну частоту, ви можете:

  • Подивіться на свої графіки роботи, щоб побачити, що працює на цьому інтервалі
  • Запустіть прослідку Профілера або Розширені події в цей проміжок часу, щоб з'ясувати таємницю (я, як правило, не прихильник відстежувати виробництво, але якщо ви точно знаєте, коли вбивця збирається завдати удару, досить легко підпалити низький -приклад вибірки того, що працює)
  • За цей час увійдіть sp_WhoIsActiveдо таблиці (найпростіший метод, але найменш ймовірний звузити його до точного запиту, що викликає його)

Якщо ця дата / час змінюються щоразу, коли ви запускаєте запит , то ваш сервер, ймовірно, знаходиться під тиском пам'яті. Запустіть це, щоб створити основну інформацію про перевірку стану здоров’я, а потім ви можете скопіювати / вставити його у своє запитання про стек, щоб ми могли діагностувати його:

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

(Розкриття: Я один з авторів sp_Blitz.)

Оновлено 2017/08/25 з вашими даними sp_Blitz - дякую за запуску sp_Blitz та додавання його до вашого питання, і це дійсно допомагає показати кілька речей. Ви використовуєте SQL Server 2016 Enterprise Edition у вітрині з 2 ядрами та 16 ГБ оперативної пам’яті. По-перше, швидка примітка щодо ліцензування: якщо ви ліцензуєте гостя, мінімальна вимога покупки становить 4 ядра, а не 2. (Докладніше див. Посібник з ліцензування SQL Server .) 4 ядра Enterprise Edition становлять близько 28 000 доларів США , і досить незвично бачити, що багато ліцензійних грошей витрачено лише на 16 Гб оперативної пам’яті. Якщо ви ліцензуєте SQL Server Enterprise Edition на рівні хосту, ви можете проігнорувати це та запустити менші VM.

Схоже, що ваш SQL Server знаходиться під тиском зовнішньої пам'яті. У вас є 16 Гб оперативної пам’яті та ви встановили максимальну пам'ять сервера на 15 ГБ. На жаль, 1 Гб не вистачає для операційної системи (плюс усе, що ви будете там працювати, як програмне забезпечення для резервного копіювання та SSMS.) У нашому Посібнику з налаштування SQL Server ми пропонуємо залишити 4 ГБ або 10% безкоштовно, залежно від того більше - у вашому випадку це було б 4 Гб, тому ваш максимальний об'єм пам'яті сервера повинен бути 12 ГБ, а не 15 ГБ.

Більше доказів відображається в поточному розподілі пам’яті: ви заблокували сторінки в пам'яті (LPIM), увімкнено, але у вас лише 12,02 ГБ сторінок, зафіксованих у пам'яті. Це, ймовірно, (але не гарантовано) означає, що якійсь іншій програмі потрібна пам'ять, тому Windows надіслала сповіщення про тиск пам’яті, а SQL Server відмовився від інших 3 Гб пам’яті, щоб дозволити іншому додатку робити все. Це ще один доказ того, що ви не можете реально користуватися максимумом 15 ГБ - вам потрібна пам'ять для інших матеріалів.

Коли ваш SQL Server опиниться під тиском зовнішньої пам’яті та потребує звільнення пам’яті для інших додатків, кеш планування постраждає.

Отже, у вас є кілька варіантів:

  • Встановіть макс. Пам'ять належним чином - скажімо, 12 Гб (або навіть нижче, якщо ви збираєтеся запускати інші програми на сервері.) Таким чином, SQL Server не повинен мати продаж вогню в пам'яті та вимивати речі лише тому, що деякі інші додатку потрібно 2-3 Гб оперативної пам’яті - він уже буде доступний
  • Не припиняйте запускати інші програми на сервері - це може бути важко, якщо це інші віддалені на робочому столі sysadmins та такі речі, як SSMS. Я встановив лічильники сигналів Perfmon для кількості відкритих сеансів RDP і попередив, коли це щось інше, ніж 0 - це може допомогти зловити винуватця в дії.
  • Додайте більше пам’яті до VM - але я не думаю, що вам це дуже потрібно. Деякі докази показує звіт sp_Blitz про те, що "значних очікувань не виявлено". Я не думаю, що ти часто зазнаєш тиску в пам'яті, тим більше що ти повідомляєш, що це відбувається раз у раз. Це найменш економічний варіант.

5

Добре, ОП тут, я нарешті вирішив цю проблему, оновивши SQL Server 2016 до останньої версії. Я мав SP1і вчора встановивCumulative Update 6 .

Я також встановлюю "макс. Пам'ять" відповідно, як пропонує відповідь Брента. До речі, чудова відповідь, я закликаю всіх підтримати її.

Минуло 36 годин і підрахунок, плани не скидаються.

Тут також є дуже приємний веб-сайт Brent Ozar: https://sqlserverupdates.com/ який допоможе визначити, які оновлення вам потрібні.

Ще одна річ, яка допомогла, було виявлення та вирішення проблеми "недовірених закордонних ключів". У Brent є дуже приємна стаття (ха-ха, так, Brent знову, я знаю правильно) про те, як її вирішити, просто google, він є результатом №1


1

У мене ця проблема була в домашньому вікні тестування, і я з'ясував, що додавши дозвіл "Заблокувати сторінки в пам'яті" до облікового запису служби SQL Server, це вирішило проблему, але я не впевнений, що це найкраща порада.

Див. Розділ Включення сторінок блокування в опції пам'яті (Windows)


Блокування сторінок у пам'яті не виправить це, якщо буде видалено лише кеш плану (не пул буфера).
Брент Озар
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.