Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Quy trình được lưu trữ để có được cài đặt phiên bản

SQL Server thể hiện cơ sở dữ liệu nội bộ chứa dữ liệu cho ngăn xếp phụ trợ của mô hình kinh doanh hoặc dữ liệu cấu hình cho các ứng dụng cụ thể. Bất kể trường hợp sử dụng là gì, một phiên bản có một bộ giá trị / cài đặt cần được điều chỉnh để tuân theo các phương pháp hay nhất.

Mục đích của Quy trình được lưu trữ mà tôi sẽ trình bày trong bài viết này là cung cấp cho DBA một tập hợp các cài đặt / giá trị quan trọng không nên bỏ qua. Hơn nữa, tôi sẽ chia sẻ một tính năng thú vị giúp DBA giữ quyền kiểm soát bất kỳ cài đặt / giá trị cụ thể nào đã được thay đổi / sửa đổi gần đây.

Cân nhắc ban đầu

Đảm bảo rằng tài khoản mà bạn sẽ sử dụng để thực hiện Quy trình đã lưu trữ này có đủ đặc quyền. Tôi biết rằng yêu cầu người dùng có đặc quyền sysadmin nghe có vẻ hơi quá, nhưng đó là cách dễ nhất để làm cho nó hoạt động bình thường, vì SP sử dụng xp_cmdshell và các thủ tục được lưu trữ trong hệ thống đặc biệt khác để hoàn thành công việc. Hoặc, bạn có thể điều chỉnh các quyền của người dùng để tuân thủ nguyên tắc đặc quyền ít nhất.

Làm thế nào để Sử dụng Thủ tục Lưu trữ SQL?

  1. Sao chép và dán Mã TSQL SP được cung cấp trong bài viết này.
  2. SP chỉ yêu cầu 1 tham số: @ storeValuesInTable

Y là nếu DBA muốn lưu kết quả đầu ra trong bảng đích và N là nếu DBA chỉ muốn xem đầu ra trực tiếp.

Các trường được trình bày và ý nghĩa của chúng

  • sql_version - phiên bản SQL Server hiện tại của phiên bản.
  • sql_edition - phiên bản SQL Server hiện tại của phiên bản.
  • build_number - số bản dựng hiện tại của phiên bản.
  • min_server_memory - giá trị hiện tại (tính bằng MB) được gán cho Bộ nhớ máy chủ tối thiểu.
  • max_server_memory - giá trị hiện tại (tính bằng MB) được gán cho Bộ nhớ máy chủ tối đa.
  • server_memory - giá trị hiện tại (tính bằng MB) mà máy chủ lưu trữ phiên bản SQL Server có sẵn.
  • server_cores - số lượng lõi vCPU mà máy chủ lưu trữ phiên bản SQL Server có.
  • sql_cores - số lượng lõi vCPU mà phiên bản SQL Server đã chỉ định để sử dụng.
  • cost_threshold_for_parallelism - giá trị hiện tại được chỉ định cho cài đặt Ngưỡng chi phí cho chế độ song song.
  • max_degree_of_parallelism - giá trị hiện tại được chỉ định cho cài đặt Mức độ song song tối đa.
  • lpim_enabled - 0 if Khóa các trang trong bộ nhớ cài đặt bị tắt và 1 cài đặt nếu được bật.
  • ifi_enabled - 0 if Khởi tạo tệp tức thì bị tắt và 1 nếu được bật.
  • install_date - ngày và giờ khi phiên bản SQL Server được cài đặt.
  • sql_service_account - tài khoản dịch vụ sẽ chạy dịch vụ DB Engine.
  • sql_agent_service_account - tài khoản dịch vụ sẽ chạy dịch vụ Đại lý.
  • startup_time - giá trị ngày và giờ khi phiên bản SQL Server mới bắt đầu.
  • data_collection_timestamp - chỉ hiển thị nếu Y được chuyển cho SP. Nó được sử dụng để xác định thời điểm SP được thực thi và lưu thành công thông tin trong InstanceValues ​​ bảng.

