メモリ管理アーキテクチャ ガイド

適用対象:yesSQL Server Analytics Platform System (PDW) YesYesAzure SQL Database Azure SQL Managed Instance yesyesAzure Synapse Analytics (すべてのサポートされているバージョン)

Windows 仮想メモリ マネージャー

Windows 仮想メモリ マネージャー (VMM) は、使用可能な物理メモリにコミット済みのアドレス空間をマップします。

さまざまなオペレーティング システムでサポートされている物理メモリ量の詳細については、Windows のマニュアルの「Windows のリリース別のメモリ制限」を参照してください。

仮想メモリ システムでは、仮想メモリと物理メモリの比率が 1:1 を超えるような物理メモリの設定を許可しています。 その結果、さまざまな物理メモリ構成のコンピューターで大規模なプログラムを実行できます。 しかし、すべてのプロセスの平均ワーキング セットを合わせた容量よりもはるかに大きな仮想メモリを使用すると、パフォーマンスが低下する可能性があります。

SQL Server のメモリ アーキテクチャ

SQL Server では、メモリの確保と解放が必要に応じて動的に行われます。 通常、管理者が SQL Server に割り当てるメモリ量を指定する必要はありませんが、このオプションは一部の環境で必要になるので存在しています。

ディスクの読み書きはコンピューター操作の中でも特にリソースを消費するので、どのようなデータベース ソフトウェアでも、ディスク I/O を最小限に抑えることを主な設計目標としています。 SQL Server では、データベースから読み取ったページを保持するバッファー プールがメモリ内に構築されます。 SQL Server のコードの大部分はディスクとバッファー プールの間の物理的な読み書きの回数が最も少なくなるように記述されています。 SQL Server では次の 2 つの目標のバランスを取ることを目指しています。

  • システム全体のメモリ不足を防ぐため、バッファー プールが大きくなりすぎないようにする。
  • バッファー プールのサイズを最大にして、データベース ファイルの物理 I/O を最小限に抑える。

Note

負荷の高いシステムでは、実行に大量のメモリを必要とする大きなクエリが必要最低限のメモリ量を確保できず、メモリ リソースの待機中にタイムアウト エラーが発生することがあります。 これを解決するには、 query wait オプションの値を増やします。 並列クエリの場合は、 max degree of parallelism オプションの値を減らすことを検討してください。

Note

メモリ不足で負荷の高いシステムでは、クエリ プランにマージ結合、並べ替え、およびビットマップを使用したクエリが含まれていると、クエリがビットマップに必要な最低限のメモリ量を確保できなかった場合に、ビットマップが削除されることがあります。 この動作がクエリのパフォーマンスに影響を与える場合があります。そのために並べ替え処理がメモリに収まらなくなったときに、tempdb データベース内の作業テーブルの使用率が増加し、tempdb データベースのサイズが大きくなります。 この問題を解決するには、物理メモリを追加するか、より実行速度の速い別のクエリ プランを使用するようにクエリをチューニングします。

SQL Server に対する最大メモリ容量の指定

AWE および Locked Pages in Memory 特権を使用して、SQL Server データベース エンジン に次の容量のメモリを指定できます。

Note

次の表には、現在利用できない 32 ビット バージョンの列が含まれています。

メモリ ポリシー 32 ビット 1 64 ビット
コンベンショナル メモリ すべてのSQL Serverエディション。 プロセス仮想アドレス空間制限まで:
- 2 GB
- 3 GB (/3 gb のブート パラメーターを使用する場合) 2
- 4 GB (WOW64 の場合) 3
すべてのSQL Serverエディション。 プロセス仮想アドレス空間制限まで:
- IA64 アーキテクチャを使用した 7 TB (SQL Server 2012 (11.x) 以上ではサポートされていません)
- オペレーティング システムの最大容量 (x64 アーキテクチャを使用する場合) 4
AWE メカニズム (SQL Server で 32 ビット プラットフォームのプロセス仮想アドレス空間制限を超えることを許可する) SQL Server Standard、Enterprise、および Developer エディション: バッファー プールは、最大 64 GB のメモリにアクセスできます。 該当なし 5
Lock Pages in Memory オペレーティング システム (OS) 特権 (物理メモリのロックを許可し、ロックされたメモリの OS ページングを回避する) 6 SQL Server Standard、Enterprise、および Developer エディション: AWE メカニズムを使用する SQL Server プロセスで必要です。 AWE メカニズムによって割り当てられたメモリは、ページ アウトできません。
AWE を有効にせずにこの特権を許可しても、サーバーに対する影響はありません。
必要なときにのみ、具体的には、sqlservr プロセスがページ アウトされているという兆候があるときにのみ使用します。その場合、次のようなエラー 17890 がエラー ログに報告されます。A significant part of sql server process memory has been paged out. This may result in a performance degradation. Duration: #### seconds. Working set (KB): ####, committed (KB): ####, memory utilization: ##%.

2014 年 (12.x) から 1 SQL Server 32 ビット バージョンを使用できません。
2 /3gb は、オペレーティング システムのブート パラメーターです。
3 WOW64 (Windows Windows 64) は、32 ビット SQL Server が 64 ビット オペレーティング システムで実行されるモードです。
4 SQL Server Standard Edition では、最大 128 GB がサポートされます。 SQL Server Enterprise Edition では、オペレーティング システムの最大値がサポートされます。
5 64 ビット sp_configure有効にしたオプションが 64 ビットの場合SQL Serverが無視されます。
6 Lock Pages in Memory (LPIM) 特権が許可されている (AWE サポートの場合は 32 ビット、AWE そのものでは 64 ビットで) 場合は、サーバーの最大メモリも設定することをお勧めします。 LPIM の詳細については、「サーバー メモリに関するサーバー構成オプション」を参照してください

