「メモリ内のページのロック」権限は、SQL Serverが使用するサービスアカウントに付与できます。これにより、SQL Serverはメモリがディスクにページングされるのを防ぐことができます。
SQL Serverマシンのいくつかに、SQL Serverが使用するサービスアカウントに対してこの権限を許可するように構成されたローカルポリシーがないことに気付きました。サーバーは多数あるため、「ローカルシステムポリシー」管理コンソールを使用して各サーバーを手動で確認するのは、せいぜい面倒です。
問題のサーバーが適切かどうかを判断するために使用できるT-SQLクエリ、拡張ストアドプロシージャ、またはその他の方法はありますか?
現在のSQL Serverエラーログの確認に依存しているため、notEXEC xp_readerrorlog 0, 1, 'lock memory privilege was not granted';
を使用したいと思います。また、サーバーが最後に再起動されてからログがロールオーバーされている場合、エラーログには関連するエントリが含まれていない可能性があります。最初のパラメーターを0
から1
などに変更することで古いログを確認できることを理解していますが、保持しているエラーログは10個だけであり、それだけでは不十分な場合があります。設定を確認するためのフェイルセーフな方法が必要です。
xp_cmdshell
はオプションです。ここにwhoami
を使用するスクリプトがあります。
DECLARE @LockPagesInMemory VARCHAR(255);
SET @LockPagesInMemory = 'UNKNOWN';
DECLARE @Res TABLE
(
[output] NVARCHAR(255) NULL
);
IF (SELECT value_in_use
FROM sys.configurations c
WHERE c.name = 'xp_cmdshell'
) = 1
BEGIN
INSERT INTO @Res
EXEC xp_cmdshell 'WHOAMI /PRIV';
IF EXISTS (SELECT *
FROM @Res
WHERE [output] LIKE 'SeLockMemoryPrivilege%'
)
SET @LockPagesInMemory = 'ENABLED';
ELSE
SET @LockPagesInMemory = 'DISABLED';
END
SELECT LockPagesInMemoryEnabled = @LockPagesInMemory;
whoami.exe
は、whoami
を実行するアカウントが保有するすべての権利を報告することができます。これとxp_cmdshell
は、SQL Serverのインスタンスがメモリ内のページをロックするために必要な権利を持っているかどうかを判断する信頼できる方法を提供します。
xp_cmdshell
は有効になっていません。このコードはUNKNOWN
を返します。 xp_cmdshell
is有効で、SQL Serverアカウントに対して権限が有効になっている場合、ENABLED
を返し、それ以外の場合はDISABLED
を返します。
他の方法もあります。おそらく2つのDMVを使用できます。どちらもSQL Server 2008以降でのみ機能することに注意してください。
locked_page_allocations_kb
のゼロ以外の値は、SQL Serverアカウントがメモリ内のロックされたページ特権を持っていることを示します。
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'
...そして:
select
(physical_memory_in_use_kb/1024)Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024 )Locked_pages_used_Sqlserver_MB,
(total_virtual_address_space_kb/1024 )Total_VAS_in_MB,
process_physical_memory_low,
process_virtual_memory_low
from sys.dm_os_process_memory
列Locked_pages_allocation_KB
にゼロ以外の値が表示されている場合、SQL Serverサービスアカウントにもメモリ内のロックされたページの権限があります。
...そして:
DBCC MEMORYSTATUS
出力の「メモリマネージャー」セクションには、「割り当てられたAWE」にゼロ以外の値が表示されるか、SQL Serverサービスアカウントにメモリ内のロックされたページの権限がある場合。
注:
SQL Serverサービスアカウントがローカルシステム(NT Authority\System)アカウントで実行されている場合、デフォルトでSQL Serverはメモリ内のロックされたページの権限を持ちます。
更新:
SQL Server 2012 for Standard Editionより前のバージョンでは、LPIMを利用するためにトレースフラグt -845を有効にする必要があります。 LPIM特権を持つアカウントでSQL Serverを実行している場合でも、トレースフラグが有効になっていない限り、SQL Serverは実際にはLPIMアドバンテージを使用しません。
2012年以降、LPIMを利用するために標準版でトレースフラグを有効にする必要はありません。
Microsoftは、SQL Serverが(適切なアクセス許可を持つのではなく)LPIMを利用するメモリモデルで実行されているかどうかが本当に知りたい場合に、新しいバージョンの製品でこれを容易にします。この情報は、SQL Serverのバージョンに応じて sys.dm_os_sys_info にあります。拡張機能は ブログ投稿 で発表されました:
SQL Server 2016 SP1およびSQL Server 2012 SP4では、sys.dm_os_sys_infoに2つの新しい列viz sql_memory_modelおよびsql_memory_model_descが追加されました。これらを使用して、メモリ内のページのロック(LPIM)権限がSQL Serverサービスアカウントに割り当てられているかどうかを識別できます。
注意すべき重要なことの1つは、新しい列は、SQL Serverインスタンスの起動以降に使用されているSQLメモリモデルを報告します。これは、必要な情報です。 SQLサービスアカウントのLPIM権限について、OSレベルで実行されるチェックはありません。 SQL Serverの起動時にLPIM特権がSQL Serverサービスアカウントプロセストークンに存在する場合、SQL Serverはロックされたページ(ページング不可)を使用してSQLメモリを割り当てます。さらに、SQLサービスアカウントに割り当てられたLPIM特権でSQL ServerのEnterpriseエディションを実行していて、トレースフラグ834がオンになっている場合、SQL Serverはラージページを使用してSQLメモリを割り当てます。
メモリ内のページのロック特権が特定のSQL Serverインスタンスに対して有効かどうかを確認するには、sys.dm_os_sys_infoのsql_memory_modelにクエリを実行し、1より大きい値を探します。
サービスアカウントプロセストークンにLPIM権限がない場合、コンベンショナルメモリモデルが使用され、DMVによって同じことが報告されます(sql_memory_model = 1)。ここで、メモリ内のロックページ権限がSQLサーバーに割り当てられているが、SQLサービスは再起動されていない場合、DMVは従来のメモリモデルを報告し続けます。再起動後、SQL Serverはメモリモデルのロックされたページを使用し、同じことがsys.dm_os_sys_infoのsql_memory_modelおよびsql_memory_model_descによって報告されます。
サーバーの1つで次のクエリを実行すると、
SELECT sql_memory_model, sql_memory_model_desc
FROM sys.dm_os_sys_info;
現在使用されているメモリモデルはCONVENTIONAL
です。これは、サーバーの起動時にLPIMが許可されなかったことを意味します。ただし、LPIMを付与してSQL Serverサービスを再起動しないことは可能であるため、質問の正確な性質によっては、このDMVが役に立たない場合があります。