Blocking Chain
Blocking Chain
Identify blocking chain processes and head of the blocking chain with wait types.
Select Session_ID,Blocking_Session_ID From Sys.dm_Exec_Requests Where Session_ID > 50 And Blocking_Session_Id <> 0
SELECT spid ,sp.STATUS ,loginame ,hostname ,blocked ,open_tran ,dbname = SUBSTRING(DB_NAME(sp.dbid),1,50) ,cmd ,waittype ,waittime ,last_batch ,SQLStatement = SUBSTRING ( qt.text, er.statement_start_offset/2, (CASE WHEN er.statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(MAX), qt.text)) * 2 ELSE er.statement_end_offset END - er.statement_start_offset)/2 ) FROM master.dbo.sysprocesses sp LEFT JOIN sys.dm_exec_requests er ON er.session_id = sp.spid OUTER APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt WHERE spid IN (SELECT blocked FROM master.dbo.sysprocesses) AND blocked = 0
StoredProcs
Execution Counts
Query to gather stored procedure execution count , average and max elapsed time , reads, writes
SELECT @@SERVERNAME ServerName, DB_NAME() AS DatabaseName, object_id ObjectID , OBJECT_NAME(object_id) StoredProcName , OBJECT_SCHEMA_NAME(object_id) AS SchemaName, cached_time AS CachedDateTime , execution_count , total_elapsed_time / ( 1000 * execution_count ) AS Avg_elapsed_time , min_elapsed_time / 1000 AS min_elapsed_time , max_elapsed_time / 1000 AS max_elapsed_time , total_logical_reads / execution_count AS Avg_logical_reads , total_physical_reads / execution_count AS Avg_physical_reads FROM sys.dm_exec_procedure_stats WITH ( NOLOCK ) WHERE OBJECT_NAME(object_id) IS NOT NULL AND type = 'P' AND database_id = DB_ID() ORDER BY execution_count DESC ;
SPID-SQLText
DECLARE @spid INT SELECT @spid = 70 SELECT req.session_id , req.start_time , req.status , req.wait_type , req.last_wait_type , req.logical_reads , req.total_elapsed_time , sqltext.text QueryText , SUBSTRING(sqltext.text, ( req.statement_start_offset / 2 ) + 1, ( ( CASE req.statement_end_offset WHEN -1 THEN DATALENGTH(sqltext.text) ELSE req.statement_end_offset END - req.statement_start_offset ) / 2 ) + 1) AS StatementText , plantext.query_plan FROM sys.dm_exec_requests req CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) sqltext CROSS APPLY sys.dm_exec_query_plan(req.plan_handle) plantext WHERE req.session_id = @spid
RowCounts
; WITH Table_RowCnt_SpaceUsed AS ( SELECT object_id , reservedpages = SUM(reserved_page_count) , usedpages = SUM(used_page_count) , pages = SUM(CASE WHEN ( index_id < 2 ) THEN ( in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count ) ELSE lob_used_page_count + row_overflow_used_page_count END) , row_Count = SUM(CASE WHEN ( index_id < 2 ) THEN row_count ELSE 0 END) FROM sys.dm_db_partition_stats GROUP BY object_id ) SELECT schema_name = OBJECT_SCHEMA_NAME(object_id) , table_name = OBJECT_NAME(object_id) , row_Count , reserved = LTRIM(STR(reservedpages * 8, 15, 0) + ' KB') , data = LTRIM(STR(pages * 8, 15, 0) + ' KB') , index_size = LTRIM(STR(( CASE WHEN usedpages > pages THEN ( usedpages - pages ) ELSE 0 END ) * 8, 15, 0) + ' KB') , unused = LTRIM(STR(( CASE WHEN reservedpages > usedpages THEN ( reservedpages - usedpages ) ELSE 0 END ) * 8, 15, 0) + ' KB') FROM Table_RowCnt_SpaceUsed WHERE OBJECT_SCHEMA_NAME(object_id) IN ( 'ls','dbo' ) ORDER BY Table_RowCnt_SpaceUsed.row_Count DESC;
RenameDB
-- Enable SQLCMD Mode to Run this Script :SETVAR pOldDatabaseName "Util" :SETVAR pNewDatabaseName "UtilNew" USE master; GO ALTER DATABASE $(pOldDatabaseName) SET SINGLE_USER WITH ROLLBACK IMMEDIATE; GO USE master; GO ALTER DATABASE $(pOldDatabaseName) Modify Name = $(pNewDatabaseName); GO USE master; GO ALTER DATABASE $(pNewDatabaseName) SET MULTI_USER WITH ROLLBACK IMMEDIATE; GO
Kill SPIDS to Obtain Exclusive Database Lock
USE master GO ALTER DATABASE AdventureWorks SET OFFLINE WITH ROLLBACK IMMEDIATE /* Msg 5061, Level 16, State 1, Line 4 ALTER DATABASE failed because a lock could not be placed on database 'AdventureWorks'. Try again later. Msg 5069, Level 16, State 1, Line 4 ALTER DATABASE statement failed. */ USE [master] GO DECLARE @kill varchar(8000) = ''; SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';' + CHAR(13) FROM sys.dm_exec_sessions WHERE database_id = db_id('AdventureWorks') SELECT @kill -- kill 57; kill 58; kill 62; kill 64; kill 67; kill 68; EXEC(@kill);
ClusterInfo
SELECT VirtualServerName = SERVERPROPERTY('ServerName') , ActiveNode = SERVERPROPERTY('ComputerNamePhysicalNetBIOS') , PassiveNode = CASE ( SELECT SERVERPROPERTY('IsClustered') ) WHEN 0 THEN 'Stand-Alone' WHEN 1 THEN ( SELECT NodeName FROM sys.dm_os_cluster_nodes WHERE NodeName <> SERVERPROPERTY('ComputerNamePhysicalNetBIOS') ) ELSE CAST(( SELECT COUNT(*) FROM sys.dm_os_cluster_nodes WHERE NodeName <> SERVERPROPERTY('ComputerNamePhysicalNetBIOS') ) AS VARCHAR(2)) + ' Passive Nodes' END SELECT PassiveNodes = NodeName FROM sys.dm_os_cluster_nodes WHERE NodeName <> SERVERPROPERTY('ComputerNamePhysicalNetBIOS') SELECT ClusterDrives = DriveName FROM sys.dm_io_cluster_shared_drives ORDER BY DriveName SELECT @@SERVERNAME -- NVSQL3A SELECT SERVERPROPERTY('ComputerNamePhysicalNetBIOS') SELECT * FROM sys.dm_os_cluster_nodes
Backup-Restore
BACKUP DATABASE DatabaseName TO DISK ='\\NetworkShare\DatabaseName.bak' WITH COMPRESSION,COPY_ONLY , CHECKSUM RESTORE VERIFYONLY FROM DISK = '\\NetworkShare\DatabaseName.bak' RESTORE FILELISTONLY FROM DISK ='\\NetworkShare\DatabaseName.bak' RESTORE HEADERONLY FROM DISK = '\\NetworkShare\DatabaseName.bak' RESTORE LABELONLY FROM DISK = '\\NetworkShare\DatabaseName.bak' RESTORE DATABASE DatabaseName FROM DISK ='\\NetworkShare\DatabaseName.bak' WITH MOVE 'DataFileName' TO 'DataDrive\DataFileName.mdf' , MOVE 'LogFileName' TO 'LogDrive\LogFileName.mdf' ,REPLACE
Dynamic Restore from Backup Flie
http://ramblingsofraju.com/sql-server/dynamically-restore-sql-server-database-from-backup/
— Identify Restored Database Source and TimeStamp
SELECT [rs].[destination_database_name] , [rs].[restore_date] , [bs].[backup_start_date] , [bs].[backup_finish_date] , [bs].[database_name] AS [source_database_name] , [bmf].[physical_device_name] AS [backup_file_used_for_restore] FROM msdb..restorehistory rs INNER JOIN msdb..backupset bs ON [rs].[backup_set_id] = [bs].[backup_set_id] INNER JOIN msdb..backupmediafamily bmf ON [bs].[media_set_id] = [bmf].[media_set_id] ORDER BY [rs].[restore_date] DESC
xp_cmdshell
EXEC sys.xp_cmdshell 'dir \\networkshare-nas\share\' /* Msg 15281, Level 16, State 1, Procedure xp_cmdshell, Line 1 SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online. */ SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell' EXEC sp_configure 'show advanced options', 1; GO RECONFIGURE; GO EXEC sp_configure 'xp_cmdshell', 1; GO RECONFIGURE; GO SELECT * FROM sys.configurations WHERE name = 'clr enabled' /* configuration_id name value minimum maximum value_in_use description is_dynamic is_advanced 16390 xp_cmdshell 0 0 1 0 Enable or disable command shell 1 1 */
EXEC sys.xp_cmdshell 'dir \\networkshare-nas\share\' /* Msg 15281, Level 16, State 1, Procedure xp_cmdshell, Line 1 SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online. */ SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell' EXEC sp_configure 'show advanced options', 1; GO RECONFIGURE; GO EXEC sp_configure 'xp_cmdshell', 1; GO RECONFIGURE; GO SELECT * FROM sys.configurations WHERE name = 'clr enabled' /* configuration_id name value minimum maximum value_in_use description is_dynamic is_advanced 16390 xp_cmdshell 0 0 1 0 Enable or disable command shell 1 1 */
Security
Script to Create a Login , Create Database User from the Login
and Granting SELECT,UPDATE,INSERT,DELETE,EXEC Permissions
/****************************************************************************************************** ** Desc: Create SampleLoginName login ** Auth: Raju Venkataraman ** Date: 07/27/2016 Created ************************** ** Change History ************************** ** CR Date Author Description 1 07/27/2016 Raju Venkataraman Create SampleLoginName Login and grant EXEC AND CRUD Permissions ** ----- ----------------------- ------------------------------------------------------------ ********************************************************************************************************/ SET ARITHABORT ON SET CONCAT_NULL_YIELDS_NULL ON SET QUOTED_IDENTIFIER ON SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON SET NUMERIC_ROUNDABORT OFF SET XACT_ABORT ON -----------BEGIN SQL SCRIPT HEADER------------------- DECLARE @DB_NAME VARCHAR(128) SET @DB_NAME = (SELECT DB_NAME(dbid) FROM MASTER..SYSPROCESSES WHERE spid=@@SPID) PRINT '-----------------------------------------------------------------------' PRINT '-----START RAPID DEVELOPEMENT SQL SCRIPT--------' PRINT '-----SQL COMPILED BY: Raju Venkataraman' PRINT '-----SCRIPT RAN ON DB: ' + @DB_NAME PRINT '-----SCRIPT START TIME: ' + CONVERT(VARCHAR,CONVERT(DATETIME,GETDATE()),121) PRINT '-----MachineName : ' + cast( serverproperty ( 'MachineName' ) as varchar ) PRINT '-----SQL Instance : ' + cast( @@SERVERNAME as varchar ) PRINT '-----DB User : ' + current_user PRINT '-----System User : ' + system_user PRINT '-----Host : ' + host_name() PRINT '-----Application : ' + app_name() PRINT '-----TranCount : ' + cast (@@trancount as varchar) PRINT '-----------------------------------------------------------------------' GO ----------------END SQL SCRIPT HEADER--------------------- BEGIN BEGIN TRY USE MASTER IF NOT EXISTS (SELECT 1 FROM master.sys.sql_logins WHERE [name] = 'SampleLoginName') CREATE LOGIN [LoginName] WITH PASSWORD='passwordvalue', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF USE AdventureWorks IF DB_NAME()<>'AdventureWorks' RAISERROR('AdventureWorks Database Doesn''t exist in this Server',16,1) IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE [name] = 'SampleLoginName') Begin CREATE USER [LoginName] FOR LOGIN [LoginName] GRANT SELECT,UPDATE,INSERT,DELETE,EXEC TO [LoginName]; End END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; DECLARE @ErrorNumber INT = ERROR_NUMBER(); DECLARE @ErrorLine INT = ERROR_LINE(); DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE(); DECLARE @ErrorSeverity INT = ERROR_SEVERITY(); DECLARE @ErrorState INT = ERROR_STATE(); RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState); END CATCH END; GO -------BEGIN SQL SCRIPT FOOTER------------------------------------ PRINT '-----------------------------------------------------------' PRINT '-------------------FINISHED SQL SCRIPT---------------------' PRINT '--COMPLETED TIME:' + CONVERT(VARCHAR,CONVERT(DATETIME,GETDATE()),121) PRINT '--TranCount : ' + cast (@@trancount as varchar) PRINT '------------------------------------------------------------'
Enable successful and Failed Logins
-- To Enable Failed and Successful Logins . By Default Only Failed Logins are Captured -- Need to Restart the Server for this to effect EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'AuditLevel', REG_DWORD, 3; GO
Query Error Log for Successful and Failed Logins
-- Query for Successful Logins EXEC sys.sp_readerrorlog @p1 = 0, -- int -- 0 = current, 1 = Archive #1, 2 = Archive @p2 = 1, -- int -- 1 or NULL = error log, 2 = SQL Agent log @p3 = 'succe', -- varchar(255) -- String one we want to search for @p4 = 'login' -- varchar(255) -- String two we want to search to further refine the result -- Login succeeded for user 'xxxxxx'. Connection made using Windows authentication. [CLIENT: xx.xx.xx.xx] -- Query for Failed Logins EXEC sys.sp_readerrorlog @p1 = 0, -- int -- 0 = current, 1 = Archive #1, 2 = Archive @p2 = 1, -- int -- 1 or NULL = error log, 2 = SQL Agent log @p3 = 'failed', -- varchar(255) -- String one we want to search for @p4 = 'login' -- varchar(255) -- String two we want to search to further refine the result -- Login failed for user ''. Reason: Could not find a login matching the name provided. [CLIENT: ]
Enumerate User Permissions
EXECUTE AS USER = 'samplelogin'; SELECT * FROM fn_my_permissions(NULL, 'DATABASE'); REVERT;
Enumerate Database Owners and Change it to “SA”
SELECT SUSER_SNAME(owner_sid) DatabaseOwner , * FROM sys.databases; SELECT 'ALTER AUTHORIZATION ON DATABASE::' + QUOTENAME(name) + ' TO [sa];' FROM sys.databases WHERE name NOT IN ( 'master', 'model', 'tempdb' ); ALTER AUTHORIZATION ON DATABASE::[Demo] TO [sa];
Indexes
Useful queries for identifying least and most used indexes , quick way rebuild all indexes , gather index name and size .
Least Used 20 Indexes
SELECT TOP 20 @@SERVERNAME ServerName, DB_NAME() AS DatabaseName, o.name AS ObjectName , i.name AS IndexName , i.index_id AS IndexID , dm_ius.user_seeks AS UserSeek , dm_ius.user_scans AS UserScans , dm_ius.user_lookups AS UserLookups , dm_ius.user_updates AS UserUpdates , p.TableRows FROM sys.dm_db_index_usage_stats dm_ius INNER JOIN sys.indexes i ON i.index_id = dm_ius.index_id AND dm_ius.object_id = i.object_id INNER JOIN sys.objects o ON dm_ius.object_id = o.object_id INNER JOIN sys.schemas s ON o.schema_id = s.schema_id INNER JOIN ( SELECT SUM(p.rows) TableRows , p.index_id , p.object_id FROM sys.partitions p GROUP BY p.index_id , p.object_id ) p ON p.index_id = dm_ius.index_id AND dm_ius.object_id = p.object_id WHERE OBJECTPROPERTY(dm_ius.object_id, 'IsUserTable') = 1 AND dm_ius.database_id = DB_ID() AND i.type_desc = 'nonclustered' AND i.is_primary_key = 0 AND i.is_unique_constraint = 0 AND p.TableRows > 1000 ORDER BY ( dm_ius.user_seeks + dm_ius.user_scans + dm_ius.user_lookups + dm_ius.user_updates ) ASC;
Results
ServerName | DatabaseName | ObjectName | IndexID | Seeks | Scans | Lookups | Updates | Rows |
---|---|---|---|---|---|---|---|---|
DevSQLServer | SampleDB | FileValidationError | 6 | 3 | 0 | 0 | 77 | 17928 |
DevSQLServer | SampleDB | FileValidationError | 8 | 11 | 1 | 0 | 77 | 17928 |
DevSQLServer | SampleDB | FileValidationError | 7 | 11 | 5 | 0 | 77 | 17928 |
Top 20 Most Fragmented Objects
SELECT TOP 20 @@SERVERNAME ServerName, DB_NAME() DatabaseName, OBJECT_NAME(ind.object_id) AS TableName , ind.name AS IndexName , indexstats.index_type_desc AS IndexType , indexstats.avg_fragmentation_in_percent FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats INNER JOIN sys.indexes ind ON ind.object_id = indexstats.object_id AND ind.index_id = indexstats.index_id WHERE indexstats.avg_fragmentation_in_percent > 25 ORDER BY indexstats.avg_fragmentation_in_percent DESC;
Results:
ServerName | DatabaseName | TableName | IndexName | IndexType | avg_fragmentation_in_percent |
---|---|---|---|---|---|
DEVSQLServer | Jira | userhistoryitem | uh_type_user_entity | NONCLUSTERED INDEX | 98.0582524271845 |
DEVSQLServer | Jira | changegroup | chggroup_issue | NONCLUSTERED INDEX | 96.6207759699625 |
DEVSQLServer | Jira | cwd_user_attributes | idx_user_attr_dir_name_lval | NONCLUSTERED INDEX | 96.4285714285714 |
DEVSQLServer | Jira | AO_7DEABF_SCHEDULE | pk_AO_7DEABF_SCHEDULE_ID | CLUSTERED INDEX | 96.2962962962963 |
DEVSQLServer | Jira | jiraissue | issue_assignee | NONCLUSTERED INDEX | 95.7894736842105 |
DEVSQLServer | Jira | AO_575BF5_PROVIDER_ISSUE | index_ao_575bf5_pro741170824 | NONCLUSTERED INDEX | 95.4545454545455 |
DEVSQLServer | Jira | remembermetoken | remembermetoken_username_index | NONCLUSTERED INDEX | 95 |
DEVSQLServer | Jira | AO_7DEABF_TESTSTEP | pk_AO_7DEABF_TESTSTEP_ID | CLUSTERED INDEX | 95 |
DEVSQLServer | Jira | cwd_user_attributes | PK_cwd_user_attributes | CLUSTERED INDEX | 94.7368421052632 |
DEVSQLServer | Jira | AO_7DEABF_CHANGE_ZJEITEM | pk_AO_7DEABF_CHANGE_ZJEITEM_ID | CLUSTERED INDEX | 94.6843853820598 |
Missing Indexes
SELECT TOP 20 @@SERVERNAME ServerName, DB_NAME(dm_mid.database_id) AS DatabaseName , OBJECT_NAME(dm_mid.object_id, dm_mid.database_id) TableName , dm_migs.user_seeks , dm_migs.user_scans , dm_mid.equality_columns , dm_mid.included_columns , dm_migs.avg_user_impact * ( dm_migs.user_seeks + dm_migs.user_scans ) Avg_Estimated_Impact , dm_migs.last_user_seek AS Last_User_Seek FROM sys.dm_db_missing_index_groups dm_mig INNER JOIN sys.dm_db_missing_index_group_stats dm_migs ON dm_migs.group_handle = dm_mig.index_group_handle INNER JOIN sys.dm_db_missing_index_details dm_mid ON dm_mig.index_handle = dm_mid.index_handle WHERE dm_mid.database_id = DB_ID() ORDER BY dm_migs.user_seeks + dm_migs.user_scans DESC;
Results
ServerName | DatabaseName | TableName | user_seeks | user_scans | equality_columns | included_columns | Avg_Estimated_Impact | Last_User_Seek |
---|---|---|---|---|---|---|---|---|
DEVSQLServer | Jira | propertyentry | 34416 | 0 | [ENTITY_NAME], [ENTITY_ID] | NULL | 3158356.32 | 2016-08-03 19:36:46.173 |
DEVSQLServer | Jira | jiraaction | 6 | 0 | [AUTHOR] | [issueid], [CREATED] | 435 | 2016-08-03 14:05:17.617 |
DEVSQLServer | Jira | jiraaction | 3 | 0 | [actiontype] | NULL | 181.74 | 2016-08-02 09:36:57.623 |
DEVSQLServer | Jira | userhistoryitem | 2 | 0 | NULL | [ID] | 186.8 | 2016-08-03 14:05:57.240 |
DEVSQLServer | Jira | changegroup | 1 | 0 | [AUTHOR] | [issueid], [CREATED] | 50.59 | 2016-08-03 10:50:46.970 |
Percentiles
Percentile Calculation
This comes very handy to calculate percentiles for stored procedure Duration which are captured in Trace Files.
-- Percentile Calculation SELECT StoredProcName -- A crosstab query to aggregate the results , [25th Percentile] = MAX([25th Percentile]) , [50th Percentile] = MAX([50th Percentile]) , [75th Percentile] = MAX([75th Percentile]) , [100th Percentile] = MAX([100th Percentile]) FROM ( SELECT StoredProcName -- Calculate percentile rankings of interest (25%, 50%, 75%, 100%) , [25th Percentile] = PERCENTILE_CONT(0.25) WITHIN GROUP ( ORDER BY Duration ) OVER ( PARTITION BY StoredProcName ) , [50th Percentile] = PERCENTILE_CONT(0.50) WITHIN GROUP ( ORDER BY Duration ) OVER ( PARTITION BY StoredProcName ) , [75th Percentile] = PERCENTILE_CONT(0.75) WITHIN GROUP ( ORDER BY Duration ) OVER ( PARTITION BY StoredProcName ) , [100th Percentile] = PERCENTILE_CONT(1.00) WITHIN GROUP ( ORDER BY Duration ) OVER ( PARTITION BY StoredProcName ) FROM ( SELECT LEFT(TextData,( CHARINDEX('@', TextData,CHARINDEX('dbo', TextData)) ) - 1) AS StoredProcName , [Reads] , [Writes] , [CPU] , [ServerName] , [Duration] , [StartTime] , [EndTime] FROM [ITTools].[dbo].[AWSRDSTrace] WHERE ( CHARINDEX('@', TextData, CHARINDEX('dbo', TextData)) ) > 0 ) der ) a GROUP BY StoredProcName;
StoredProcName | 25th Percentile | 50th Percentile | 75th Percentile | 100th Percentile |
---|---|---|---|---|
exec [dbo].[ProcA] | 6256.25 | 8246 | 12213.75 | 5799489 |
exec [dbo].[ProcB] | 33267.25 | 57639.5 | 154683.25 | 163191464 |
exec [dbo].[ProcC] | 6059.75 | 8376 | 14027 | 5796761 |
exec [dbo].[ProcD] | 3796 | 4731 | 11467 | 19218 |
Misc
Miscellaneous queries
SELECT @@SERVERNAME ServerName,local_net_address,local_tcp_port FROM sys.dm_exec_connections WHERE session_id = @@SPID AND net_transport ='TCP'
EXEC master..xp_logininfo 'DomainName\DevTeam', @option = 'members' /* account name type privilege mapped login name permission path DomainName\username user user DomainName\username DomainName\NTGroupName */ EXEC sys.sp_MSloginmappings @loginname = N'DomainName\GroupName', -- nvarchar(258) @flags = 0 -- int
EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'
Maintenance
Available Drive Space
-- Gather Space Availability Data DECLARE @DriveSpace TABLE ( [DriveLetter] NVARCHAR(255) , [SpaceFreeinMB] NVARCHAR(255) ); INSERT INTO @DriveSpace EXEC xp_fixeddrives; SELECT @@SERVERNAME , [DriveLetter] , [SpaceFreeinMB] FROM @DriveSpace;
Results:
ServerName | DriveLetter | SpaceFreeinMB |
---|---|---|
DevSQLServer | G | 2108673 |
DevSQLServer | L | 694004 |
DevSQLServer | T | 452866 |
Virtual File Stats:
Returns I/O statistics for database files, including log files
Function Usuage : fn_virtualfilestats ( { database_id | NULL } , { file_id | NULL } )
https://msdn.microsoft.com/en-us/library/ms187309.aspx
SELECT @@SERVERNAME AS ServerName , LEFT(saf.[filename], 1) + ':' AS DriveLetter , COUNT(saf.fileid) AS NumFiles , CAST (SUM(saf.[size] / 128.0) AS NUMERIC(18, 3)) AS SizeMB , -- convert to Megabytes from 8-k pages SUM(NumberReads) AS NumberReads , SUM(NumberWrites) AS NumberWrites , CAST(SUM(BytesRead) AS NUMERIC) / ( 1024 * 1024 * 1024 ) AS BytesRead_GB , CAST (SUM(BytesWritten) AS NUMERIC) / ( 1024 * 1024 * 1024 ) AS BytesWritten_GB , SUM(IoStallMS) AS IoStallMS FROM :: fn_virtualfilestats(DB_ID(), NULL) vfs -- NULL for all Databaes INNER JOIN master..sysaltfiles saf ON vfs.dbid = saf.dbid AND vfs.fileid = saf.fileid GROUP BY LEFT(saf.[filename], 1) + ':' ORDER BY DriveLetter ASC;
Virtual File Stats
ServerName | Drive | NumFiles | SizeMB | NbrReads | NbrWrites | BytesRead_GB | BytesWritten_GB | IoStallMS |
---|---|---|---|---|---|---|---|---|
DEVServer | G: | 67 | 2719097.188 | 16836383 | 39788032 | 9961.03092670440 | 630.40092325210 | 2012394598 |
DEVServer | L: | 45 | 1019043.461 | 218901 | 8443038 | 10.14563369750 | 121.29507875442 | 36124905 |
DEVServer | T: | 9 | 5120.000 | 12317258 | 21437262 | 623.82694625854 | 787.39944887161 | 2371380991 |
Virtual File Stats by Database
SELECT @@SERVERNAME AS ServerName , d.name AS [Database] , f.physical_name AS [File] , ( fs.num_of_bytes_read / 1024.0 / 1024.0 ) [Total MB Read] , ( fs.num_of_bytes_written / 1024.0 / 1024.0 ) AS [Total MB Written] , ( fs.num_of_reads + fs.num_of_writes ) AS [Total I/O Count] , fs.io_stall AS [Total I/O Wait Time (ms)] , fs.size_on_disk_bytes / 1024 / 1024 AS [Size (MB)] FROM sys.dm_io_virtual_file_stats(DEFAULT, DEFAULT) AS fs INNER JOIN sys.master_files f ON fs.database_id = f.database_id AND fs.file_id = f.file_id INNER JOIN sys.databases d ON d.database_id = fs.database_id;
ServerName | Database | File | Total MB Read | Total MB Written | Total I/O Count | Total I/O Wait Time (ms) | Size (MB) |
---|---|---|---|---|---|---|---|
DEVSQLServer | master | K:\SQLServer\MSSQL\DATA\master.mdf | 30.234375000000 | 1.046875000000 | 534 | 9299 | 88 |
DEVSQLServer | master | K:\SQLServer\MSSQL\DATA\master.log | 0.714843750000 | 3.457031250000 | 871 | 1573 | 2 |
DEVSQLServer | Developer | D:\SQLServer\\Dev.mdf | 24.507812500000 | 0.773437500000 | 341 | 2976 | 3 |
DEVSQLServer | Developer | L:\SQLServer\Log\Dev_log.ldf | 0.719238281250 | 0.590332031250 | 225 | 463 | 1 |
DEVSQLServer | Developer | M:\SQLServer\Dev_File1.ndf | 3.609375000000 | 0.039062500000 | 62 | 1071 | 3 |
SQL Server Wait Statistics
Wait Statistics are very useful to identify Problem Areas
-- Gather Wait Statistics IF OBJECT_ID('tempdb..#Waits') IS NOT NULL DROP TABLE #Waits ; SELECT [wait_type] , [wait_time_ms] / 1000.0 AS [WaitS] , ( [wait_time_ms] - [signal_wait_time_ms] ) / 1000.0 AS [ResourceS] , [signal_wait_time_ms] / 1000.0 AS [SignalS] , [waiting_tasks_count] AS [WaitCount] , 100.0 * [wait_time_ms] / SUM([wait_time_ms]) OVER ( ) AS [Percentage] , ROW_NUMBER() OVER ( ORDER BY [wait_time_ms] DESC ) AS [RowNum] INTO #Waits FROM sys.dm_os_wait_stats WHERE [wait_type] NOT IN ( N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR', N'BROKER_TASK_STOP', N'BROKER_TO_FLUSH', N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE', N'CHKPT', N'CLR_AUTO_EVENT', N'CLR_MANUAL_EVENT', N'CLR_SEMAPHORE', N'DBMIRROR_DBM_EVENT', N'DBMIRROR_EVENTS_QUEUE', N'DBMIRROR_WORKER_QUEUE', N'DBMIRRORING_CMD', N'DIRTY_PAGE_POLL', N'DISPATCHER_QUEUE_SEMAPHORE', N'EXECSYNC', N'FSAGENT', N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'FT_IFTSHC_MUTEX', N'HADR_CLUSAPI_CALL', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION', N'HADR_LOGCAPTURE_WAIT', N'HADR_NOTIFICATION_DEQUEUE', N'HADR_TIMER_TASK', N'HADR_WORK_QUEUE', N'KSOURCE_WAKEUP', N'LAZYWRITER_SLEEP', N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE', N'PWAIT_ALL_COMPONENTS_INITIALIZED', N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP', N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP', N'REQUEST_FOR_DEADLOCK_SEARCH', N'RESOURCE_QUEUE', N'SERVER_IDLE_CHECK', N'SLEEP_BPOOL_FLUSH', N'SLEEP_DBSTARTUP', N'SLEEP_DCOMSTARTUP', N'SLEEP_MASTERDBREADY', N'SLEEP_MASTERMDREADY', N'SLEEP_MASTERUPGRADED', N'SLEEP_MSDBSTARTUP', N'SLEEP_SYSTEMTASK', N'SLEEP_TASK', N'SLEEP_TEMPDBSTARTUP', N'SNI_HTTP_ACCEPT', N'SP_SERVER_DIAGNOSTICS_SLEEP', N'SQLTRACE_BUFFER_FLUSH', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP', N'SQLTRACE_WAIT_ENTRIES', N'WAIT_FOR_RESULTS', N'WAITFOR', N'WAITFOR_TASKSHUTDOWN', N'WAIT_XTP_HOST_WAIT', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG', N'WAIT_XTP_CKPT_CLOSE', N'XE_DISPATCHER_JOIN', N'XE_DISPATCHER_WAIT', N'XE_TIMER_EVENT' ) AND [waiting_tasks_count] > 0; SELECT @@SERVERNAME ServerName , MAX([W1].[wait_type]) AS [WaitType] , CAST (MAX([W1].[WaitS]) AS DECIMAL(16, 2)) AS [Wait_S] , CAST (MAX([W1].[ResourceS]) AS DECIMAL(16, 2)) AS [Resource_S] , CAST (MAX([W1].[SignalS]) AS DECIMAL(16, 2)) AS [Signal_S] , MAX([W1].[WaitCount]) AS [WaitCount] , CAST (MAX([W1].[Percentage]) AS DECIMAL(5, 2)) AS [Percentage] , CAST (( MAX([W1].[WaitS]) / MAX([W1].[WaitCount]) ) AS DECIMAL(16, 4)) AS [AvgWait_S] , CAST (( MAX([W1].[ResourceS]) / MAX([W1].[WaitCount]) ) AS DECIMAL(16, 4)) AS [AvgRes_S] , CAST (( MAX([W1].[SignalS]) / MAX([W1].[WaitCount]) ) AS DECIMAL(16, 4)) AS [AvgSig_S] FROM #Waits AS [W1] INNER JOIN #Waits AS [W2] ON [W2].[RowNum] <= [W1].[RowNum] GROUP BY [W1].[RowNum] HAVING SUM([W2].[Percentage]) - MAX([W1].[Percentage]) < 95; -- percentage threshold
Sample Results:
ServerName | WaitType | Wait_S | Resource_S | Signal_S | WaitCount | Percentage |
---|---|---|---|---|---|---|
DEV2016Server | CXPACKET | 2780766.45 | 2709948.99 | 70817.46 | 2303786508 | 32.27 |
DEV2016Server | TRACEWRITE | 2749593.72 | 2749536.56 | 57.16 | 1845757 | 31.90 |
DEV2016Server | PWAIT_DIRECTLOGCONSUMER_GETNEXT | 2283287.93 | 2283287.91 | 0.03 | 593 | 26.49 |
DEV2016Server | IO_COMPLETION | 138159.91 | 138041.36 | 118.55 | 16211715 | 1.60 |
DEV2016Server | PAGEIOLATCH_SH | 93710.55 | 93414.69 | 295.86 | 7569772 | 1.09 |
DEV2016Server | LATCH_EX | 91766.77 | 89777.26 | 1989.51 | 27969162 | 1.06 |
DEV2016Server | ASYNC_NETWORK_IO | 79182.28 | 78462.72 | 719.57 | 25585992 | 0.92 |
Mirroring
Mirroring Status
SELECT DB_NAME(database_id) As DatabaseName, CASE WHEN mirroring_guid IS NOT NULL THEN 'Mirroring is On' ELSE 'No mirror configured' END AS IsMirrorOn, mirroring_state_desc, CASE WHEN mirroring_safety_level=1 THEN 'High Performance' WHEN mirroring_safety_level=2 THEN 'High Safety' ELSE NULL END AS MirrorSafety, mirroring_role_desc, mirroring_partner_instance AS MirrorServer FROM sys.database_mirroring GO