Note

32 ビット オペレーティング システム上では、古いバージョンの SQL Server を実行できます。 32 ビットのオペレーティング システム上で 4 ギガバイト (GB) を超えるメモリにアクセスするには、Address Windowing Extensions (AWE) がメモリを管理する必要がありました。 これは、64 ビット オペレーティング システムで SQL Server を実行するときには必要ありません。 AWE の詳細については、SQL Server 2008 ドキュメントの「プロセス アドレス空間」および「大規模データベースのメモリ管理」を参照してください。

SQL Server 2012 (11.x) から始まるメモリ管理の変更

以前のバージョンの SQL Server ( SQL Server 2005 (9.x)、SQL Server 2008 および SQL Server 2008 R2) では、次の 5 つの異なるメカニズムを使用してメモリ割り当てが実行されました。

  • シングルページ アロケーター (SPA) (メモリ割り当て量が 8 KB 以下のメモリ割り当てのみを含む) は、SQL Serverされます。 構成オプションの max server memory (MB)min server memory (MB) によって、SPA が利用する物理メモリの上限が決められていました。 同時にバッファー プールが SPA のメカニズムであり、これが単一ページ割り当てを最も多く利用していました。
  • MPA (Multi-Page Allocator/複数ページ アロケータ) 。8 KB より多くを要求するメモリ割り当て用。
  • CLR アロケータ。CLR 初期化中に作成される SQL CLR ヒープとそのグローバル割り当てを含む。
  • プロセス内のスレッド スタックに対するメモリSQL Server割り当て。
  • DWA (Direct Windows allocations/直接 Windows 割り当て) 。Windows に直接行われるメモリ割り当て要求。 これには、Windowsに読み込まれるモジュールによって行われた直接仮想割り当てと、ヒープの使用量SQL Serverがあります。 このようなメモリ割り当ての例としては、たとえば、拡張ストアド プロシージャ DLL からの割り当て、オートメーション プロシージャ (sp_OA 呼び出し) で作成されたオブジェクト、リンク サーバー プロバイダーからの割り当てがあります。

SQL Server 2012 (11.x)、Single-Page 割り当て、マルチページ割り当て、CLR 割り当てはすべて "任意のサイズ" ページ アロケーターに統合され、最大サーバー メモリ (MB) および最小サーバー メモリ (MB) 構成オプションによって制御されるメモリ制限に含まれます。 この変更により、メモリ マネージャーで使用されるすべてのメモリ要件に対して、より正確なサイズSQL Serverが提供されます。

重要

SQL Server 2012 (11.x) から SQL Server 2019 (15.x) にアップグレードした後、現在の最大サーバー メモリ (MB) と最小サーバー メモリ (MB) の構成を慎重に確認します。 これは、SQL Server 2012 (11.x) から、このような構成には以前のバージョンと比較してより多くのメモリ割り当てが含まれるためです。 これらの変更は、SQL Server 2012 (11.x) と SQL Server 2014 (12.x) の 32 ビット バージョンと 64 ビット バージョン、および SQL Server 2016 (13.x) から SQL Server 2019 (15.x) の 64 ビット バージョンの両方に適用されます。

次の表は、メモリ割り当ての種類とそれを制御する構成オプションである max server memory (MB)min server memory (MB) についてまとめたものです。

メモリ割り当ての種類 SQL Server 2005 (9.x)、SQL Server 2008 および SQL Server 2008 R2 SQL Server 2012 (11.x) から
単一ページ割り当て はい はい。"あらゆるサイズの" ページ割り当てに統合。
複数ページ割り当て いいえ はい。"あらゆるサイズの" ページ割り当てに統合。
CLR 割り当て いいえ はい
スレッド スタック メモリ いいえ いいえ
Windows からの直接割り当て いいえ いいえ

SQL Server 2012 (2.x) 以降、SQL Server では max Server memory 設定で指定された値よりも多くのメモリが割り当てられる可能性があります。 そのような動作は、Total Server Memory (KB) の値が (max server memory によって指定される) Target Server Memory (KB) の設定に既に到達しているときに発生することがあります。 メモリの断片化のために、連続した空きメモリが不足しているために、複数ページのメモリ要求 (8 KB 以上) を満たすことができない場合、SQL Server はメモリ要求を拒否するのではなく、オーバーコミットを実行できます。

この割り当ての実行直後、バックグラウンド タスクのリソース モニターがすべてのメモリ コンシューマーに信号を送り、割り当てられているメモリの解放を求め、Total Server Memory (KB)Target Server Memory (KB) 仕様を下回るようにします。 そのため、SQL Server メモリ使用量が、最大サーバーメモリ設定を短時間で超える可能性があります。 このような状況では、Total Server Memory (KB) パフォーマンス カウンター読み取り値が max server memory 設定と Target Server Memory (KB) 設定を超えます。

この動作は通常、次の操作中に観察されます。

  • 大規模な列ストア インデックス クエリ。
  • 大規模な行ストアでのバッチ モード クエリ。
  • 列ストア インデックスの (再) ビルド。大量のメモリを使用し、ハッシュ操作とソート操作を実行します。
  • 大量のメモリ バッファーを必要とするバックアップ操作。
  • 大量の入力パラメーターを格納する必要があるトレース操作。

SQL Server 2012 (2.x) 以降の "memory_to_reserve" への変更

