最近は 64 ビット (x64) の OS を使う機会の方が多いと思いますが、あらためて 32 ビット (x86) の SQL Server のメモリチューニングについてまとめていきたいと思います。
今回は
- Windows Server 2008 Datacenter Edition x86 SP2
- SQL Server 2008 R2 Enterprise Evaluation x86
- SQL Server Code Name ‘Denali’ Enterprise Evaluation x86
- 4 CPU
- 6GB Memory
の環境を使用しています。
■仮想アドレス空間の確認
32 ビット の SQL Server の場合、ユーザーモードの仮想アドレス空間 (VAS : Virtual Address Space) の最大サイズは通常 [2GB] となります。
SQL Server のユーザーモードの VAS ですが、SQL を実行して確認をするためには二種類の方法があります。
- DBCC MEMORYSTATUS を実行
- sys.dm_os_memory_nodes を参照
この 2 種類の方法で VAS の状態を確認することが可能です。
DBCC MEMORY STATUS については技術情報が提供されています。
DBCC MEMORYSTATUS コマンドを使用して SQL Server 2005 のメモリ使用量を監視する方法
sys.dm_os_memory_nodes に関しては BOL に情報が記載されています。
sys.dm_os_memory_nodes (Transact-SQL)
これらを使用することで SQL Server の VAS の情報を確認することができます。
DBCC MEMORYSTATUS を実行するとこのような情報が取得できます。
Memory Manager KB |
sys.dm_os_memory_nodes ではこのような情報が取得できます。
memory_node_id virtual_address_space_reserved_kb virtual_address_space_committed_kb locked_page_allocations_kb pages_kb shared_memory_reserved_kb shared_memory_committed_kb cpu_affinity_mask online_scheduler_mask processor_group foreign_committed_kb |
どちらのコマンドを実行しても VAS の情報を確認可能です。
DBCC MEMORYSTATUS で取得できる情報は、[sys.dm_os_memory_nodes] [sys.dm_os_memory_clerks] [sys.dm_os_memory_objects] [sys.dm_os_memory_cache_counters] [sys.dm_os_memory_pools] から取得することも可能です。
これらの情報を取得することで、[reserved] と [committed] の2 種類を確認することができます。
[reserved] (予約) は仮想メモリの領域を予約しているが実際には物理メモリを割り当てていない状態、 [committed] (確定) は物理メモリを割り当てている状態になります。
■max server memory の設定
SQL Server では [max server memory] を設定することでメモリの上限を設定することができますが、この設定をすることで、[reserved] とするサイズの上限を制限することが可能です。
今回は 32 ビット版の SQL Server を使用しているのですが、1.6GB 程度 VAS が確保できています。
# 大量のデータを検索して SQL Server のメモリを使用させた状態です。
この情報は以下のクエリを実行して取得しています。
SELECT |
初期設定の状態なので max server memory は [2147483647] が設定されているので、使用できる上限まで SQL Server はメモリを確保します。
それでは、max server memory を [1024] に設定して VAS の状態を確認してみたいと思います。
max server memory を設定することで、[Committed] のサイズが変更されていることが確認できます。
今回は設定変更後はサービスを再起動していないため、[Reserved] に関しては 1024 MB 以上の値となっています。
このことから max server memory は [Reserved] ではなく [Committed] 状態のメモリのサイズを制御していることが確認できます。
サービスの再起動をして、Reserved を解放し再度メモリの割り当てを確認してみます。
起動直後の VAS の状態は以下のようになっています。
SQL Server は通常の設定では max server memory を設定しても、起動直後は最小限のメモリのみ [Reserved] [Committed] で確保を行います。
サービスを再起動すると最小限の [Reserved] [Committed] から開始されますので、[Reserved] の確保も抑えられた状態となります。
# [Committed] が [1024 MB] で上限となるので、[Reserved] の確保も抑えらえた状態となります。
■/3GB スイッチによる VAS 上限の変更
今回の環境ではメモリを 6GB 割り当てているのですが、32 ビット OS の制限でユーザーモードの VAS の上限は 2GB となっています。
以下は SQL Server のメモリ割り当て (Memory ManagerTotal Server Memory (KB)) とサーバーの空きメモリ (MemoryAvailable MBytes) の関係をグラフ化したものになります。
サーバーの空きメモリはあるのですが、SQL Server で使用しているメモリについては VAS の上限に達してから頭打ちになっているのが確認できます。
この状態が 32 ビット版の SQL Server の通常設定時の限界となります。
空きメモリがあるにも関わらず、32 ビット OS の制限でメモリを最大限使用できない状態となっています。
32 ビット OS では [/3GB] オプションを設定することで、ユーザーモードのVAS の上限値を 2GB → 3GB に変更することが可能となります。
# [/3GB スイッチ] [4GB チューニング] と呼ばれる設定になります。
Windows Server 2003 向けなりますが以下の技術情報が公開されています。
/userva スイッチと /3GB スイッチを使用してユーザー モード領域を 2 ~ 3 GB の間でチューニングする方法
4 GB RAM チューニング機能と物理アドレス拡張のスイッチの説明
Windows Server 2008 以降は boot.ini ではなく、BCD が使用されていますので bcdedit を使用して設定を行う必要があります。
[/3GB] スイッチは、[increaseuserva 3072] で設定することが可能です。
bcdedit /set {current} increaseuserva 3072 |
上記コマンドをコマンドプロンプトで実行することでユーザーモードの VAS を3GB まで使用することが可能となります。
# 代わりにカーネルモードが 1GB に制限されますが。
設定を削除する場合は以下のコマンドを実行します。
bcdedit /deletevalue {current} increaseuserva |
設定をしたら一度サーバーを再起動して、SQL Server のメモリの使用状況を確認してみます。
設定をすることで設定前と比較して 1GB 程メモリの割り当てが増えていることが確認できます。
この設定をすることで 2GB 以上のメモリを使用することが可能となりますが、サーバーの空きメモリはまだ残っておりメモリを最大限活用できていない状態となっています。
これ以上のメモリを使用するためには AWE (Address Windowing Extensions) を有効にする必要があります。
AWE については次の投稿でまとめたいと思います。