diff --git a/alwayson-dashboard.sql b/alwayson-dashboard.sql index 3ee011b..8020673 100644 --- a/alwayson-dashboard.sql +++ b/alwayson-dashboard.sql @@ -84,6 +84,10 @@ BEGIN WHEN 1 THEN 0 ELSE ISNULL(DATEDIFF([ss], [dbr].[last_commit_time], [dbrp].[last_commit_time]), 0) END AS [EstimatedDataLoss_(Seconds)] + ,CASE [dbcs].[is_failover_ready] + WHEN 1 THEN '00:00:00:000' + ELSE CONVERT(varchar, DATEADD(ms, ISNULL(DATEDIFF([ss], [dbr].[last_commit_time], [dbrp].[last_commit_time]), 0) * 1000, 0), 114) + END AS [EstimatedDataLoss] ,ISNULL(CASE [dbr].[redo_rate] WHEN 0 THEN -1 ELSE CAST([dbr].[redo_queue_size] AS FLOAT) / NULLIF([dbr].[redo_rate] ,0) diff --git a/alwayson-failover-database-recovery-status.sql b/alwayson-failover-database-recovery-status.sql new file mode 100644 index 0000000..147b818 --- /dev/null +++ b/alwayson-failover-database-recovery-status.sql @@ -0,0 +1,48 @@ +DECLARE @DBName VARCHAR(64) = 'database_name'; + +-- AG SYNC STATE +SELECT DB_NAME(database_id) as DatabaseName + ,synchronization_state_desc + ,database_state_desc +FROM sys.dm_hadr_database_replica_states +WHERE is_local=1 +AND is_primary_replica=0 +AND DB_NAME(database_id) = @DBName; + +-- REPLICA ROLLBACK +SELECT object_name + ,counter_name + ,instance_name + ,cntr_value AS [log_kb_remaining] +FROM sys.dm_os_performance_counters +WHERE counter_name = 'log remaining for undo' +AND instance_name LIKE @DBName + '%'; + +-- RECOVERY STATUS +DECLARE @ErrorLog AS TABLE([LogDate] CHAR(24), [ProcessInfo] VARCHAR(64), [TEXT] VARCHAR(MAX)); + +INSERT INTO @ErrorLog +EXEC master..sp_readerrorlog 0, 1, 'Recovery of database', @DBName; + +INSERT INTO @ErrorLog +EXEC master..sp_readerrorlog 0, 1, 'Recovery completed', @DBName; + +SELECT TOP 1 + @DBName AS [DBName] + ,[LogDate] + ,CASE + WHEN SUBSTRING([TEXT],10,1) = 'c' THEN '100%' + ELSE SUBSTRING([TEXT], CHARINDEX(') is ', [TEXT]) + 4,CHARINDEX(' complete (', [TEXT]) - CHARINDEX(') is ', [TEXT]) - 4) + END AS PercentComplete + ,CASE + WHEN SUBSTRING([TEXT],10,1) = 'c' THEN 0 + ELSE CAST(SUBSTRING([TEXT], CHARINDEX('approximately', [TEXT]) + 13,CHARINDEX(' seconds remain', [TEXT]) - CHARINDEX('approximately', [TEXT]) - 13) AS FLOAT)/60.0 + END AS MinutesRemaining + ,CASE + WHEN SUBSTRING([TEXT],10,1) = 'c' THEN 0 + ELSE CAST(SUBSTRING([TEXT], CHARINDEX('approximately', [TEXT]) + 13,CHARINDEX(' seconds remain', [TEXT]) - CHARINDEX('approximately', [TEXT]) - 13) AS FLOAT)/60.0/60.0 + END AS HoursRemaining + ,[TEXT] +FROM @ErrorLog +ORDER BY CAST([LogDate] as datetime) DESC + ,[MinutesRemaining]; diff --git a/backup-restore-to-RDS-for-SQL-Server.sql b/backup-restore-to-RDS-for-SQL-Server.sql new file mode 100644 index 0000000..562da9d --- /dev/null +++ b/backup-restore-to-RDS-for-SQL-Server.sql @@ -0,0 +1,37 @@ +/* +Migrating SQL Server to Amazon RDS using native backup and restore +https://aws.amazon.com/blogs/database/migrating-sql-server-to-amazon-rds-using-native-backup-and-restore/ +*/ + +USE master; +GO + +EXEC msdb.dbo.rds_restore_database + @restore_db_name='DatabaseName', + @s3_arn_to_restore_from='arn:aws:s3:::bucketname/sqlserverbackups/DatabaseName_full.bak', + @with_norecovery=1, + @type='FULL'; +GO + +SELECT * FROM msdb.dbo.rds_fn_task_status(NULL,0); +GO + +EXEC msdb.dbo.rds_restore_database + @restore_db_name='DatabaseName', + @s3_arn_to_restore_from='arn:aws:s3:::bucketname/sqlserverbackups/DatabaseName_diff.bak', + @type='DIFFERENTIAL', + @with_norecovery=1; +GO + +SELECT * FROM msdb.dbo.rds_fn_task_status(NULL,0); +GO + +EXEC msdb.dbo.rds_restore_log + @restore_db_name='DatabaseName', + @s3_arn_to_restore_from='arn:aws:s3:::bucketname/sqlserverbackup/DatabaseName_log.trn', + @with_norecovery=0; +go + +SELECT * FROM msdb.dbo.rds_fn_task_status(NULL,0); +GO + diff --git a/batch-update-script.sql b/batch-update-script.sql new file mode 100644 index 0000000..0e2b1bb --- /dev/null +++ b/batch-update-script.sql @@ -0,0 +1,40 @@ +USE [DATABASE_NAME]; +GO +SET NOCOUNT ON; + +DECLARE @Rows INT + ,@BatchSize INT = 4000 + ,@Completed INT = 0 + ,@Total INT; + +-- \/\/ Populate temp table with PK column(s) \/\/ -- +SELECT [SOME_ID] +INTO #temp_ids +FROM [TABLE_NAME] +WHERE [SOME_COLUMN] IS NULL; + +SELECT @Total = COUNT(*) FROM #temp_ids; + +CREATE TABLE #temp_upd (Id UNIQUEIDENTIFIER); + +WHILE EXISTS (SELECT 1 FROM #temp_ids) +BEGIN + DELETE TOP (@BatchSize) + FROM #temp_ids + OUTPUT deleted.Id INTO #temp_upd; + + UPDATE t + SET [SOME_COLUMN] = 'Some Value' + FROM [TABLE_NAME] t + JOIN #temp_upd tmp ON t.[SOME_ID] = tmp.Id; + + SET @Rows = @@ROWCOUNT; + SET @Completed = @Completed + @Rows; + + PRINT 'Completed ' + cast(@Completed as varchar(10)) + '/' + cast(@Total as varchar(10)); + + TRUNCATE TABLE #temp_upd; +END; + +DROP TABLE IF EXISTS #temp_upd; +DROP TABLE IF EXISTS #temp_ids; diff --git a/database-get-encryption-state.sql b/database-get-encryption-state.sql new file mode 100644 index 0000000..fcc655e --- /dev/null +++ b/database-get-encryption-state.sql @@ -0,0 +1,9 @@ +SELECT d.name AS [database] + ,d.is_encrypted + ,dek.encryption_state + ,dek.percent_complete + ,dek.key_algorithm + ,dek.key_length +FROM master.sys.databases d + LEFT JOIN master.sys.dm_database_encryption_keys dek ON d.database_id = dek.database_id +ORDER BY d.name; \ No newline at end of file diff --git a/database-get-file-size-and-space-used.sql b/database-get-file-size-and-space-used.sql index cd38b77..4f555ea 100644 --- a/database-get-file-size-and-space-used.sql +++ b/database-get-file-size-and-space-used.sql @@ -22,7 +22,7 @@ CREATE TABLE #DB_FILE_INFO ( ); DECLARE @l_sql NVARCHAR(4000) - ,@l_DBName NVARCHAR(128) + ,@l_DBName NVARCHAR(128) = 'mf_scratch' ; SET @l_sql = diff --git a/database-get-table-and-index-size.sql b/database-get-table-and-index-size.sql index 0e47a8a..a49c2eb 100644 --- a/database-get-table-and-index-size.sql +++ b/database-get-table-and-index-size.sql @@ -13,11 +13,15 @@ exec sp_spaceused 'ZipCode'; exec sp_spaceused 'StatisticalArea_to_Zip'; */ -DECLARE @l_DBId INT; +DECLARE @l_DBId INT + ,@l_TblName VARCHAR(128) = '[dbo].[FactLoanResponseAttribute]' + ,@l_TblId INT; SET @l_DBId = DB_ID(); +SET @l_TblId = OBJECT_ID(@l_TblName); SELECT TblId = o.object_id + , SchemaName = SCHEMA_NAME(o.schema_id) , TblName = o.name , IndxId = i.index_id , IndxName = i.name @@ -42,4 +46,5 @@ FROM sys.objects o ON i.data_space_id = d.data_space_id WHERE o.type = 'U' AND o.is_ms_shipped = 0 +AND (@l_TblId IS NULL OR o.object_id = @l_TblId) ORDER BY CONVERT(NUMERIC(9,1),CASE WHEN i.index_id IN(0,1) THEN a.data_pages END * @pgsz) + CONVERT(NUMERIC(9,1),ISNULL(CASE WHEN i.index_id > 1 THEN a.data_pages END,0) * @pgsz) desc diff --git a/database-get-table-size.sql b/database-get-table-size.sql index ca69d9f..acb0eb7 100644 --- a/database-get-table-size.sql +++ b/database-get-table-size.sql @@ -8,9 +8,12 @@ FROM [master].dbo.spt_values WHERE number = 1 AND type = 'E'; -DECLARE @l_DBId INT; +DECLARE @l_DBId INT + ,@l_TblId INT + ,@l_Table VARCHAR(128) = 'schema.table'; SET @l_DBId = DB_ID(); +SET @l_TblId = OBJECT_ID(@l_Table); SELECT TblId = o.object_id , TblName = o.name @@ -29,6 +32,7 @@ FROM sys.objects o ON p.partition_id = a.container_id WHERE o.type = 'U' AND o.is_ms_shipped = 0 +AND (o.object_id = @l_TblId OR @l_TblId IS NULL) GROUP BY o.object_id , o.name ORDER BY 4 DESC diff --git a/database-migrate-encryption-keys.sql b/database-migrate-encryption-keys.sql index 9ccedaa..9c1300c 100644 --- a/database-migrate-encryption-keys.sql +++ b/database-migrate-encryption-keys.sql @@ -2,6 +2,8 @@ create table #key_tbls (DBName VARCHAR(100), KeyName VARCHAR(100)); declare @sql nvarchar(max) = 'use [?]; insert #key_tbls (DBName, KeyName) select DB_NAME(), name from sys.symmetric_keys where name <> ''##MS_DatabaseMasterKey##'';' + select DB_NAME(), name from sys.symmetric_keys where name <> '##MS_DatabaseMasterKey##'; + exec sp_MSforeachdb @sql select DBName, KeyName @@ -15,3 +17,7 @@ alter master key add encryption by service master key exec SystemConfiguration_GetValue 'ValidationKey' */ + + + select * from sys.symmetric_keys + select * from sys.certificates diff --git a/database-purge-all-connections.sql b/database-purge-all-connections.sql new file mode 100644 index 0000000..3fbc9c6 --- /dev/null +++ b/database-purge-all-connections.sql @@ -0,0 +1,34 @@ +USE MASTER +GO + +DECLARE @Spid INT +DECLARE @ExecSQL VARCHAR(255) + +DECLARE KillCursor CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY +FOR +SELECT DISTINCT SPID, * +FROM MASTER..SysProcesses +WHERE DBID = DB_ID('DatabaseName') + +OPEN KillCursor + +-- Grab the first SPID +FETCH NEXT +FROM KillCursor +INTO @Spid + +WHILE @@FETCH_STATUS = 0 + BEGIN + SET @ExecSQL = 'KILL ' + CAST(@Spid AS VARCHAR(50)) + + EXEC (@ExecSQL) + + -- Pull the next SPID + FETCH NEXT + FROM KillCursor + INTO @Spid + END + +CLOSE KillCursor + +DEALLOCATE KillCursor \ No newline at end of file diff --git a/database-shrink-file.sql b/database-shrink-file.sql new file mode 100644 index 0000000..26ba146 --- /dev/null +++ b/database-shrink-file.sql @@ -0,0 +1,13 @@ +USE [Database] +GO + +DECLARE @StartSize INT = 102400 -- SET START SIZE OF THE DATABASE FILE (MB) + ,@TargetSize INT = 20480 -- SET END SIZE OF THE DATABASE FILE (MB) +; + +WHILE @StartSize > @TargetSize +BEGIN + SET @StartSize = @StartSize - 10240; + DBCC SHRINKFILE (N'FileName' , @StartSize); -- logical name +END; +GO diff --git a/error-log-query-using-xp_readerrorlog.sql b/error-log-query-using-xp_readerrorlog.sql index 8aad1ec..bec9be7 100644 --- a/error-log-query-using-xp_readerrorlog.sql +++ b/error-log-query-using-xp_readerrorlog.sql @@ -8,10 +8,10 @@ DECLARE @ArchiveID INT --Value of error log file you want to read: 0 = current SELECT @ArchiveID = 0 ,@LogFileType = 1 - ,@Filter1Text = 'SomeText' + ,@Filter1Text = NULL ,@Filter2Text = NULL - ,@FirstEntry = NULL - ,@LastEntry = NULL + ,@FirstEntry = '2021-05-01 05:44:39' + ,@LastEntry = '2021-05-02 06:38:59.080' ,@SortOrder = N'asc'; EXEC master.sys.xp_readerrorlog @ArchiveID diff --git a/get-estimated-completion.sql b/get-estimated-completion.sql new file mode 100644 index 0000000..8e4e6a9 --- /dev/null +++ b/get-estimated-completion.sql @@ -0,0 +1,19 @@ +DECLARE @SPID INT = ; + +SELECT command + ,percent_complete + ,estimated_completion_time / 1000 AS estimated_completion_time_sec +FROM sys.dm_exec_requests +WHERE session_id = @SPID; + +SELECT + node_id, + physical_operator_name, + SUM(row_count) row_count, + SUM(estimate_row_count) AS estimate_row_count, + CAST(SUM(row_count)*100 AS float)/SUM(estimate_row_count) as estimate_percent_complete +FROM sys.dm_exec_query_profiles +WHERE session_id=@SPID +GROUP BY node_id,physical_operator_name +ORDER BY node_id desc; + diff --git a/get-worker-thread-counts.sql b/get-worker-thread-counts.sql index d8ded81..59f8e08 100644 --- a/get-worker-thread-counts.sql +++ b/get-worker-thread-counts.sql @@ -6,3 +6,17 @@ select (select max_workers_count from sys.dm_os_sys_info) as 'TotalThreads' ,sum(work_queue_count) as 'Request_Waiting_for_threads' from sys.dm_os_Schedulers where status='VISIBLE ONLINE' + + +SELECT s.session_id, r.command, r.status, + r.wait_type, r.scheduler_id, w.worker_address, + w.is_preemptive, w.state, t.task_state, + t.session_id, t.exec_context_id, t.request_id +FROM sys.dm_exec_sessions AS s +INNER JOIN sys.dm_exec_requests AS r + ON s.session_id = r.session_id +INNER JOIN sys.dm_os_tasks AS t + ON r.task_address = t.task_address +INNER JOIN sys.dm_os_workers AS w + ON t.worker_address = w.worker_address +WHERE s.is_user_process = 0; \ No newline at end of file diff --git a/index-get-detail-by-table.sql b/index-get-detail-by-table.sql index 95e3753..95be747 100644 --- a/index-get-detail-by-table.sql +++ b/index-get-detail-by-table.sql @@ -1,8 +1,10 @@ SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +GO DECLARE @DBId INT = DB_ID() ,@SchemaName sysname - ,@TblName sysname = N'dbo.factloanresponseattribute' + ,@TblName sysname = N'[dbo].[FactLoanResponseAttribute]' ,@TblId INT ,@MinFragmentation REAL = 5.0 -- Defaulted to 5% as recommended by MS in BOL ,@MinPageCount INT = 1000 -- Defaulted to 1000 pages as recommended by MS in BOL @@ -187,42 +189,42 @@ ORDER BY Impact DESC OPTION (MAXDOP 2); /****** POSSIBLE MISSING INDEXES BLOCK END ******/ -/****** POSSIBLE BAD INDEXES BLOCK START ******/ -SELECT 'POSSIBLE BAD (since last restart):' AS Info; -SELECT OBJECT_NAME(i.object_id) AS [Table Name] - ,i.name AS [Index Name] - ,i.type_desc AS [Index Type] - ,ISNULL(s.user_seeks + s.user_scans + s.user_lookups,0) AS [Total Reads] - ,ISNULL(s.user_updates,0) AS [Total Writes] - ,ISNULL(s.user_updates - (s.user_seeks + s.user_scans + s.user_lookups),0) AS [Difference] - ,ISNULL(CASE WHEN s.user_updates < 1 THEN 100 - ELSE 1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates - END,0) AS reads_per_write - ,( - SELECT SUM(p.rows) - FROM sys.partitions p - WHERE p.index_id = i.index_id - AND i.object_id = p.object_id - ) AS Rows - ,CASE WHEN i.is_primary_key = 1 - OR i.is_unique_constraint = 1 THEN - 'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' - + QUOTENAME(OBJECT_NAME(i.object_id)) + ' DROP CONSTRAINT ' + QUOTENAME(i.name) - ELSE - 'DROP INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' - + QUOTENAME(OBJECT_NAME(i.object_id)) - END AS [Drop Statement] -FROM sys.indexes AS i WITH (NOLOCK) - LEFT JOIN sys.dm_db_index_usage_stats AS s WITH (NOLOCK) - ON s.object_id = i.object_id - AND i.index_id = s.index_id - AND OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1 - AND s.database_id = DB_ID() -WHERE i.index_id > 1 -AND i.object_id = @TblId -AND s.user_updates > (s.user_seeks + s.user_scans + s.user_lookups) -ORDER BY Difference DESC - ,[Total Writes] DESC - ,[Total Reads] ASC -OPTION (RECOMPILE, MAXDOP 2); -/****** POSSIBLE BAD INDEXES BLOCK END ******/ \ No newline at end of file +--/****** POSSIBLE BAD INDEXES BLOCK START ******/ +--SELECT 'POSSIBLE BAD (since last restart):' AS Info; +--SELECT OBJECT_NAME(i.object_id) AS [Table Name] +-- ,i.name AS [Index Name] +-- ,i.type_desc AS [Index Type] +-- ,ISNULL(s.user_seeks + s.user_scans + s.user_lookups,0) AS [Total Reads] +-- ,ISNULL(s.user_updates,0) AS [Total Writes] +-- ,ISNULL(s.user_updates - (s.user_seeks + s.user_scans + s.user_lookups),0) AS [Difference] +-- ,ISNULL(CASE WHEN s.user_updates < 1 THEN 100 +-- ELSE 1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates +-- END,0) AS reads_per_write +-- ,( +-- SELECT SUM(p.rows) +-- FROM sys.partitions p +-- WHERE p.index_id = i.index_id +-- AND i.object_id = p.object_id +-- ) AS Rows +-- ,CASE WHEN i.is_primary_key = 1 +-- OR i.is_unique_constraint = 1 THEN +-- 'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' +-- + QUOTENAME(OBJECT_NAME(i.object_id)) + ' DROP CONSTRAINT ' + QUOTENAME(i.name) +-- ELSE +-- 'DROP INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' +-- + QUOTENAME(OBJECT_NAME(i.object_id)) +-- END AS [Drop Statement] +--FROM sys.indexes AS i WITH (NOLOCK) +-- LEFT JOIN sys.dm_db_index_usage_stats AS s WITH (NOLOCK) +-- ON s.object_id = i.object_id +-- AND i.index_id = s.index_id +-- AND OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1 +-- AND s.database_id = DB_ID() +--WHERE i.index_id > 1 +--AND i.object_id = @TblId +--AND s.user_updates > (s.user_seeks + s.user_scans + s.user_lookups) +--ORDER BY Difference DESC +-- ,[Total Writes] DESC +-- ,[Total Reads] ASC +--OPTION (RECOMPILE, MAXDOP 2); +--/****** POSSIBLE BAD INDEXES BLOCK END ******/ \ No newline at end of file diff --git a/index-get-overlapping-indexes.sql b/index-get-overlapping-indexes.sql index b278c90..aad3276 100644 --- a/index-get-overlapping-indexes.sql +++ b/index-get-overlapping-indexes.sql @@ -124,7 +124,7 @@ EXEC sp_executesql @loadIndexSQL; ----------- --SELECT 'Listing Possible Redundant Index keys' AS [Comments]; -SELECT DISTINCT i.TableName, i.IndexName,i.IndexType, i.ConstraintType, i.AllColName, i.IndexSizeKB, i.HasFilter, i.HasIncludedColumn +SELECT DISTINCT i.SchemaName, i.TableName, i.IndexName,i.IndexType, i.ConstraintType, i.AllColName, i.IndexSizeKB, i.HasFilter, i.HasIncludedColumn FROM #AllIndexes AS i JOIN #AllIndexes AS i2 ON i.TableID = i2.TableID AND i.ColName1 = i2.ColName1 diff --git a/index-get-table-fragmentation.sql b/index-get-table-fragmentation.sql new file mode 100644 index 0000000..a66c3c4 --- /dev/null +++ b/index-get-table-fragmentation.sql @@ -0,0 +1,16 @@ +DECLARE @l_TableName VARCHAR(128) = 'Schema.TableName' + ,@l_TableId INT; + +SET @l_TableId = OBJECT_ID(@l_TableName); + +SELECT OBJECT_NAME(i.object_id) AS TableName + ,i.name AS IndexName + ,ps.index_type_desc AS IndexType + ,TRY_CONVERT(NUMERIC(9,2), ps.page_count * 1.0 / 128) AS IndexSize_MB + ,TRY_CONVERT(NUMERIC(9,2), ps.avg_fragmentation_in_percent) AS FragmentationPercentage + ,TRY_CONVERT(NUMERIC(9,2), ps.avg_page_space_used_in_percent) AS PageDensityPercentage +FROM sys.indexes i + CROSS APPLY sys.dm_db_index_physical_stats(DB_ID(), i.object_id, i.index_id, NULL, 'SAMPLED') ps +WHERE i.object_id = @l_TableId +ORDER BY ps.index_type_desc + ,FragmentationPercentage DESC; diff --git a/mysql-change-password.sql b/mysql-change-password.sql new file mode 100644 index 0000000..9c42072 --- /dev/null +++ b/mysql-change-password.sql @@ -0,0 +1 @@ +ALTER USER 'user'@'%' IDENTIFIED BY 'new_pwd'; \ No newline at end of file diff --git a/plan-cache-find-longest-running-queries.sql b/plan-cache-find-longest-running-queries.sql index 4eff906..094d690 100644 --- a/plan-cache-find-longest-running-queries.sql +++ b/plan-cache-find-longest-running-queries.sql @@ -7,7 +7,7 @@ SELECT TOP (1000) ,querystats.creation_time ,querystats.last_execution_time ,ISNULL(querystats.execution_count / 1000 / NULLIF(DATEDIFF(SECOND, querystats.creation_time, GETDATE()), 0), 0) AS freq_per_second - ,CAST(query_plan AS XML) AS plan_xml + ,TRY_CONVERT(XML, query_plan) AS plan_xml FROM sys.dm_exec_query_stats as querystats CROSS APPLY sys.dm_exec_text_query_plan (querystats.plan_handle, querystats.statement_start_offset, querystats.statement_end_offset) as textplan CROSS APPLY sys.dm_exec_sql_text(querystats.sql_handle) AS sqltext diff --git a/security-change-sql-login-password.sql b/security-change-sql-login-password.sql index 16ebd8f..7f2c2a0 100644 --- a/security-change-sql-login-password.sql +++ b/security-change-sql-login-password.sql @@ -1,4 +1,7 @@ -ALTER LOGIN [user] WITH - PASSWORD = 'NewPassword' - OLD_PASSWORD = 'OldPassword'; -GO \ No newline at end of file + +SELECT LOGINPROPERTY(USER_NAME(), 'DaysUntilExpiration') AS DaysUntilExpiration + ,LOGINPROPERTY(USER_NAME(), 'IsExpired') AS IsExpired + ,LOGINPROPERTY(USER_NAME(), 'IsLocked') AS IsLocked; + +ALTER LOGIN [user] WITH PASSWORD = 'NewPassword'; +GO diff --git a/security-get-sql-logins-is-expiration-checked.sql b/security-get-sql-logins-is-expiration-checked.sql new file mode 100644 index 0000000..f8151fc --- /dev/null +++ b/security-get-sql-logins-is-expiration-checked.sql @@ -0,0 +1,10 @@ + +SELECT sp.name + ,LOGINPROPERTY (sp.name, 'IsExpired') AS IsExpired + ,LOGINPROPERTY (sp.name, 'DaysUntilExpiration') AS DaysUntilExpiration +FROM sys.server_principals sp + JOIN sys.sql_logins sl ON sp.principal_id = sl.principal_id +WHERE sp.type_desc = 'SQL_LOGIN' +AND sp.is_disabled = 0 +AND sl.is_expiration_checked = 1 +ORDER BY 1 diff --git a/security-migrate-database-principals.sql b/security-migrate-database-principals.sql index 1039c4b..7269155 100644 --- a/security-migrate-database-principals.sql +++ b/security-migrate-database-principals.sql @@ -1,6 +1,7 @@ DECLARE @sql VARCHAR(2048) ,@sort INT - ,@login VARCHAR(128) = NULL; + ,@login VARCHAR(128) = 'src_login' + ,@login_mirror VARCHAR(128) = 'tgt_login'; DECLARE tmp CURSOR FOR @@ -23,7 +24,7 @@ UNION ALL SELECT '-- [-- DB USERS --] --' AS [-- SQL STATEMENTS --] ,3 AS [-- RESULT ORDER HOLDER --] UNION ALL -SELECT 'IF NOT EXISTS (SELECT [name] FROM sys.database_principals WHERE [name] =' + SPACE(1) + '''' + [name] + '''' + ') BEGIN CREATE USER ' + SPACE(1) + QUOTENAME([name]) + ' FOR LOGIN ' + QUOTENAME([name]) + ' WITH DEFAULT_SCHEMA = ' + QUOTENAME([default_schema_name]) + SPACE(1) + 'END;' AS [-- SQL STATEMENTS --] +SELECT 'IF NOT EXISTS (SELECT [name] FROM sys.database_principals WHERE [name] =' + SPACE(1) + '''' + ISNULL(@login_mirror,[name]) + '''' + ') BEGIN CREATE USER ' + SPACE(1) + QUOTENAME(ISNULL(@login_mirror,[name])) + ' FOR LOGIN ' + QUOTENAME(ISNULL(@login_mirror,[name])) + ' WITH DEFAULT_SCHEMA = ' + QUOTENAME([default_schema_name]) + SPACE(1) + 'END;' AS [-- SQL STATEMENTS --] ,3 AS [-- RESULT ORDER HOLDER --] FROM sys.database_principals WHERE [type] IN ('U', 'S', 'G') -- windows users, sql users, windows groups @@ -40,7 +41,7 @@ UNION ALL SELECT '-- [-- DB ROLES --] --' AS [-- SQL STATEMENTS --] ,5 AS [-- RESULT ORDER HOLDER --] UNION ALL -SELECT 'ALTER ROLE ' + QUOTENAME(USER_NAME(rm.[role_principal_id])) + ' ADD MEMBER ' + QUOTENAME(USER_NAME(rm.[member_principal_id])) + ';' AS [-- SQL STATEMENTS --] +SELECT 'ALTER ROLE ' + QUOTENAME(USER_NAME(rm.[role_principal_id])) + ' ADD MEMBER ' + QUOTENAME(ISNULL(@login_mirror,USER_NAME(rm.[member_principal_id]))) + ';' AS [-- SQL STATEMENTS --] ,6 AS [-- RESULT ORDER HOLDER --] FROM sys.database_role_members AS rm WHERE USER_NAME(rm.[member_principal_id]) IN ( @@ -71,7 +72,7 @@ SELECT CASE WHEN c.[column_id] IS NULL THEN SPACE(0) ELSE '(' + QUOTENAME(c.[name]) + ')' END - + SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(USER_NAME(dp.[principal_id])) COLLATE DATABASE_DEFAULT + + SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(ISNULL(@login_mirror,USER_NAME(dp.[principal_id]))) COLLATE DATABASE_DEFAULT + CASE WHEN p.[state] <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' @@ -101,7 +102,7 @@ SELECT CASE ELSE 'GRANT' END + SPACE(1) + p.[permission_name] - + SPACE(1) + 'TO' + SPACE(1) + '[' + USER_NAME(dp.[principal_id]) + ']' COLLATE DATABASE_DEFAULT + + SPACE(1) + 'TO' + SPACE(1) + '[' + ISNULL(@login_mirror,USER_NAME(dp.[principal_id])) + ']' COLLATE DATABASE_DEFAULT + CASE WHEN p.[state] <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' @@ -132,7 +133,7 @@ SELECT CASE + SPACE(1) + p.[permission_name] + SPACE(1) + 'ON' + SPACE(1) + p.[class_desc] + '::' COLLATE DATABASE_DEFAULT + QUOTENAME(SCHEMA_NAME(p.[major_id])) - + SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(USER_NAME(p.[grantee_principal_id])) COLLATE DATABASE_DEFAULT + + SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(ISNULL(@login_mirror,USER_NAME(p.[grantee_principal_id]))) COLLATE DATABASE_DEFAULT + CASE WHEN p.[state] <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' diff --git a/server-get-buffer-usage-by-database.sql b/server-get-buffer-usage-by-database.sql new file mode 100644 index 0000000..cd0c794 --- /dev/null +++ b/server-get-buffer-usage-by-database.sql @@ -0,0 +1,28 @@ +/* +Determine SQL Server memory use by database and object +https://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/ + +-- Note: querying sys.dm_os_buffer_descriptors +-- requires the VIEW_SERVER_STATE permission. +*/ + +DECLARE @total_buffer INT; + +SELECT @total_buffer = cntr_value +FROM sys.dm_os_performance_counters +WHERE RTRIM([object_name]) LIKE '%Buffer Manager' +AND counter_name = 'Database Pages'; + +WITH src AS ( + SELECT database_id, db_buffer_pages = COUNT_BIG(*) + FROM sys.dm_os_buffer_descriptors + GROUP BY database_id +) +SELECT [db_name] = CASE [database_id] WHEN 32767 THEN 'Resource DB' ELSE DB_NAME([database_id]) END, +db_buffer_pages, +db_buffer_MB = db_buffer_pages / 128, +db_buffer_percent = CONVERT(DECIMAL(6,3), +db_buffer_pages * 100.0 / @total_buffer) +FROM src +ORDER BY db_buffer_MB DESC; + diff --git a/server-get-io-snapshot.sql b/server-get-io-snapshot.sql index 0406fc3..82cfbc8 100644 --- a/server-get-io-snapshot.sql +++ b/server-get-io-snapshot.sql @@ -91,8 +91,8 @@ FROM [DiffLatencies] AS [vfs] JOIN sys.master_files AS [mf] ON [vfs].[database_id] = [mf].[database_id] AND [vfs].[file_id] = [mf].[file_id] ---ORDER BY [ReadLatency(ms)] DESC; -ORDER BY [WriteLatency(ms)] DESC; +ORDER BY [ReadLatency(ms)] DESC; +--ORDER BY [WriteLatency(ms)] DESC; GO -- Cleanup diff --git a/sp_who_is_active-run-as-script.sql b/sp_who_is_active-run-as-script.sql index 9f11e54..277fb8b 100644 --- a/sp_who_is_active-run-as-script.sql +++ b/sp_who_is_active-run-as-script.sql @@ -9,19 +9,14 @@ GO Who Is Active? v11.17 (2016-10-18) (C) 2007-2016, Adam Machanic -Feedback: mailto:amachanic@gmail.com5 +Feedback: mailto:amachanic@gmail.com Updates: http://whoisactive.com -kill 375; -kill 171; -kill 389; -kill 383; -kill 492; -kill 376; + License: Who is Active? is free to download and use for personal, educational, and internal corporate purposes, provided that this header is preserved. Redistribution or sale of Who is Active?, in whole or in part, is prohibited without the author's express - written consent. + written consent. *********************************************************************************************/ --ALTER PROC dbo.sp_WhoIsActive --( @@ -32,8 +27,8 @@ DECLARE --Valid filter types are: session, program, database, login, and host --Session is a session ID, and either 0 or '' can be used to indicate "all" sessions --All other filter types support % or _ as wildcards - @filter sysname = '', --kill 320 - @filter_type VARCHAR(10) = 'session', + @filter sysname = '', --kill 320 10.90.70.246 + @filter_type VARCHAR(10) = 'login', @not_filter sysname = '', @not_filter_type VARCHAR(10) = 'session', diff --git a/sql-agent-job-get-new-or-modified.sql b/sql-agent-job-get-new-or-modified.sql new file mode 100644 index 0000000..2b5158d --- /dev/null +++ b/sql-agent-job-get-new-or-modified.sql @@ -0,0 +1,21 @@ +DECLARE @Date DATETIME = '2021-05-11 14:15:46.250'; + +-- JOBS CREATED SINCE @Date +SELECT j.name AS JobName + ,l.name AS JobOwner + ,j.date_created + ,j.enabled +FROM msdb.dbo.sysjobs AS J + JOIN sys.server_principals AS L ON J.owner_sid = L.sid +WHERE j.date_created > @Date +ORDER BY j.name; + +-- JOBS MODIFIED SINCE @Date +SELECT j.name AS JobName + ,l.name AS JobOwner + ,j.date_modified + ,j.enabled +FROM msdb.dbo.sysjobs AS J + JOIN sys.server_principals AS L ON J.owner_sid = L.[sid] +WHERE j.date_modified > @Date +ORDER BY j.name; diff --git a/wait-stats-RESOURCE_SEMAPHORE.sql b/wait-stats-RESOURCE_SEMAPHORE.sql new file mode 100644 index 0000000..3d364ba --- /dev/null +++ b/wait-stats-RESOURCE_SEMAPHORE.sql @@ -0,0 +1,62 @@ +/* +SQL SERVER – List Number Queries Waiting for Memory Grant Pending +https://blog.sqlauthority.com/2019/12/10/sql-server-list-number-queries-waiting-for-memory-grant-pending/ + +Poison Wait Detected: RESOURCE_SEMAPHORE +https://social.msdn.microsoft.com/Forums/SqlServer/en-US/61352bc0-8f8f-4e41-8121-4f6d16fdc0f2/poison-wait-detected-resourcesemaphore?forum=sqldatabaseengine +*/ + +-- OS MEMORY AND STATE +-- state = 'Available physical memory is high' indicates not under external memory pressure +SELECT (total_physical_memory_kb/1024/1024) total_physical_memory_GB -- Total size of physical memory available to the operating system, in KB + ,(available_physical_memory_kb/1024/1024) available_physical_memory_GB -- Size of physical memory available, in KB + ,(total_page_file_kb/1024/1024) total_page_file_GB -- Size of the commit limit reported by the operating system, in KB + ,(available_page_file_kb/1024/1024) available_page_file_GB -- Total amount of page file that is not being used, in KB + ,system_memory_state_desc -- Description of the memory state +FROM sys.dm_os_sys_memory WITH (NOLOCK) OPTION (RECOMPILE); + +-- MEMORY ALLOCATED TO SQL SERVER +--(shows whether locked pages is enabled, among other things) +-- process_physical_memory_low = 0 AND process_virtual_memory_low = 0 indicates not under internal memory pressure +SELECT (physical_memory_in_use_kb/1024/1024) physical_memory_in_use_GB -- Working set, in KB, as reported by OS + ,(locked_page_allocations_kb/1024/1024) locked_page_allocations_GB -- Memory pages locked in memory + ,page_fault_count -- Number of page faults incurred by SQL Server process + ,memory_utilization_percentage -- Percentage of committed memory that is in the working set + ,(available_commit_limit_kb/1024/1024) available_commit_limit_GB -- Amount of memory available to be committed by the process + ,process_physical_memory_low -- Indicates process is responding to low physical memory notification + ,process_virtual_memory_low -- Indicates low virtual memory condition has been detected +FROM sys.dm_os_process_memory WITH (NOLOCK) OPTION (RECOMPILE); + +-- HOW MANY QUERIES ARE WAITING FOR A MEMORY GRANT +SELECT @@SERVERNAME AS [Server Name] + ,[cntr_value] AS [Memory Grants Pending] +FROM sys.dm_os_performance_counters WITH (NOLOCK) +WHERE [object_name] LIKE N'%Memory Manager%' +AND [counter_name] = N'Memory Grants Pending'; + +-- ACTIVE QUERIES REQUIRING A MEMORY GRANT +SELECT mg.session_id + ,(mg.requested_memory_kb/1024) requested_memory_MB -- Total requested amount of memory, in KB + ,(mg.granted_memory_kb/1024) granted_memory_MB -- Total amount of memory granted, in KB + ,(mg.required_memory_kb/1024) required_memory_MB -- Minimum memory required to run this query, in KB + ,(mg.used_memory_kb/1024) used_memory_MB -- Physical memory used at this moment, in KB + ,(mg.ideal_memory_kb/1024) ideal_memory_MB -- Size, in KB, of memory grant to fit everything into physical memory (based on cardinality estimate) + ,mg.request_time -- Date and time when this query requested the memory grant + ,mg.grant_time -- Date and time when memory was granted for this query (NULL if memory is not granted yet) + ,mg.query_cost -- Estimated query cost + ,mg.dop -- Degree of parallelism of this query + ,mg.wait_order + ,DB_NAME(s.database_id) as [database] + ,st.[TEXT] AS query_text + ,s.login_name + ,s.host_name + ,s.program_name + ,qp.query_plan +FROM sys.dm_exec_query_memory_grants AS mg + CROSS APPLY sys.dm_exec_sql_text(mg.plan_handle) AS st + CROSS APPLY sys.dm_exec_query_plan(mg.plan_handle) AS qp + JOIN sys.dm_exec_sessions AS s ON mg.session_id = s.session_id +ORDER BY mg.granted_memory_kb DESC + ,mg.grant_time + ,mg.wait_order; +