以前のバージョンの SQL Server (SQL Server 2005 (1.x)、SQL Server 2008、および SQL Server 2008 R2) では、SQL Server memory manager によって、マルチページアロケーター (MPA)CLR アロケータースレッドスタックのメモリ割り当てによって使用されるプロセス仮想アドレス空間 (VAS) の一部が確保されていました。 SQL Server プロセスでは、とに直接 Windows 割り当て (dwa)があります。 仮想アドレス空間のこの部分は、"Mem-To-Leave" または "non-Buffer Pool" 領域とも呼ばれています。

これらの割り当て用に予約されている仮想アドレス空間は、 memory_to_reserve 構成オプションによって決まります。 SQL Server 使用される既定値は 256 MB です。 既定値をオーバーライドするには、SQL Server -g startup パラメーターを使用します。 スタートアップ パラメーター -g の詳細については、ドキュメント ページの「データベース エンジン サービスのスタートアップ オプション」を参照してください。

SQL Server 2012 (2.x) 以降では、新しい "任意のサイズ" のページアロケーターも 8 KB を超える割り当てを処理します。 memory_to_reserveの値には複数ページの割り当ては含まれません。 この変更を除き、他のすべてはこの構成オプションと引き続き同じになります。

次の表は、特定の種類のメモリ割り当てが SQL Server プロセス用の仮想アドレス空間のmemory_to_reserve領域に含まれるかどうかを示しています。

メモリ割り当ての種類 SQL Server 2005 (1.x)、SQL Server 2008、SQL Server 2008 R2 SQL Server 2012 (2.x) 以降
単一ページ割り当て いいえ いいえ。"あらゆるサイズの" ページ割り当てに統合。
複数ページ割り当て はい いいえ。"あらゆるサイズの" ページ割り当てに統合。
CLR 割り当て はい はい
スレッド スタック メモリ はい はい
Windows からの直接割り当て はい はい

動的メモリ管理

SQL Server データベースエンジンの既定のメモリ管理動作では、システムのメモリ不足を生じることなく、必要な量のメモリを取得します。 SQL Server データベースエンジンは、Microsoft Windows のメモリ通知 api を使用してこれを行います。

メモリを動的に使用している SQL Server は、システムに定期的にクエリを行い、空きメモリ容量を判断します。 このようにメモリの空き容量を維持することによって、オペレーティング システム (OS) のページングが防止されます。 メモリが不足している場合は、SQL Server によって OS にメモリが解放されます。 メモリが不足している場合は、SQL Server によってより多くのメモリが割り当てられる可能性があります。 SQL Server は、そのワークロードに必要なメモリが多い場合にのみメモリを追加します。保存しているサーバーは、仮想アドレス空間のサイズを大きくしません。

Max server memory SQL Server は、メモリの割り当て、コンパイルメモリ、すべてのキャッシュ (バッファープールを含む)、クエリ実行メモリの許可ロックマネージャーのメモリ、CLR1メモリ (基本的にsys.dm_os_memory_clerksで見つかったメモリクラーク) を制御します。

1 CLR メモリは、SQL Server 2012 (2.x) 以降の max_server_memory 割り当てで管理されます。

次のクエリでは、現在割り当てられているメモリに関する情報を返します。

SELECT 
  physical_memory_in_use_kb/1024 AS sql_physical_memory_in_use_MB, 
	large_page_allocations_kb/1024 AS sql_large_page_allocations_MB, 
	locked_page_allocations_kb/1024 AS sql_locked_page_allocations_MB,
	virtual_address_space_reserved_kb/1024 AS sql_VAS_reserved_MB, 
	virtual_address_space_committed_kb/1024 AS sql_VAS_committed_MB, 
	virtual_address_space_available_kb/1024 AS sql_VAS_available_MB,
	page_fault_count AS sql_page_fault_count,
	memory_utilization_percentage AS sql_memory_utilization_percentage, 
	process_physical_memory_low AS sql_process_physical_memory_low, 
	process_virtual_memory_low AS sql_process_virtual_memory_low
FROM sys.dm_os_process_memory;  

スレッドスタック、CLR2、拡張プロシージャ .dll ファイル、分散クエリによって参照される OLE DB プロバイダー、transact-sql SQL ステートメントで参照されるオートメーションオブジェクト、および非 SQL Server DLL によって割り当てられるメモリは、max Server memory によって制御されません

1 現在のホストで関連付けられている所与の CPU 数に対して計算される既定のワーカー スレッドについては、ドキュメント ページの「max worker threads サーバー構成オプションの構成」を参照してください。 SQL Server スタックサイズは次のとおりです。

SQL Server アーキテクチャ OS アーキテクチャ スタック サイズ
x86 (32 ビット) x86 (32 ビット) 512 KB
x86 (32 ビット) x64 (64 ビット) 768 KB
x64 (64 ビット) x64 (64 ビット) 2048 KB
IA64 (Itanium) IA64 (Itanium) 4096 KB

2 CLR メモリは、SQL Server 2012 (2.x) 以降の max_server_memory 割り当てで管理されます。

SQL Server は、メモリ通知 API QueryMemoryResourceNotificationを使用して、SQL Server メモリマネージャーがメモリを割り当て、メモリを解放するタイミングを判断します。

SQL Server を起動すると、システムの物理メモリの量、サーバー スレッドの数、さまざまな起動パラメーターなど、数多くのパラメーターに基づいてバッファー プール用の仮想アドレス空間のサイズが計算されます。 SQL Server では、計算された量のプロセス仮想アドレス空間をバッファー プール用に予約しますが、現在の負荷に必要な量だけ物理メモリを獲得 (コミット) します。

