O SQL Server limpa periodicamente as estatísticas de cache e execução do plano

24

Após a atualização do SQL Server 2014 para 2016, o servidor continua redefinindo planos de execução em cache e dm*exibições (como dm_exec_query_stats) etc. a cada duas horas

Como se alguém executasse DBCC FREEPROCCACHEe DBCC DROPCLEANBUFFERSmanualmente (exceto por ninguém, isso acontece automaticamente).

O mesmo banco de dados funcionou bem no SQL Server 2014 e no Windows Server 2012; as coisas foram para o sul depois de mudar para o SQL Server 2016 (e Windows server 2016)

Coisas que verifiquei: o banco de dados não possui o sinalizador "fechar automaticamente". O servidor SQL está ad hoc optimizeddefinido como true(eu pensei que ajudaria, não ajudou). O "repositório de consultas" está "desativado". O servidor possui 16 GB de memória.

Nada útil no "log do SQL Server" também. Apenas uma mensagem de backup semanal ...

Também verifiquei este artigo https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (role para baixo até a seção "Exemplos" e logo acima ) existe uma lista de situações em que o plano é limpo automaticamente. Nenhuma delas se aplica.

ATUALIZAR:

Infelizmente, nenhuma das sugestões ajudou. Concedendo permissões LPIM, detectando e corrigindo consultas não parametrizadas que geraram vários planos para a mesma consulta, diminuindo a "memória máxima do servidor" ... Os planos continuam sendo redefinidos aleatoriamente, a cada duas horas a cada 5 a 10 minutos. Se o servidor estava "sob pressão de memória", como é que a versão de 2014 estava funcionando bem na mesma máquina.

Aqui está a saída sp_Blitz, conforme solicitado

**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
fonte
11
Eu resolvi o mesmo problema, você pode tentar. dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus UYANIK

Respostas:

27

Primeiro, obtenha os horários exatos em que o cache do plano está sendo limpo. Aqui está a maneira mais fácil de fazer isso - ele deve ser executado quase instantaneamente e não bloqueia ninguém:

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

Se essa data / hora lhe parecer mais antiga do que o esperado , apenas parte do cache do plano está sendo limpa. Por exemplo, talvez alguém esteja executando um trabalho de reconstrução de índice ou atualização de estatísticas, o que liberaria o cache do plano para os objetos específicos afetados - mas outros objetos ainda permanecerão. Eu vejo isso muito quando as consultas do sistema (como as consultas DMV) permanecem, mas os planos de banco de dados do usuário desaparecem.

Se essa data / hora for atualizada em intervalos específicos , como se parecesse atualizar exatamente a cada 2 horas para dizer 6:00, 8:00, 10:00, etc., provavelmente alguém está executando um trabalho ou consulta que faz com que o cache do plano limpar. Depois de saber a frequência exata, você pode:

  • Veja os horários de seu trabalho para ver o que é executado nesse intervalo
  • Execute um rastreio do Profiler ou Eventos estendidos durante esse período para descobrir o mistério (geralmente não sou fã de rastreio na produção, mas se você sabe exatamente quando o assassino vai atacar, é fácil o suficiente disparar um baixo). amostra geral do que está sendo executado)
  • Faça logon sp_WhoIsActiveem uma tabela durante esse período (o método mais fácil, mas com menor probabilidade de reduzi-la à consulta exata que a causa)

Se essa data / hora continuar mudando sempre que você executar a consulta , provavelmente o servidor estará sob pressão de memória. Execute isso para gerar informações básicas de verificação de integridade e, em seguida, você pode copiá-lo / colá-lo na sua pergunta do Stack para que possamos diagnosticá-lo:

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

(Divulgação: sou um dos autores de sp_Blitz.)

