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/…
Юнус УЯНИК,

Ответы:


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 и т. Д., То, возможно, кто-то выполняет задание или запрос, который вызывает кэш плана вычищать. Как только вы знаете точную частоту, вы можете:

  • Посмотрите на ваши графики работы, чтобы увидеть, что работает на этом интервале
  • Запустите трассировку Profiler или Extended Events в течение этого промежутка времени, чтобы выяснить загадку (я обычно не фанат трассировки в производстве, но если вы точно знаете, когда убийца собирается нанести удар, достаточно легко запустить низкий Образец того, что работает)
  • За это время войдите 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 на уровне хоста, вы можете игнорировать это и запускать меньшие виртуальные машины.

Похоже, что ваш 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 ГБ оперативной памяти - оно уже будет доступно
  • Прекратите запуск других приложений на сервере - это может быть сложно, если это другие удаленные рабочие столы системных администраторов и запускающие такие вещи, как SSMS. Я настроил счетчик тревоги Perfmon для количества открытых сеансов RDP и предупреждал, когда он не равен 0 - это может помочь поймать виновника в действии.
  • Добавьте больше памяти к ВМ - но я не думаю, что вам это действительно нужно. Некоторое доказательство показано в отчете sp_Blitz о том, что «значительных ожиданий не обнаружено». Я не думаю, что вы испытываете частое давление памяти, тем более, что вы сообщаете, что это происходит только время от времени. Это наименее рентабельный вариант.

5

Хорошо, OP здесь, я наконец исправил эту проблему, обновив SQL Server 2016 до последней версии. Я имел SP1и вчера я установил Cumulative Update 6.

Я также установил «максимальную память» соответствующим образом, как предполагает ответ Брента. Кстати, отличный ответ, я призываю всех поддержать его.

Прошло 36 часов и считается, планы не сбрасываются.

У Брента Озара также есть очень хороший сайт здесь: https://sqlserverupdates.com/, чтобы помочь определить, какие обновления вам нужны.

Еще одна вещь, которая помогла, была обнаружение и решение проблемы «ненадежных внешних ключей». У Брента есть очень хорошая статья (хахах, да, Брент снова, я знаю правильно) о том, как ее решить, просто Google, он # 1 результат


1

У меня была эта проблема в моем домашнем окне тестирования, и я обнаружил, что добавление разрешения «Блокировка страниц в памяти» к учетной записи службы SQL Server решило проблему, но я не уверен, что это лучший совет.

См. Параметр «Включить блокировку страниц в памяти» (Windows)


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