インスタンスでは、ワークロードのサポートに必要なメモリを獲得し続けます。 より多くのユーザーが接続してクエリを実行すると、SQL Server は必要に応じてより多くの物理メモリを獲得します。 SQL Server インスタンスは、max server memory allocation ターゲットに到達するか、os が空きメモリが不足していることを示していない場合、または os によって空きメモリが不足していることが示されるまで、物理メモリを取得し続けます。また、min Server memory 設定よりも多くのメモリがあることを os が示します。

SQL Server のインスタンスが動作しているコンピューター上で他のアプリケーションを起動すると、メモリを消費し、物理メモリの空き領域が SQL Server の目標よりも少なくなります。 SQL Server のインスタンスでは、メモリの消費を調整します。 他のアプリケーションが停止され、使用可能なメモリが増えると、SQL Server のインスタンスはメモリ割り当てのサイズを大きくします。 SQL Server は、数 MB のメモリの解放および獲得を毎秒行うことができるため、メモリ割り当ての変更に迅速に対応できます。

最小および最大サーバー メモリの効果

min server memoryおよびmax server memory構成オプションは、バッファープールおよびその他のデータベースエンジンのキャッシュによって使用されるメモリの量に上限と下限を設定します。 バッファー プールは、min server memory に指定されたメモリ容量をすぐには獲得しません。 バッファー プールは、初期化に必要なメモリのみで起動します。 SQL Server データベースエンジンワークロードの増加に応じて、ワークロードをサポートするために必要なメモリを獲得し続けます。 バッファー プールは、min server memory で指定しされたメモリ容量に達するまでは獲得したメモリを解放しません。 メモリ容量が min server memory に達すると、バッファー プールは標準アルゴリズムを使用して、必要に応じてメモリ容量を獲得または解放します。 唯一の違いは、バッファー プールはそのメモリ割り当てを min server memory の値より少ないメモリ容量にはせず、max server memory の値より多いメモリ容量は獲得しないということです。

Note

プロセスとしての SQL Server は、max server memory オプションで指定された容量を超えるメモリを獲得します。 内部コンポーネントと外部コンポーネントの両方で、バッファープール外にメモリを割り当てることができます。これにより、追加のメモリが消費されますが、通常、バッファープールに割り当てられるメモリは、SQL Server によって消費されるメモリの最大部分を表します。

SQL Server データベースエンジンによって取得されるメモリの量は、インスタンスに配置されたワークロードに完全に依存します。 あまり多くの要求を処理しない SQL Server のインスタンスでは、まったく min server memory に達しないこともあります。

min server memory と max server memory の両方に同じ値を指定した場合、SQL Server データベースエンジンに割り当てられたメモリがその値に達すると、SQL Server データベースエンジンはバッファープールに対するメモリの動的な解放と取得を停止します。

他のアプリケーションが頻繁に停止または起動されるコンピューター上で SQL Server のインスタンスが動作している場合、SQL Server のインスタンスによるメモリの割り当てと解放により、他のアプリケーションの起動時間が遅くなることがあります。 SQL Server が、1 つのコンピューター上で動作している複数のサーバー アプリケーションのうちの 1 つであるときも、SQL Server に割り当てるメモリ量をシステム管理者が制御しなければならない場合があります。 このような場合には、min server memory オプションと max server memory オプションを使用して、SQL Server が使用するメモリ量を制御できます。 min server memorymax server memory は MB 単位で指定されます。 これらのメモリ構成の設定方法に関する推奨事項などの詳細については、「サーバー メモリの構成オプション」を参照してください。

SQL Server オブジェクトの仕様で使用されるメモリ

次の一覧で、SQL Server の各オブジェクトによって使用されるおおよそのメモリ量について説明します。 表示されている金額は概算であり、環境とオブジェクトの作成方法によって異なります。

  • ロック (ロック マネージャーにより保守管理):64 バイト + (32 バイト * 所有者数)
  • ユーザー接続: 約 (3 * network_packet_size + 94 kb)

ネットワーク パケット サイズは、アプリケーションとアプリケーション間の通信に使用される表形式データ ストリーム (TDS) パケットのサイズデータベース エンジン。 既定のパケット サイズは 4 KB であり、network packet size 構成オプションによって制御されます。

複数のアクティブな結果セット (MARS) が有効になっている場合、ユーザー接続で使用されるメモリは約 (3 + 3 * num_logical_connections) * network_packet_size + 94 KB です。

min memory per query の効果

min memory per query 構成オプションでは、クエリの実行用に割り当てる最小メモリ容量 (KB 単位) を確定します。 これは、最小メモリ許可とも呼ばれます。 すべてのクエリは、実行を開始するためには、要求された最小メモリをセキュリティで保護できるようになるまで、または query wait サーバー構成オプションで指定された値を超えるまで、待機する必要があります。 このシナリオで累積される待機の種類は、RESOURCE_SEMAPHORE です。

重要

稼働率が非常に高いシステムでは特に、min memory per query サーバー構成オプションの値を高く設定しすぎないでください。そうしないと、次の状況を招く可能性があります。

  • メモリ リソースの競合が増加します。
  • 実行時に必要なメモリがこの構成より少ない場合でも、すべての単一クエリのメモリ量を増やすことで、コンカレンシーが低下します。

この構成の使い方の推奨事項については、「min memory per query サーバー構成オプションの構成」を参照してください。

メモリ許可に関する考慮事項

行モード実行の場合は、いかなる状況でも初期のメモリ許可を超過することはありません。 ハッシュ操作または並べ替え操作を実行するために、初期のメモリ許可より多くのメモリを必要とする場合、ディスクへの書き込みが行われます。 ハッシュ操作では TempDB 内の作業ファイルによって書き込みがサポートされます。一方、並べ替え操作では作業テーブルによって書き込みがサポートされます。

