web-dev-qa-db-ja.com

SQL Serverは計画キャッシュと実行統計を定期的にクリアします

SQL Server 2014を2016にアップグレードした後、サーバーはキャッシュされた実行プランやdm*ビュー(dm_exec_query_statsなど)などをリセットし続けます2時間ごと

誰かがDBCC FREEPROCCACHEDBCC DROPCLEANBUFFERSを手動で実行するかのように(誰も実行しない場合を除き、自動的に実行されます)。

SQL Server 2014とWindows Server 2012では同じデータベースが正常に機能しましたが、SQL Server 2016(およびWindows Server 2016)に移行した後、事態は悪化しました。

私がチェックしたもの:データベースには「自動クローズ」フラグがありません。 SQLサーバーはad hoc optimizedtrueに設定されています(私はそれが役立つと思いましたが、役に立ちませんでした)。 「クエリストア」は「オフ」です。サーバーには16 GBのメモリがあります。

「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...
24
jitbit

OK、ここでOP、SQL Server 2016を最新バージョンに更新して、この問題を最終的に修正しました。 SP1と昨日インストールしたCumulative Update 6

ブレントの回答が示唆するように、「最大メモリ」も適切に設定します。ちなみに素晴らしい答えですが、私はそれを賛成することを皆に強く勧めます。

36時間経過しましたが、計画はリセットされていません。

Brent Ozarには、非常に素晴らしいWebサイトもあります。 https://sqlserverupdates.com/ は、必要な更新の判別に役立ちます。

もう1つの助けとなったのは、「信頼できない外部キー」の問題を検出して解決することでした。ブレントには、それを解決する方法についての非常に素晴らしい記事があります(ハハ、ええ、ブレント、また知っています)。グーグルだけで、彼は1位の結果です

5
jitbit

まず、プランのキャッシュがクリアされている正確な時間を取得します。これが最も簡単な方法です。ほぼ瞬時に実行され、誰もブロックしません。

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

その日付/時刻が予想よりも古いと思われる場合、プランキャッシュの一部のみがクリアされます。たとえば、誰かがインデックスの再構築または統計の更新ジョブを実行している場合、影響を受ける特定のオブジェクトのプランキャッシュがフラッシュされますが、他のオブジェクトはそのまま残ります。これは、システムクエリ(DMVクエリなど)が定着しているときによく見られますが、ユーザーデータベースの計画は明確です。

その日付/時刻が特定の間隔で更新される場合、たとえば6:00、8:00、10と言って正確に2時間ごとに更新されるように見える場合: 00などの場合、誰かがジョブまたはクエリを実行しているため、プランのキャッシュがクリアされます。正確な頻度がわかったら、次のことができます。

  • ジョブスケジュールを見て、その間隔で実行されるものを確認します
  • その期間内にプロファイラートレースまたは拡張イベントトレースを実行して、謎を解明します(私は通常、本番環境ではトレースのファンではありませんが、キラーがいつ攻撃を開始するかを正確に知っている場合は、ローを起動するのは簡単です-実行中のオーバーヘッドサンプル)
  • Log sp_WhoIsActive to a table その間(最も簡単な方法ですが、それを引き起こしている正確なクエリに絞り込む可能性は最も低くなります)

クエリを実行するたびにその日付/時刻が変化し続ける場合、サーバーはおそらくメモリ不足になっています。これを実行して基本的なヘルスチェック情報を生成し、それをスタックの質問にコピー/貼り付けて、診断できるようにします。

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

(開示:私はsp_Blitzの作成者の1人です。)

2017年8月25日、sp_Blitzデータを更新-sp_Blitzを実行して質問に追加していただきありがとうございます。 VM 2コアと16GBのRAMを搭載したSQL Server 2016 Enterprise Editionを実行しています。最初に、ライセンスに関する簡単なメモ:ゲストによるライセンスの場合、最低購入要件は2ではなく4コアです(詳細は SQL Server Licensing Guide を参照してください)。EnterpriseEditionの4コアは約28,000ドルです。 16GB RAM。ただし、SQL Server Enterprise Editionをホストレベルでライセンスしている場合は、それを無視して、より小さなVMを実行できます。

SQL Serverに外部メモリの負荷がかかっているようです。 16 GBのRAMがあり、サーバーの最大メモリを15 GBに設定しています。残念ながら、1 GBはオペレーティングシステム(およびバックアップソフトウェアやSSMSのようなそこで実行する他のすべてのもの)のために十分に残されていません。SQLServerセットアップガイドでは、4 GBまたは10%の空き容量を残しておくことをお勧めしますより大きい-あなたの場合、それは4GBになるので、最大サーバーメモリ設定は15GBではなく12GBでなければなりません。

現在のメモリ割り当てにより多くの証拠が表示されます。メモリ内のページのロック(LPIM)がオンになっていますが、メモリ内でロックされているページは12.02GBしかありません。その可能性は高いですが(保証はされません)、他のアプリケーションがメモリを必要としたため、Windowsがメモリ不足の通知を送信し、SQL Serverは他の3 GBのメモリをあきらめて、他のアプリケーションが処理できるようにしました。これは、15 GBの最大値では十分に対応できないことを示す証拠です。他のものにメモリが必要です。

SQL Serverがその外部メモリのプレッシャーにさらされ、他のアプリのためにメモリを解放する必要がある場合、プランキャッシュが影響を受けます。

したがって、いくつかのオプションがあります。

  • 最大メモリを適切に設定します-たとえば、12GB(または、他のものを実行する場合はさらに小さくします)サーバー上のアプリ。)そのようにすれば、他のアプリが2〜3 GBのRAM-を必要とするからといって、SQL Serverがメモリに火をつけてフラッシュアウトする必要はありませんすでに利用可能です
  • サーバー上で他のアプリの実行を停止します-他のシステム管理者がリモートデスクトップを実行している場合、これは難しい場合がありますSSMSのようなものです。開いているRDPセッションの数に対してPerfmonカウンターアラームを設定し、それが0以外のときにアラートを出しました。これは、犯人の行動をとらえるのに役立ちます。
  • VMにメモリを追加します-しかし、本当にそれが必要だとは思いません。 「重要な待機が検出されなかった」というsp_Blitzレポートによっていくつかの証拠が示されています。特にそれがたまにしか起こらないと報告しているので、あなたは頻繁なメモリのプレッシャーにさらされているとは思いません。これは最も費用対効果の低いオプションです。
28
Brent Ozar

私は自宅のテストボックスでこの問題を抱えていて、SQL Serverサービスアカウントに「メモリ内のページのロック」権限を追加することで問題が解決することを知りましたが、これが最善のアドバイスであるかどうかはわかりません。

参照 メモリ内のページのロックオプションを有効にする(Windows)

1
MrKudz