KB3074434 - 修正: SQL Server プロセスの仮想アドレス空間が使用可能なメモリで非常に少ない場合にメモリ不足エラーが発生する

適用先
SQL Server 2012 Service Pack 3 SQL Server 2012 Developer SQL Server 2012 Enterprise SQL Server 2012 Enterprise Core SQL Server 2012 Standard

この更新プログラムを適用した後、トレース フラグ -T8075 をスタートアップ パラメーターとして追加して、この変更を有効にする必要があります。

現象

64 ビット バージョンの Microsoft SQL Server 2012 でクエリを実行すると、SQL Server エラー ログに次のようなメモリ不足エラー メッセージが表示されます。

割り当てに失敗したページ: FAIL_PAGE_ALLOCATION 513

クエリの実行が完了するまでに長い時間がかかり、SOS_MEMORY_TOPLEVELBLOCKALLOCATOR待機が発生します。

次の情報ポイントを調べると、使用可能な仮想アドレス空間が非常に少ないことがわかります。

  • DBCC MEMORYSTATUS - プロセス/システム数セクション - 使用可能な仮想メモリ
  • DMV: sys.dm_os_process_memory - 列のvirtual_address_space_available_kb

これらの値は、x64 プロセスで約 8 テラバイト (TB) から始まり、引き続き下がり、数ギガバイト (GB) に達します。 

使用可能な仮想アドレス空間が非常に少ない段階にいる場合、メモリ割り当てを実行しようとするクエリでも、待機の種類の CMEMTHREAD が発生する可能性があります。

次のデータ ポイントは、時間の経過と同時に増加し続けます。

  • DMV: sys.dm_os_process_memoryとsys.dm_os_memory_nodes - 列のvirtual_address_space_reserved_kb
  • DBCC MEMORYSTATUS - メモリ マネージャー セクション - VM 予約済み

これらの値は通常、"最大サーバー メモリ" 値の倍数で最大約 8 TB まで増加します。

原因

SQL Server プロセスが、サーバー メモリの合計 = ターゲット サーバー メモリ = 最大サーバー メモリの状態に達すると、新しい割り当てが一時的に成功するために複数の 8 KB ページを要求できるように、SQL Server メモリ マネージャーにポリシーがあります。 このような状態で繰り返し割り当てパターンを実行すると、メモリ ブロックの断片化や仮想アドレス空間の消費が発生する可能性があります。 このプロセスが何度も繰り返されると、SQL Server仮想アドレス空間が使い果たされ、先ほど説明した現象に気付きます。

解決策

累積的な更新プログラムの情報

この問題は、SQL Serverの次の累積的な更新プログラムで最初に修正されました。

推奨事項: SQL Serverの最新の累積的な更新プログラムをインストールする

SQL Serverの各新しい累積的な更新プログラムには、すべての修正プログラムと、以前の累積的な更新プログラムに含まれていたすべてのセキュリティ修正プログラムが含まれています。 SQL Serverの最新の累積的な更新プログラムをダウンロードしてインストールすることをお勧めします。

この修正プログラムは、メモリ不足と、発生する可能性がある使用可能な仮想アドレス空間の継続的な削減の両方を防ぎます。

状態

Microsoft は、これが "適用対象" セクションに記載されている Microsoft 製品の問題であることを確認しました。

追加情報

  • Windows 2012 R2 を使用すると、仮想アドレス空間を 128 TB まで拡張できます。 そのため、Windows 2012 R2 環境ではこの問題に気付かない場合があります。 詳細については、Windows デベロッパー センターの次のトピックを参照してください。

    Windows および Windows Server リリースのメモリ制限

  • 修正プログラムを適用した後でも仮想アドレス空間が継続的に増加する場合は、Page_allocated拡張イベントを使用して、メモリの大きなチャンクを要求しているクエリまたは操作を特定できます。 サンプル スクリプトは次のようになります。

    CREATE EVENT SESSION [memory_tracking] ON SERVER
    ADD EVENT sqlos.page_allocated(
        ACTION(package0.callstack,sqlos.cpu_id,sqlos.task_address,sqlos.worker_address,sqlserver.database_id,sqlserver.query_hash,sqlserver.request_id,sqlserver.session_id,sqlserver.sql_text)
        WHERE ([number_pages]>(1)))
    ADD TARGET package0.event_file(SET filename=N'E:\Data\MSSQL11.MSSQLSERVER\MSSQL\Log\memory_tracking.xel')
    WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_CPU,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
    GO
    
    
    

    通常、これらはログ バックアップとインデックスメンテナンス操作であり、頻繁に発生します。