並べ替え操作中に発生する書き込みは、並べ替えの警告と呼ばれています。 並べ替えの警告は、並べ替え操作がメモリに収まらないことを示します。 インデックスの作成に関連する並べ替え操作は対象になりません。SELECT ステートメントで使用される ORDER BY 句などのクエリ内の並べ替え操作のみが対象になります。

ハッシュ操作中に発生する書き込みは、ハッシュの警告と呼ばれています。 これらは、ハッシュ演算中にハッシュの再帰またはハッシュの中断 (ハッシュの保留) が生じたときに発生します。

  • 使用できるメモリ内にビルド入力が収まらないときに、ハッシュの再帰が発生します。その結果、入力が複数のパーティションに分割され、個別に処理されます。 複数のパーティションに分割されても使用できるメモリ内に収まらない場合は、さらにサブパーティションに分割され、個別に処理されます。 この分割プロセスは、使用できるメモリ内に各パーティションが収まるようになるまで、または最大再帰レベルに到達するまで続きます。
  • ハッシュ演算が最大再帰レベルに到達するとハッシュの保留が発生し、パーティション分割された残りのデータを処理するための代替プランに移行されます。 これらのイベントが原因となって、サーバー内のパフォーマンスが低下する可能性があります。

バッチ モード実行の場合、初期のメモリ許可は既定では特定の内部しきい値まで動的に増加することができます。 この動的なメモリ許可メカニズムは、バッチ モードで実行されているハッシュまたは並べ替え操作のメモリ常駐実行を可能にするように設計されています。 これらの操作がまだメモリ内に収まらない場合は、ディスクへの書き込みが行われます。

実行モードの詳細については、「クエリ処理アーキテクチャ ガイド」を参照してください。

バッファー管理

SQL Server データベースの主な目的はデータの格納と取得であるため、データベース エンジンの主要な特性は頻繁なディスク I/O ということになります。 ディスク I/O 操作は多くのリソースを消費するうえ、完了するのに比較的長い時間がかかるので、SQL Server では I/O の効率を上げることに重点を置いています。 バッファー管理は、この効率向上を実現するための重要なコンポーネントです。 バッファー管理コンポーネントは 2 つのメカニズムから構成されています。1 つはデータベース ページに対するアクセスと更新を行うバッファー マネージャーで、もう 1 つはデータベース ファイルの I/O を削減するバッファー キャッシュ (バッファー プール) です。

バッファー管理のしくみ

バッファーはメモリ内の 8 KB のページで、データ ページやインデックス ページと同じサイズです。 したがって、バッファー キャッシュは 8 KB 単位のページに分割されます。 バッファー マネージャーは、データベース ディスク ファイルのデータ ページやインデックス ページをバッファー キャッシュに読み取って、変更されたページをディスクに書き戻すための機能を管理しています。 バッファー マネージャーが別のデータを読み取るためのバッファー領域を必要とするまで、そのページはバッファー キャッシュ内に残ります。 データに変更が加えられた場合だけ、そのデータがディスクに書き戻されます。 バッファー キャッシュ内のデータは、ディスクに書き戻す前に何度でも変更できます。 詳細については、「 ページの読み取り 」および「 ページの書き込み」をご覧ください。

SQL Server を起動すると、システムの物理メモリの量、構成されるサーバー スレッドの最大数、さまざまな起動パラメーターなど、数多くのパラメーターに基づいてバッファー キャッシュ用の仮想アドレス空間のサイズが計算されます。 SQL Server では、この計算された量のプロセス仮想アドレス空間 (メモリ ターゲット) をバッファー キャッシュ用に予約しますが、現在の負荷に必要な量だけ物理メモリを獲得 (コミット) します。 sys.dm_os_sys_info カタログ ビューの committed_target_kbcommitted_kb の列に対してクエリを実行すると、メモリ ターゲットとして予約されているページ数と、バッファー キャッシュ内で現在コミットされているページ数をそれぞれ返すことができます。

SQL Server の起動からバッファー キャッシュがメモリ ターゲットを取得するまでの間隔を、割り当て増加といいます。 この間、読み取り要求によって、必要に応じてバッファーが使用されます。 たとえば、1 ページ 8 KB の読み取り要求では、1 つのバッファー ページが使用されます。 つまり、割り当て増加は、クライアント要求の数や種類によって異なります。 1 ページずつの読み取り要求を 8 ページ分の要求にまとめて変換することで (1 つのエクステントとします)、割り当て増加を高速化しています。 これにより、特に多くのメモリが搭載されたコンピューターでは、割り当て増加が非常に高速に完了します。 ページとエクステントの詳細については、「ページとエクステントのアーキテクチャ ガイド」を参照してください。

バッファー マネージャーはほとんどのメモリを SQL Server プロセスで使用するので、メモリ マネージャーと連携して他のコンポーネントでバッファーを使用できるようにします。 バッファー マネージャーは主に次のコンポーネントと対話します。

  • リソース マネージャー。全体的なメモリ使用量を制御します。32 ビット プラットフォームではアドレス空間の使用量を制御します。
  • データベース マネージャーと SQL Serverオペレーティング システム (SQLOS) を使用して、低レベルのファイル I/O 操作を実行できます。
  • ログ マネージャー。先行書き込みログ記録を行います。

サポートされている機能