Atualizado 25/08/2017 com seus dados do sp_Blitz - obrigado por executar o sp_Blitz e adicioná-lo à sua pergunta, e isso realmente ajuda a mostrar algumas coisas. Você está executando o SQL Server 2016 Enterprise Edition em uma VM com 2 núcleos e 16 GB de RAM. Primeiro, uma observação rápida sobre o licenciamento: se você está licenciando pelo convidado, o requisito mínimo de compra é de 4 núcleos, e não 2. (Consulte o Guia de Licenciamento do SQL Server para obter mais detalhes.) , e é bastante incomum ver tanto dinheiro gasto com licenciamento em apenas 16 GB de RAM. Se você estiver licenciando o SQL Server Enterprise Edition no nível do host, poderá ignorá-lo e executar VMs menores.

Parece que o SQL Server está sofrendo pressão de memória externa. Você tem 16 GB de RAM e configurou a memória máxima do servidor em 15 GB. Infelizmente, 1 GB não é suficiente para o sistema operacional (mais o que mais você executar nele, como software de backup e SSMS.) Em nosso Guia de Instalação do SQL Server, sugerimos deixar 4 GB ou 10% gratuitos, o que for é maior - no seu caso, seriam 4 GB, portanto, a configuração máxima da memória do servidor deve ser de 12 GB em vez de 15 GB.

Mais evidências são exibidas nas alocações de memória atuais: você tem páginas bloqueadas na memória (LPIM) ativadas, mas você só tem 12,02 GB de páginas bloqueadas na memória. Isso provavelmente (mas não garantido) significa que algum outro aplicativo precisava de memória; portanto, o Windows enviou uma notificação de pressão de memória e o SQL Server gastou os outros 3 GB de memória para permitir que o outro aplicativo fizesse suas coisas. É mais uma prova de que você não pode realmente usar um máximo de 15 GB - você precisa de memória para outras coisas.

Quando o SQL Server sofrer essa pressão de memória externa e precisar liberar memória para outros aplicativos, o cache do seu plano sofrerá.

Então você tem algumas opções:

  • Defina a memória máxima adequadamente - digamos, 12 GB (ou até mais, se você estiver executando outros aplicativos no servidor). Dessa forma, o SQL Server não precisará ter uma venda direta na memória e liberar coisas apenas porque outras O aplicativo precisa de 2-3 GB de RAM - já estará disponível
  • Pare de executar outros aplicativos no servidor - isso pode ser difícil se houver outros administradores de área de trabalho remota e executar coisas como SSMS. Eu configurei os alarmes do contador Perfmon para o número de sessões RDP abertas e alertei quando for algo diferente de 0 - que pode ajudar a capturar o culpado em ação.
  • Adicione mais memória à VM - mas acho que você realmente não precisa dela. Algumas evidências são mostradas pelo relatório sp_Blitz de "nenhuma espera significativa detectada". Eu não acho que você esteja sob pressão frequente de memória, principalmente porque relata que isso acontece de vez em quando. Esta é a opção menos econômica.
Brent Ozar
fonte
5

OK, OP aqui, finalmente resolvi esse problema atualizando o SQL Server 2016 para a versão mais recente. Eu tinha SP1e ontem eu instalei Cumulative Update 6.

Também defini a "memória máxima" de maneira apropriada, como sugere a resposta de Brent. Ótima resposta, a propósito, peço a todos que o votem.

Faz 36 horas e contando, os planos não estão sendo redefinidos.

Brent Ozar também tem um site muito legal aqui: https://sqlserverupdates.com/ para ajudar a determinar quais atualizações você precisa.

Outra coisa que ajudou foi detectar e resolver o problema de "chaves estrangeiras não confiáveis". Brent tem um artigo muito bom (hahah, sim, Brent de novo, eu sei direito) sobre como resolvê-lo, apenas no google, ele é o resultado # 1

jitbit
fonte
1

Eu tive esse problema na minha caixa de testes em casa e descobri que a adição de permissão 'Bloquear páginas na memória' à conta de serviço do SQL Server resolveu o problema, mas não tenho certeza se esse é o melhor conselho.

Consulte Ativar a opção Bloquear páginas na memória (Windows)

MrKudz
fonte
Bloquear páginas na memória não o corrigirá se apenas o cache do plano estiver sendo apagado (e não o buffer pool).
Brent Ozar