Kiểm tra thực thi của Thủ tục được Lưu trữ trong SQL

Tôi sẽ trình bày một số cách thực thi của Thủ tục được lưu trữ để bạn có thể biết được điều gì sẽ xảy ra từ nó.

EXEC DBA_InstanceValues @storeValuesInTable = 'N'
EXEC DBA_InstanceValues @storeValuesInTable = 'Y'

Đối với việc thực thi cụ thể này, kết quả đầu ra sẽ được lưu vào một bảng có tên là InstanceValues ​​ . Nó sẽ được tạo trong cơ sở dữ liệu đích nếu nó không tồn tại.

Bảng có cấu trúc gần như giống như trong ảnh chụp màn hình ở trên, với sự khác biệt nhỏ:nó bao gồm một trường có tên data_collection_timestamp ở cuối bảng.

data_collection_timestamp trường hữu ích cho một số mục đích:

  • cho bạn biết khi nào SP được thực thi để thu thập dữ liệu đã lưu (khá rõ ràng).
  • Để tìm kiếm bất kỳ sự khác biệt nào trong một khoảng thời gian cụ thể cho bất kỳ trường cài đặt cụ thể nào.

Để chứng minh rằng nó hữu ích, hãy để tôi trình bày một ví dụ nhanh.

Tôi đã thực thi SP một lần, vượt qua Y tham số. Bản ghi tương ứng đã được chèn vào InstanceValues ​​ bàn. Sau đó, tôi thay đổi cost_threshold_for_parallelism giá trị trong phiên bản của tôi thành 50 , sau đó thực thi lại tập lệnh.

Như bạn có thể thấy, sửa đổi đã được ghi thành công vào InstanceValues ​​ bàn. Bây giờ, điều này có thể hữu ích như thế nào?

Nếu bạn tạo Công việc đại lý thực hiện Quy trình được lưu trữ này hàng ngày, bạn có thể tạo cơ chế kiểm toán nội bộ để theo dõi thời điểm một giá trị cài đặt cụ thể được sửa đổi, giống như tôi đã trình bày. Do đó, bạn có thể giữ toàn quyền kiểm soát phiên bản SQL Server của mình. Nếu bạn hỏi tôi, đó là một thứ cực kỳ hữu ích.

Mã hoàn chỉnh của quy trình được lưu trữ

Ở phần đầu của script, bạn sẽ thấy giá trị mặc định. Thủ tục được lưu trữ giả định điều đó nếu không có giá trị nào được truyền cho tham số.

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

Kết luận

Quy trình được lưu trữ tùy chỉnh được trình bày trong bài viết này cho phép bạn xây dựng cơ chế cảnh báo để thông báo về những thay đổi của bất kỳ giá trị nào của một trường cụ thể theo thời gian.

Bạn có thể triển khai SP này trong mọi phiên bản SQL Server dưới sự hỗ trợ của bạn và triển khai cơ chế kiểm tra trên toàn bộ ngăn xếp các phiên bản được hỗ trợ của bạn.

Tầm quan trọng chính của thông tin được trình bày là kiểm tra xem phiên bản SQL Server có các giá trị tuân theo các phương pháp hay nhất được đề xuất hay không. Nó cũng giúp bạn kiểm tra xem có bất kỳ hoạt động / thay đổi nào gần đây diễn ra hay không để cập nhật bất kỳ cài đặt nào (cố ý hoặc do nhầm lẫn).


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hiệu suất và bình thường hóa chế độ hàng loạt

  2. Cách tìm giá trị tối đa của một cột số trong SQL

  3. WordPress - Hậu trường, Phần 2

  4. Hash tham gia trên các cột không thể xóa

  5. Tìm hiểu cách xử lý ngoại lệ trong PL / SQL