SQL Serverに使用可能な物理メモリが残っていない場合はどうなりますか?


16

グーグル検索中に、矛盾する情報を見つけました。

一部のサイトでは、データ用の物理メモリが残っていない場合、SQL Serverは既存のデータをTEMPDBに移動すると述べていますSQL Server:TempDbの説明と推奨事項を参照)。

しかし、他のサイトでは、十分な物理メモリが残っていない場合、オペレーティングシステムがPAGE FILEを使用して物理メモリからデータをそこに移動できると述べています(SQL Serverのページファイルを参照)。

SQL Serverが物理メモリを使い果たしたときにデータを書き込む場所はどこでしょうか?tempdbまたはOSページファイルに?それとも両方とも?

回答:


28

データ用の物理メモリが残っていない場合、SQL Serverは既存のデータをTEMPDBに移動します

リンクした記事はせいぜい誤解を招くだけで、一部の場所では間違っています。著者は、いくつかの複雑なことを単純化し過ぎていたと思います。

SQL Serverは、データをメモリ(バッファープール)からtempdbにそのように移動しません。「最も最近使用されていない」キャッシング戦略(一般的に)を使用しているため、メモリのプレッシャーがあり、新しいデータをメモリに取り込む必要がある場合、SQL Serverは新しいデータに対応するためにバッファプールからLRUデータを追い出します。この動作は、多くの場合「Page Life Expectancy」(PLE)と呼ばれるperfmonカウンターによって監視されます。

PLEの定義は、バッファプール(データファイルページのメモリ内キャッシュ)に読み込まれたデータファイルページがメモリに残り、別のデータ用のスペースを確保するまでの予想時間(秒単位)です。ファイルページ。PLEを考えるもう1つの方法は、ディスクから読み取られるページの空きスペースを確保するためのバッファープールの圧力を瞬時に測定することです。これらの定義の両方について、数値が大きいほど優れています。

クエリの実行中、SQL Server 特定の操作にtempdbを使用できます。これは通常、見積もりが悪い場合に行われますが、使用可能なメモリが少ないとこの動作に影響する可能性があります。

この方法でtempdbに "流出"できる操作には、行のハッシュ(結合または集計など)、メモリ内の行の並べ替え、並列クエリ実行中の行のバッファリングなどがあります。

ユーザークエリは、明示的にtempdb(グローバルまたはローカルの一時テーブル)を使用し、暗黙的にtempdb(スナップショットまたは読み取りコミットスナップショット分離レベル)を使用することもできます。

これらの状況のどちらも、あなたが引用したステートメントに実際には当てはまらないようです。

十分な物理メモリが残っていない場合、オペレーティングシステムはページファイルを使用して、物理メモリからデータをそこに移動できます。

これは間違いなく発生する可能性があり、ほとんどの場合、SQL Serverの制御外です。いくつかの種類のOSレベルのページング、つまり「メモリ内のページのロック」(LPIM)を防ぐために回すことができるノブがあります。

このWindowsポリシーは、どのアカウントがプロセスを使用して物理メモリにデータを保持できるかを決定し、システムがディスク上の仮想メモリにデータをページングするのを防ぎます。

それでは、ディスクにページングされるのを防ぐことができますか?

SQL Server 2012より前は、「シングルページアロケーター」と呼ばれるコンポーネントを介して割り当てられたページはメモリ内でロックされていました(ページングできませんでした)。これには、バッファプール(データベースページ)、プロシージャキャッシュ、およびその他のメモリ領域が含まれていました。

参照ロックされたページとの楽しい、AWE、タスクマネージャ、およびワーキングセット...詳細については、特にセクション「正確に何がロックされ、? 『ロックされたページを』 4.今、私はx64の上でSQL Serverのことを知っているでは使用することができます」その他の関連資料については、SQL Serverに関する優れた議論:メモリ内のページのロックを参照してください。

SQL Server 2012以降には、「シングルページアロケーター」はありません(メモリの詳細な調査-SQL Server 2012/2014に従って、シングルページアロケーターとマルチページアロケーターがマージされました)。ページングできるものとできないものの詳細は、私が見たどこにも詳細に文書化されていません。クエリを使用することができ、このようにものを見るためにされてロックされました:

select osn.node_id, osn.memory_node_id, osn.node_state_desc, omn.locked_page_allocations_kb
from sys.dm_os_memory_nodes omn
inner join sys.dm_os_nodes osn on (omn.memory_node_id = osn.memory_node_id)
where osn.node_state_desc <> 'ONLINE DAC'

同じMSサポート記事に従って、DBCC MEMORYSTATUS「ロックされている」メモリの量を確認することもできます。

補足説明として、SQL ServerのワーキングセットがOSによってページングされている証拠をエラーログで確認できます。次のようなメッセージが表示されます。

2019-09-02 10:19:27.29 spid11s SQLサーバープロセスメモリのかなりの部分がページアウトされました。これにより、パフォーマンスが低下する可能性があります。期間:329秒。ワーキングセット(KB):68780、コミット済み(KB):244052、メモリ使用率:28%。


0

SQL Serverの最新バージョンでは、完全にハングアップする可能性はほとんどありません。SQL Serverは、.NET Frameworkをそのアドレススペースにロードし、通常の操作で使用します。物理メモリとページファイルの両方がなくなると、Windowsはページファイルを拡大しようとします。ただし、ページファイルを拡大できる場合でも、これは瞬間的な操作ではなく、ページファイルの拡大中にメモリの割り当ては失敗します。APC通知に応答してメモリを割り当てる.NET非同期I / Oハンドラーにはバグがあります。への呼び出しがnew失敗すると、スローされますOutOfMemoryException。この例外は、タスクスケジューラ内のネイティブコードでキャッチされます。ただし、非同期I / Oは終了しないように見えます。FileStreamのファイナライザスレッドは、I / Oが終了するのを待ってブロックし、バッファの固定を解除して、ファイナライザスレッドを永久にハングアップさせます。これにより、.NET Frameworkは割り当てられるメモリがなくなるまで徐々にメモリを使い果たします。この時点でwinsockはバッファを割り当てることができず、管理者アクセス接続も役に立たないため、SQLサーバーは応答しなくなります。

メモリ不足のため、.NETアプリケーションで実際にタスクスケジューラの合計ハングアップが発生しました。ありがたいことに、プロセスはOutOfMemoryException、いくつかの失敗の後にそれをキャッチしなかったスレッドをスローしたために最終的に停止しました。

探しているものがわかれば、静的解析のバグを見つけるのは簡単でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.