SQL Serverインスタンスには、ビジネスモデルのバックエンドスタックのデータ、または特定のアプリケーションの構成データを含むデータベースが格納されています。ユースケースに関係なく、インスタンスには、ベストプラクティスに従うように調整する必要がある一連の値/設定があります。
この記事で紹介するストアドプロシージャの目的は、DBAに見逃してはならない重要な設定/値のセットを提示することです。さらに、DBAが最近変更/変更された特定の設定/値を制御し続けるのに役立つ優れた機能を共有します。
最初の考慮事項
このストアドプロシージャを実行するために使用するアカウントに十分な権限があることを確認してください。 sysadmin特権を持つユーザーを要求するのはあまりにも多すぎるように聞こえますが、SPは xp_cmdshell を使用するため、適切に実行するための最も簡単な方法です。 仕事を成し遂げるためのその他の特別なシステムストアドプロシージャ。または、最小特権の原則に従うようにユーザーの権利を調整することもできます。
SQLストアドプロシージャの使用方法
- この記事で提供されているSPTSQLコードをコピーして貼り付けます。
- SPは1つのパラメーターのみを想定しています: @ storeValuesInTable
Y これは、DBAが出力をターゲットテーブルに保存することを希望する場合であり、 N DBAが出力を直接見たいだけの場合です。
提示されたフィールドとその意味
- sql_version – インスタンスの現在のSQLServerバージョン。
- sql_edition – インスタンスの現在のSQLServerエディション。
- build_number – インスタンスの現在のビルド番号。
- min_server_memory – 最小サーバーメモリに割り当てられている現在の値(MB単位)。
- max_server_memory – 最大サーバーメモリに割り当てられている現在の値(MB単位)。
- server_memory – SQL Serverインスタンスをホストしているサーバーが利用できる現在の値(MB単位)。
- server_cores – SQLServerインスタンスをホストしているサーバーが持つvCPUコアの数。
- sql_cores – SQLServerインスタンスがその使用のために割り当てたvCPUコアの量。
- cost_threshold_for_parallelism – 並列処理のコストしきい値設定に割り当てられている現在の値。
- max_degree_of_parallelism – Max DegreeofParallelism設定に割り当てられた現在の値。
- lpim_enabled – メモリ内のページをロックするの場合は0 設定は無効で、有効な場合は1です。
- ifi_enabled – インスタントファイル初期化の場合は0 は無効で、有効な場合は1です。
- installed_date – SQLServerインスタンスがインストールされた日時。
- sql_service_account – DBエンジンサービスを実行するサービスアカウント。
- sql_agent_service_account – エージェントサービスを実行するサービスアカウント。
- startup_time – SQLServerインスタンスが最近開始された日時の値。
- data_collection_timestamp – Yの場合にのみ表示されます SPに渡されます。これは、SPがいつ実行され、 InstanceValuesに情報が正常に保存されたかを定義するために使用されます。 テーブル。
実行テスト SQLでのストアドプロシージャの概要
ストアドプロシージャのいくつかの実行を示して、そこから何を期待できるかを理解できるようにします。
EXEC DBA_InstanceValues @storeValuesInTable = 'N'
EXEC DBA_InstanceValues @storeValuesInTable = 'Y'
この特定の実行では、出力は InstanceValuesというテーブルに保存されます。 。存在しない場合は、ターゲットデータベースに作成されます。
このテーブルの構造は上のスクリーンショットとほぼ同じですが、わずかな違いがあります。 data_collection_timestampというフィールドが含まれています。 表の最後にあります。
data_collection_timestamp フィールドはいくつかの目的に役立ちます:
- 保存されたデータを収集するためにSPがいつ実行されたかを通知します(非常に明白です)。
- 特定の設定フィールドについて、特定の時間範囲内で違いを探すため。
それが有用であることを証明するために、簡単な例を示しましょう。
Y を通過して、SPを1回実行しました パラメータ。それぞれのレコードがInstanceValuesに挿入されました テーブル。次に、 cost_threshold_for_parallelismを変更します インスタンス内の値を50 、スクリプトを再度実行します。
ご覧のとおり、変更は InstanceValuesに正常に記録されました。 テーブル。さて、これはどのように役立つのでしょうか?
このストアドプロシージャを毎日実行するエージェントジョブを作成する場合は、内部監査メカニズムを作成できます。 私が示したように、特定の設定値がいつ変更されたかを追跡するため。したがって、SQLServerインスタンスを完全に制御できます。私に言わせれば、それは非常に便利なものです。
ストアドプロシージャの完全なコード
スクリプトの最初に、デフォルト値が表示されます。ストアドプロシージャは、パラメータに値が渡されない場合にそれを想定します。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author : Alejandro Cobar
-- Create date: 2021-05-15
-- Description: SP to retrieve important instance settings/values
-- =============================================
CREATE PROCEDURE [dbo].[DBA_InstanceValues]
@storeValuesInTable CHAR(1) = 'N'
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sqlCommand VARCHAR(4096)
SET @sqlCommand = ''
IF(@storeValuesInTable = 'Y')
BEGIN
IF NOT EXISTS (SELECT * FROM dbo.sysobjects where id = object_id(N'[InstanceValues]') and OBJECTPROPERTY(id, N'IsTable') = 1)
BEGIN
CREATE TABLE InstanceValues(
[sql_version] [VARCHAR](32) NOT NULL,
[sql_edition] [VARCHAR](64) NOT NULL,
[build_number] [VARCHAR](32) NOT NULL,
[min_server_memory] [DECIMAL](15,2) NOT NULL,
[max_server_memory] [DECIMAL](15,2) NOT NULL,
[server_memory] [DECIMAL](15,2) NOT NULL,
[server_cores] [SMALLINT] NOT NULL,
[sql_cores] [SMALLINT] NOT NULL,
[cost_threshold_for_parallelism][SMALLINT] NOT NULL,
[max_degree_of_parallelism] [SMALLINT] NOT NULL,
[lpim_enabled] [TINYINT] NOT NULL,
[ifi_enabled] [TINYINT] NOT NULL,
[installed_date] [DATETIME] NOT NULL,
[sql_service_account] [VARCHAR](64) NOT NULL,
[sql_agent_service_account] [VARCHAR](64) NOT NULL,
[startup_time] [DATETIME] NOT NULL,
[data_collection_timestamp] [DATETIME] NOT NULL
) ON [PRIMARY]
END
END
CREATE TABLE #CPUValues(
[index] SMALLINT,
[description] VARCHAR(128),
[server_cores] SMALLINT,
[value] VARCHAR(5)
)
CREATE TABLE #MemoryValues(
[index] SMALLINT,
[description] VARCHAR(128),
[server_memory] DECIMAL(10,2),
[value] VARCHAR(64)
)
INSERT INTO #CPUValues
EXEC xp_msver 'ProcessorCount'
INSERT INTO #MemoryValues
EXEC xp_msver 'PhysicalMemory'
CREATE TABLE #IFI_Value(DataOut VarChar(2000))
DECLARE @show_advanced_options INT
DECLARE @xp_cmdshell_enabled INT
DECLARE @xp_regread_enabled INT
SELECT @show_advanced_options = CONVERT(INT, ISNULL(value, value_in_use))
FROM master.sys.configurations
WHERE name = 'show advanced options'
IF @show_advanced_options = 0
BEGIN
EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
END
SELECT @xp_cmdshell_enabled = CONVERT(INT, ISNULL(value, value_in_use))
FROM master.sys.configurations
WHERE name = 'xp_cmdshell'
IF @xp_cmdshell_enabled = 0
BEGIN
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE WITH OVERRIDE
END
INSERT INTO #IFI_Value
EXEC xp_cmdshell 'whoami /priv | findstr `"SeManageVolumePrivilege`"'
IF @xp_cmdshell_enabled = 0
BEGIN
EXEC sp_configure 'xp_cmdshell', 0
RECONFIGURE WITH OVERRIDE
END
IF @show_advanced_options = 0
BEGIN
EXEC sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
END
IF (SELECT CONVERT(INT, (REPLACE(SUBSTRING(CONVERT(NVARCHAR, SERVERPROPERTY('ProductVersion')), 1, 2), '.', '')))) > 10
BEGIN
IF(@storeValuesInTable = 'Y')
BEGIN
SET @sqlCommand = '
INSERT INTO InstanceValues
'
END
SET @sqlCommand += '
SELECT
v.sql_version,
(SELECT SUBSTRING(CONVERT(VARCHAR(255),SERVERPROPERTY(''EDITION'')),0,CHARINDEX(''Edition'',CONVERT(VARCHAR(255),SERVERPROPERTY(''EDITION'')))) + ''Edition'') AS sql_edition,
CONVERT(VARCHAR,SERVERPROPERTY(''ProductVersion'')) AS build_number,
(SELECT CONVERT(DECIMAL(10,2),[value]) FROM sys.configurations WHERE name LIKE ''%min server memory%'') min_server_memory,
(SELECT CONVERT(DECIMAL(10,2),[value]) FROM sys.configurations WHERE name LIKE ''%max server memory%'') max_server_memory,
(SELECT ROUND(CONVERT(DECIMAL(10,2),server_memory/1024.0),1) FROM #MemoryValues) AS server_memory,
server_cores,
(SELECT COUNT(*) AS ''sql_cores'' FROM sys.dm_os_schedulers WHERE status = ''VISIBLE ONLINE'') AS sql_cores,
(SELECT CONVERT(SMALLINT,[value]) FROM sys.configurations WHERE name LIKE ''%cost threshold for parallelism%'') AS cost_threshold_for_parallelism,
(SELECT CONVERT(SMALLINT,[value]) FROM sys.configurations WHERE name LIKE ''%max degree of parallelism%'') AS max_degree_of_parallelism,
(SELECT CASE locked_page_allocations_kb WHEN 0 THEN 0 ELSE 1 END FROM sys.dm_os_process_memory) AS lpim_enabled,
(SELECT COUNT(1) FROM #IFI_Value WHERE DataOut LIKE ''%SeManageVolumePrivilege%Enabled%'') AS ifi_enabled,
(SELECT create_date FROM sys.server_principals WHERE sid = 0x010100000000000512000000) AS installed_date,
(SELECT service_account FROM sys.dm_server_services WHERE servicename = {fn CONCAT({fn CONCAT(''SQL Server ('',CONVERT(VARCHAR(32),ISNULL(SERVERPROPERTY(''INSTANCENAME''),''MSSQLSERVER'')))},'')'')}) AS sql_service_account,
(SELECT service_account FROM sys.dm_server_services WHERE servicename = {fn CONCAT({fn CONCAT(''SQL Server Agent ('',CONVERT(VARCHAR(32),ISNULL(SERVERPROPERTY(''INSTANCENAME''),''MSSQLSERVER'')))},'')'')}) AS sql_agent_service_account,
(SELECT login_time FROM sys.sysprocesses WHERE spid = 1) AS startup_time'
IF(@storeValuesInTable = 'Y')
BEGIN
SET @sqlCommand += '
,GETDATE() AS data_collection_timestamp
'
END
SET @sqlCommand += '
FROM #CPUValues
LEFT JOIN (
SELECT
CASE
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''8%'' THEN ''SQL Server 2000''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''9%'' THEN ''SQL Server 2005''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''10.0%'' THEN ''SQL Server 2008''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''10.5%'' THEN ''SQL Server 2008 R2''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''11%'' THEN ''SQL Server 2012''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''12%'' THEN ''SQL Server 2014''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''13%'' THEN ''SQL Server 2016''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''14%'' THEN ''SQL Server 2017''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''15%'' THEN ''SQL Server 2019''
ELSE ''UNKNOWN''
END AS sql_version
) AS v ON 1 = 1
'
EXECUTE(@sqlCommand)
END
ELSE
BEGIN
DECLARE @instanceName VARCHAR(100)
SET @instanceName = CONVERT(VARCHAR,SERVERPROPERTY ('InstanceName'))
IF (@instanceName) IS NULL
BEGIN
DECLARE @agentAccount NVARCHAR(128);
EXEC master.dbo.xp_regread
'HKEY_LOCAL_MACHINE',
'SYSTEM\CurrentControlSet\services\SQLSERVERAGENT',
'ObjectName',
@agentAccount OUTPUT;
DECLARE @engineAccount NVARCHAR(128);
EXEC master.dbo.xp_regread
'HKEY_LOCAL_MACHINE',
'SYSTEM\CurrentControlSet\services\MSSQLSERVER',
'ObjectName',
@engineAccount OUTPUT;
END
ELSE
BEGIN
DECLARE @SQL NVARCHAR (500)
SET @SQL = 'EXEC master.dbo.xp_regread ''HKEY_LOCAL_MACHINE'', ''SYSTEM\CurrentControlSet\services\SQLAgent$'[email protected]+''',''ObjectName'', @serviceAccount OUTPUT;'
EXECUTE sp_executesql @SQL,N'@serviceAccount NVARCHAR(128) OUTPUT',@[email protected] OUTPUT
SET @SQL = 'EXEC master.dbo.xp_regread ''HKEY_LOCAL_MACHINE'', ''SYSTEM\CurrentControlSet\services\MSSQL$'[email protected]+''',''ObjectName'', @serviceAccount OUTPUT;'
EXECUTE sp_executesql @SQL,N'@serviceAccount NVARCHAR(128) OUTPUT',@[email protected] OUTPUT
END
IF(@storeValuesInTable = 'Y')
BEGIN
SET @sqlCommand = '
INSERT INTO InstanceValues
'
END
SET @sqlCommand += '
SELECT
v.sql_version,
(SELECT SUBSTRING(CONVERT(VARCHAR(255),SERVERPROPERTY(''EDITION'')),0,CHARINDEX(''Edition'',CONVERT(VARCHAR(255),SERVERPROPERTY(''EDITION'')))) + ''Edition'') AS sql_edition,
CONVERT(VARCHAR,SERVERPROPERTY(''ProductVersion'')) AS build_number,
(SELECT CONVERT(DECIMAL(10,2),[value]) FROM sys.configurations WHERE name LIKE ''%min server memory%'') min_server_memory,
(SELECT CONVERT(DECIMAL(10,2),[value]) FROM sys.configurations WHERE name LIKE ''%max server memory%'') max_server_memory,
(SELECT ROUND(CONVERT(DECIMAL(10,2),server_memory/1024.0),1) FROM #MemoryValues) AS server_memory,
server_cores,
(SELECT COUNT(*) AS sql_cores FROM sys.dm_os_schedulers WHERE status = ''VISIBLE ONLINE'') AS sql_cores,
(SELECT CONVERT(SMALLINT,[value]) FROM sys.configurations WHERE name LIKE ''%cost threshold for parallelism%'') AS cost_threshold_for_parallelism,
(SELECT CONVERT(SMALLINT,[value]) FROM sys.configurations WHERE name LIKE ''%max degree of parallelism%'') AS max_degree_of_parallelism,
(SELECT CASE locked_page_allocations_kb WHEN 0 THEN 0 ELSE 1 END FROM sys.dm_os_process_memory) AS lpim_enabled,
(SELECT COUNT(1) FROM #IFI_Value WHERE DataOut LIKE ''%SeManageVolumePrivilege%Enabled%'') AS ifi_enabled,
(SELECT create_date FROM sys.server_principals WHERE sid = 0x010100000000000512000000) AS installed_date,
(SELECT '+CHAR(39)[email protected]+CHAR(39)+' AS sql_service_account) AS sql_service_account,
(SELECT '+CHAR(39)[email protected]+CHAR(39)+' AS sql_agent_service_account) AS sql_agent_service_account,
(SELECT login_time FROM sys.sysprocesses WHERE spid = 1) AS startup_time'
IF(@storeValuesInTable = 'Y')
BEGIN
SET @sqlCommand += '
,GETDATE() AS data_collection_timestamp
'
END
SET @sqlCommand += '
FROM #CPUValues
LEFT JOIN (
SELECT
CASE
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''8%'' THEN ''SQL Server 2000''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''9%'' THEN ''SQL Server 2005''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''10.0%'' THEN ''SQL Server 2008''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''10.5%'' THEN ''SQL Server 2008 R2''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''11%'' THEN ''SQL Server 2012''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''12%'' THEN ''SQL Server 2014''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''13%'' THEN ''SQL Server 2016''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''14%'' THEN ''SQL Server 2017''
WHEN CONVERT(VARCHAR(128), SERVERPROPERTY (''PRODUCTVERSION'')) LIKE ''15%'' THEN ''SQL Server 2019''
ELSE ''UNKNOWN''
END AS sql_version
) AS v ON 1 = 1
'
EXECUTE(@sqlCommand)
--SELECT @sqlCommand
END
DROP TABLE #CPUValues
DROP TABLE #MemoryValues
DROP TABLE #IFI_Value
END
結論
この記事で紹介するカスタムストアドプロシージャを使用すると、特定のフィールドの値の経時変化を通知するアラートメカニズムを構築できます。
このSPは、サポート下のすべてのSQL Serverインスタンスに展開し、サポートされているインスタンスのスタック全体に監査メカニズムを実装できます。
提示された情報の主な重要性は、SQLServerインスタンスに推奨されるベストプラクティスに準拠した値があるかどうかを確認することです。また、設定を更新するために最近のアクティビティ/変更が行われたかどうかを確認するのにも役立ちます(意図的または誤って)。