バッファー マネージャーは、次の機能をサポートしています。

  • NUMA (non-uniform memory access) に対応しています。 バッファー キャッシュ ページはハードウェア NUMA ノード間に分散されます。そのため、スレッドは外部メモリからではなく、ローカルの NUMA ノードに割り当てられているバッファー ページにアクセスすることができます。

  • ホット アド メモリをサポートしています。そのため、ユーザーはサーバーを再起動することなく物理メモリを追加できます。

  • 64 ビット プラットフォームの大きなページをサポートしています。 ページのサイズは、Windows のバージョンに固有です。

    Note

    2012 SQL Server (11.x) より前では、SQL Server で大きなページを有効にする場合は、トレース フラグ 834 が必要です。

  • バッファー マネージャーは、動的管理ビューによって公開される追加の診断情報を提供します。 これらのビューを使用して、SQL Server に固有のさまざまなオペレーティング システム リソースを監視できます。 たとえば、sys.dm_os_buffer_descriptors ビューを使用すると、バッファー キャッシュ内のページを監視できます。

ディスク I/O

バッファー マネージャーはデータベースの読み取りと書き込みだけを行います。 他のファイル操作やデータベース操作 (開く、閉じる、拡張、圧縮など) は、データベース マネージャー コンポーネントおよびファイル マネージャー コンポーネントによって実行されます。

バッファー マネージャーによるディスク I/O 操作には、次の特性があります。

  • すべての I/O は非同期で実行されます。つまり、呼び出し側スレッドでの処理中でも、I/O 操作はバックグラウンドで進行します。
  • affinity I/O オプションが使用されていない限り、すべての I/O は呼び出し元のスレッドで発行されます。 affinity I/O mask オプションでは、SQL Server のディスク I/O が、指定した CPU のサブセットに関連付けられます。 ハイエンドな SQL Server オンライン トランザクション処理 (OLTP) 環境では、この拡張機能により、I/O を発行する SQL Server スレッドのパフォーマンスを向上できます。
  • 複数ページの I/O は、スキャッター/ギャザー I/O を使用して実行されます。スキャッター/ギャザー I/O を使用すると、連続しないメモリ領域との間でデータを転送できます。 つまり、SQL Server は、複数の物理 I/O 要求を回避しながら、バッファー キャッシュをすばやく使用またはフラッシュできます。

実行時間の長い I/O 要求

バッファー マネージャーは未処理状態が 15 秒以上続いた I/O 要求を報告します。 これはシステム管理者が SQL Server の問題か I/O サブシステムの問題かを区別するのに役立ちます。 SQL Server のエラー ログには、次のようなエラー メッセージ 833 が報告および記録されます。

SQL Server has encountered ## occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [##] in database [##] (#). The OS file handle is 0x00000. The offset of the latest long I/O is: 0x00000.

実行時間の長い I/O は読み取りまたは書き込みのどちらかの処理ですが、どちらの処理なのかはメッセージに示されません。 実行時間の長い I/O のメッセージは、警告であってエラーではありません。 これらは、基になる I/O システムSQL Server問題を示すのではなく、問題を示します。 これらのメッセージが報告されることにより、システム管理者は、SQL Server の応答時間が遅い原因を追究したり、SQL Server の制御の範囲外にある問題を見分けたりするのに役立てることができます。 このように、メッセージに対するアクションは不要ですが、システム管理者は I/O 要求が長時間かかっている理由や、かかっている時間が正当であるかどうかを調べる必要があります。

実行時間の長い I/O 要求の原因

実行時間の長い I/O のメッセージは、I/O が永続的にブロックされていて決して完了しないこと (ロスト I/O ともいいます) を示す場合があります。また、I/O が単純にまだ完了していないことを示す場合があります。 この場合、どちらのシナリオなのかをメッセージから区別することはできません。ただ、ロスト I/O の結果、ラッチ タイムアウトが生じることがよくあります。

多くの場合、実行時間の長い I/O は、SQL Server のワークロードによってディスク サブシステムに過度の負荷がかかっていることを示します。 ディスク サブシステムが不十分だと、次の現象が発生することがあります。

  • 負荷の高い SQL Server ワークロード中に、実行時間の長い I/O のメッセージがエラー ログに複数記録される。
  • パフォーマンス カウンターに、長時間ディスクが遅延している、長時間ディスク キューに登録されている、ディスクのアイドル時間がないといった情報が表示される。

実行時間の長い I/O は、I/O パス内のコンポーネント (ドライバー、コントローラー、ファームウェアなど) が原因になっている場合もあります。ディスク ヘッドの現在位置の近くにある新しい I/O 要求の処理を優先して、古い I/O 要求の処理を絶えず延期するためです。 読み取り/書き込みヘッドの現在位置に最も近い要求を優先順位に基づいて処理する一般的な手法を、"エレベーターシーク" といいます。ほとんどの i/o はすぐにサービスを提供しているため、Windows システムモニター (PERFMON.EXE) ツールと連携さことが困難な場合があります。 実行時間の長い I/O 要求は大容量のシーケンシャル I/O を実行するワークロードによって増大することがあります。たとえば、バックアップおよび復元、テーブル スキャン、並べ替え、インデックスの作成、一括読み込み、ファイルの占有領域の解放処理などがあります。

実行時間の長い I/O のうち、以前の状態には関係ないと考えられる孤立した I/O は、ハードウェアやドライバーの問題が原因になっている場合があります。 システム イベント ログには、問題の診断に役立つ関連イベントが含まれていることがあります。

メモリ不足の検出

