sql >> データベース >  >> RDS >> Database

インスタンス設定を取得するためのストアドプロシージャ

    SQL Serverインスタンスには、ビジネスモデルのバックエンドスタックのデータ、または特定のアプリケーションの構成データを含むデータベースが格納されています。ユースケースに関係なく、インスタンスには、ベストプラクティスに従うように調整する必要がある一連の値/設定があります。

    この記事で紹介するストアドプロシージャの目的は、DBAに見逃してはならない重要な設定/値のセットを提示することです。さらに、DBAが最近変更/変更された特定の設定/値を制御し続けるのに役立つ優れた機能を共有します。

    最初の考慮事項

    このストアドプロシージャを実行するために使用するアカウントに十分な権限があることを確認してください。 sysadmin特権を持つユーザーを要求するのはあまりにも多すぎるように聞こえますが、SPは xp_cmdshell を使用するため、適切に実行するための最も簡単な方法です。 仕事を成し遂げるためのその他の特別なシステムストアドプロシージャ。または、最小特権の原則に従うようにユーザーの権利を調整することもできます。

    SQLストアドプロシージャの使用方法

    1. この記事で提供されているSPTSQLコードをコピーして貼り付けます。
    2. 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インスタンスに推奨されるベストプラクティスに準拠した値があるかどうかを確認することです。また、設定を更新するために最近のアクティビティ/変更が行われたかどうかを確認するのにも役立ちます(意図的または誤って)。


    1. scope_identity()を使用してネストされた一括挿入を実行する最速の方法は?

    2. MariaDBでのYEAR()のしくみ

    3. PostgreSQLのデフォルト値としてUTCの現在時刻を使用

    4. PostgreSQLで日付スタイルを変更するにはどうすればよいですか?