メモリ不足は、メモリの不足が原因で発生する状態であり、次の結果を招く可能性があります。

  • 余分な I/O の発生 (レイジー ライターの非常にアクティブなバック グラウンド スレッドなど)
  • 再コンパイルの比率が高くなる
  • クエリの実行時間が長くなる (メモリ許可待機が存在する場合)
  • 余分な CPU サイクルが発生する

この状況は、外部的な原因または内部的な原因によって引き起こされる可能性があります。 外部的な原因には次のようなものがあります。

  • 使用可能な物理メモリ (RAM) が不足しています。 これにより、システムは現在実行中のプロセスのワーキング セットをトリミングします。結果として、全体的な速度が低下する可能性があります。 SQL Server では、バッファープールのコミットターゲットを減らし、内部キャッシュのトリミングを頻繁に開始することができます。
  • 使用できる全体的なシステム メモリ (システムのページ ファイルを含む) が不足しています。 これにより、システムはメモリの割り当てを失敗する場合があります。現在割り当てられているメモリをページ アウトできないためです。 内部的な原因には次のようなものがあります。
  • SQL Server データベースエンジンによってメモリ使用量の上限が低く設定されている場合に、外部メモリの負荷に対応します。
  • max server memory 構成の値を手動で縮小することにより、メモリ設定の値が引き下げられました。
  • 内部コンポーネントによるいくつかのキャッシュ間のメモリ配分に変更が生じました。

SQL Server データベースエンジンは、動的メモリ管理の一部として、メモリ不足を検出して処理する専用のフレームワークを実装します。 このフレームワークには、リソース モニターと呼ばれるバックグラウンド タスクが含まれています。 リソース モニター タスクでは、外部および内部のメモリ インジケーターの状態が監視されます。 これらのインジケーターのいずれかの状態が変化すると、対応する通知が計算され、その通知がブロードキャストされます。 これらの通知は各エンジン コンポーネントからの内部メッセージであり、リング バッファーに格納されます。

次の 2 つのリング バッファーに、動的メモリ管理に関連する情報が保持されます。

  • メモリ不足が通知されているかどうかなど、リソース モニターのアクティビティを追跡するリソース モニター リング バッファー。 このリング バッファーの状態情報は、RESOURCE_MEMPHYSICAL_HIGHRESOURCE_MEMPHYSICAL_LOWRESOURCE_MEMPHYSICAL_STEADY、または RESOURCE_MEMVIRTUAL_LOW の現在の状態に依存します。
  • 各 Resource Governor リソース プールのメモリ通知のレコードが含まれるメモリ ブローカー リング バッファー。 内部メモリ不足が検出されると、メモリの割り当てを行うコンポーネントに対して、メモリ不足を示す通知がオンになり、キャッシュ間でメモリのバランスをとるためのアクションがトリガーされます。

メモリ ブローカーは、コンポーネントごとにメモリの需要と消費量を監視し、収集した情報に基づいて、これらのコンポーネントの各々に対してメモリの最適な値を算出します。 Resource Governor リソース プールごとにブローカー セットがあります。 この情報は、使用量を必要に応じて拡大または縮小する各コンポーネントにブロードキャストされます。 メモリ ブローカーの詳細については、sys.dm_os_memory_brokers に関するページを参照してください。

エラー検出

データベース ページで 2 つのオプションのメカニズム (破損ページ保護とチェックサム保護) を使用して、ページがディスクに書き込まれてから再び読み取られるまでの間、ページの整合性を保証できます。 これらのメカニズムによって、データ ストレージだけでなく、ハードウェア コンポーネント (コントローラー、ドライバー、ケーブルなど)、およびオペレーティング システムに至るまで、個々の正確性を検証するための独立した手段が可能になります。 この保護はディスクに書き込む直前にページに追加され、ディスクから読み取られた後で検証されます。

SQL Server は、チェックサム、破損ページ、またはその他の i/o エラーによって失敗したすべての読み取りを4回再試行します。 いずれかの再試行で読み取りに成功した場合には、エラー ログにメッセージが書き込まれ、その読み取りを起動したコマンドは続行されます。 再試行が失敗した場合には、そのコマンドはエラー メッセージ 824 で失敗します。

使用されている種類のページ保護は、ページが含まれているデータベースの属性です。 チェックサム保護は、SQL Server 2005 (1.x) 以降で作成されたデータベースの既定の保護です。 ページ保護のメカニズムはデータベースの作成時に指定するもので、ALTER DATABASE SET を使用して変更できます。 ページ保護の現在の設定を確認するには、sys.databases カタログ ビューの page_verify_option 列、または DATABASEPROPERTYEX 関数の IsTornPageDetectionEnabled プロパティを照会します。

Note

ページ保護の設定が変更されたとき、新しい設定がデータベース全体にすぐに反映されるわけではありません。 個々のページの出力時に、現在のデータベースの保護レベルがそのページに適用されます。 つまり、データベースはそれぞれ保護の種類が異なるページで構成されている場合があります。

破損ページ保護

破損ページ保護は、SQL Server 2000 で導入されたもので、主に電源障害によるページ破損を検出する方法です。 たとえば、予期しない電源障害でページの一部だけがディスクに書き込まれた状態になったとします。 破損ページ保護が使用されているとき、ディスクへのページ書き込み時に、8 KB のデータベース ページ内の 512 バイトのセクターごとに、特定の 2 ビット署名パターンがデータベース ページ ヘッダーに格納されます。 そのページがディスクから読み取られるときに、ページ ヘッダーに保存されている各セクターの破損ビットと、実際のページ セクター情報とが比較されます。 書き込みが行われるたびに署名パターンとしてバイナリの 01 と 10 が交互に設定されるので、セクターの一部だけがディスクに書き込まれたときを常に判別することが可能です。つまり、後でページが読み取られたときにビットの正しくない状態の場合、ページが不適切に書き込まれたので、破損ページが検出されます。 破損ページ検出で使用されるリソースは最小限です。ただし、ディスクのハードウェア障害が原因で発生したすべてのエラーを検出できるわけではありません。 破損ページ検出の設定の詳細については、「 ALTER database の SET オプション (transact-sql SQL)」を参照してください。

チェックサム保護

SQL Server 2005 (1.x) で導入されたチェックサム保護は、より強力なデータ整合性チェックを提供します。 チェックサムは各ページに書き込まれるデータから算出され、ページ ヘッダーに書き込まれます。 ページにチェックサムが書き込まれている場合は、そのページをディスクから読み取るたびにデータのチェックサムが再計算されます。そして、新しく計算されたチェックサムと、現在書き込まれているチェックサムが異なる場合は、エラー 824 が生成されます。 チェックサム保護はページの各バイトの影響を受けるので、破損ページ保護よりも多くのエラーをキャッチできますが、使用されるリソースがやや多くなります。 チェックサムが有効になっている場合、電源障害、欠陥のあるハードウェアやソフトウェアが原因で発生するエラーは、バッファー マネージャーがディスクからページを読み取るたびに検出できます。 チェックサムの設定の詳細については、「 ALTER database の SET オプション (transact-sql SQL)」を参照してください。

重要

ユーザーまたはシステムデータベースを SQL Server 2005 (1.x) 以降のバージョンにアップグレードすると、 PAGE_VERIFYの値 (NONE または TORN_PAGE_DETECTION) が保持されます。 CHECKSUM の使用を強くお勧めします。 TORN_PAGE_DETECTION は、使用するリソースが比較的少なくて済みますが、CHECKSUM による保護の最小限のサブセットしか利用できません。

Non-Uniform Memory Access について

SQL Server は non-uniform memory access (numa) に対応しており、特別な構成を行わなくても numa ハードウェアで適切に動作します。 プロセッサのクロック速度や数が増加するにつれて処理能力が向上しますが、その一方で、向上した能力の活用に必要となるメモリの待機時間を減らすことが困難になります。 ハードウェア ベンダーはメモリの待機時間をなくすために、大容量の L3 キャッシュを搭載していますが、この解決策にも限界があります。 この問題に対する、拡張性に優れた解決方法が NUMA アーキテクチャです。 SQL Server は、アプリケーションを変更しなくても NUMA ベースのコンピューターを活用できるように設計されています。 詳細については、「SQL Server を構成する方法」をご覧ください。

メモリ オブジェクトの動的パーティション

SQL Server のメモリオブジェクトと呼ばれるヒープアロケーターを使用すると、データベースエンジンはヒープからメモリを割り当てることができます。 これらは sys.dm_os_memory_objects DMV を使用して追跡できます。 CMemThread とは、複数のスレッドから同時にメモリを割り当てることを可能にするスレッドセーフなメモリ オブジェクトの種類です。 追跡を正確に行うために、CMemThread オブジェクトは、同期コンストラクト (ミューテックス) に依存し、一度に 1 つのスレッドのみで重要な情報が確実に更新されるようになっています。

Note

CMemThread オブジェクトの種類は、さまざまな割り当てのためにデータベースエンジンコードベースで使用されます。また、ノードまたは CPU ごとにグローバルにパーティション分割できます。

ただし、ミューテックスを使用すると、多数のスレッドが同じメモリ オブジェクトから同時性の高い方法で割り当てられる場合に競合が発生する可能性があります。 したがって、SQL Server にはパーティション分割されたメモリオブジェクト (PMO) という概念があり、各パーティションは1つの CMemThread オブジェクトによって表されます。 メモリ オブジェクトのパーティション分割は静的に定義され、作成後に変更することはできません。 メモリ割り当てパターンは、ハードウェアやメモリの使用状況などの側面に大きく左右されるので、完全なパーティション分割パターンを事前に取得することは不可能です。 ほとんどの場合は、1 つのパーティションを使用するだけで十分ですが、シナリオによっては、高度にパーティション分割されたメモリ オブジェクトのみが回避できる競合が発生する可能性があります。 各メモリ オブジェクトをパーティション分割することは望ましくありません。パーティションが増えると他の非効率性が生じ、メモリの断片化が増す可能性があるからです。

Note

2016 (13. x) SQL Server する前に、トレースフラグ8048を使用して、ノードベースの pmo が CPU ベースの pmo になるように強制することができます。 SQL Server 2014 (2.x) SP2 および SQL Server 2016 (13. x) 以降では、この動作は動的になり、エンジンによって制御されます。

SQL Server 2014 (2.x) SP2 および SQL Server 2016 (13. x) 以降では、データベースエンジンは、特定の CMemThread オブジェクトの競合を動的に検出し、オブジェクトをノード単位または CPU 単位の実装に昇格させることができます。 昇格すると、SQL Server プロセスが再開されるまで、PMO は昇格されたままになります。 CMemThread の競合は、sys.dm_os_wait_stats DMV 内に CMEMTHREAD の長い待機時間が存在すること、および sys.dm_os_memory_objects DMV 列 contention_factorpartition_typeexclusive_allocations_countwaiting_tasks_count を観察することで検出できます。

参照

サーバー メモリに関するサーバー構成オプション
ページの読み取り
ページの書き込み
方法: ソフト NUMA を使用するように SQL Server を構成する
メモリ最適化テーブルを使用するための要件
メモリ最適化テーブルを利用してメモリ不足の問題を解決する