Category: SQL

T SQL Script – Get SQL Job Details and history details

Description

The Script “sp_GetJobDetails” has 3 resultsets to get job details and its history analysis result. The Procedure has a parameter that gets Job_Id, however is an optional, a NULL value can be passed to fetch job details and History information for all jobs configured in the server.

The script will be very useful and handy for those who are looking for SQL Server Agent Job details and its execution details.

DOWNLOAD SCRIPT

Note: This is an enhanced version of my earlier script posted in MSDN Gallery at https://gallery.technet.microsoft.com/T-SQL-Script-Get-Job-231229b4.

Please download the script and have your suggestions.

Auto File Growth: Track the growth events Using Extended Events in SQL Server

This is a continued blog post for Auto File Growth – Different ways to track the growth events to answer one of the comments.

The author of the comment (Vinuraj R) was looking for a way to capture the Growth events through Extended Events. Let me begin with a Thank you note to the author talking about Extended Events. Extended Events are powerful ways to capture most of the metrics from the SQL Server 2008 own wards.

Here, We are going to see a method to track/cpature the growth of (Data/Log)files using Extended Events.

First of all, we are going to create an EVENT SESSION on the Server to capture the database_file_size_change Event as below: (You may also be able to provide a filter to capture information for any specific database, if required.)


-- Create event
CREATE EVENT SESSION [DB_file_size_changed] ON SERVER 
ADD EVENT sqlserver.database_file_size_change(SET collect_database_name=(1)
    ACTION
   (sqlserver.client_app_name,sqlserver.client_hostname, sqlserver.database_id,sqlserver.session_id,
   sqlserver.session_nt_username,sqlserver.username) 
   /* You can filter the database that needs to be monitored for the auto growth, for which you need to pass the database id for the filter*/
   --WHERE ([database_id]=()) 
   ) 
ADD TARGET package0.event_file
(SET filename=N'C:\temp\DB_file_size_changed.xel')
WITH (MAX_DISPATCH_LATENCY=1 SECONDS)

Once , Event Session has been created, We need to START the EVENT SESSION as below:Please note that you may need CONTROL SERVER permission to Alter/Drop the Event Session.


ALTER EVENT SESSION DB_File_size_Changed 
ON SERVER STATE = START -- START/STOP to start and stop the event session

Once the Event session is started, events will be capturing the Growth information in the file and we would be able to see those information using the below script:

USE [master];
GO
SELECT
        Case when file_type = 'Data file' Then 'Data File Grow' Else File_Type End AS [Event Name]
	   , database_name AS DatabaseName
	   , file_names
	   , size_change_kb
	   , duration
       , client_app_name AS Client_Application
	   , client_hostname
       , session_id AS SessionID
	   , Is_Automatic 
	   , sql_txt
	   , sql_username
       
FROM (
       SELECT
           n.value ('(data[@name="size_change_kb"]/value)[1]', 'int') AS size_change_kb
           , n.value ('(data[@name="database_name"]/value)[1]', 'nvarchar(50)') AS database_name
           , n.value ('(data[@name="duration"]/value)[1]', 'int') AS duration
           , n.value ('(data[@name="file_type"]/text)[1]','nvarchar(50)') AS file_type
           , n.value ('(action[@name="client_app_name"]/value)[1]','nvarchar(50)') AS client_app_name
           , n.value ('(action[@name="session_id"]/value)[1]','nvarchar(50)') AS session_id
		   , n.value ('(action[@name="client_hostname"]/value)[1]','nvarchar(50)') AS Client_HostName
		   , n.value ('(data[@name="file_name"]/value)[1]','nvarchar(50)') AS file_names
		   , n.value ('(data[@name="is_automatic"]/value)[1]','nvarchar(50)') AS Is_Automatic
		   , n.value ('(action[@name="sql_text"]/value)[1]','nvarchar(500)') AS sql_txt
			, n.value ('(action[@name="username"]/value)[1]','nvarchar(50)') AS sql_username
           
       FROM 
           (   SELECT CAST(event_data AS XML) AS event_data
               FROM sys.fn_xe_file_target_read_file(
                   N'C:\temp\DB_file_size_changed*.xel',
                   NULL,
                   NULL,
                   NULL)
           ) AS Event_Data_Table
CROSS APPLY event_data.nodes('event') AS q(n)) xyz
ORDER BY database_name

Here is a sample report generated with my testing.
AutoGrowth_ExtendedEvent

Hope, this post would help to understand another way of capturing File Growth information.

Auto File Growth – Different ways to track the growth events

Auto-Growth events are occurring when the data/log file is trying to expand size due to out of space.The amount that grows, depends on the file growth option provided for the database. Recently, in one of the project, it has been observed that the Auto growth event occurred 4 times for one of data file and a delay in response time.

Whats the problem with Auto Growth?

Auto Growth can not be stopped completely, however, a careful configuration of Growth option can control the number of Auto Growth events.The problem with Auto Growth is that during the growth event, the database would be halted until the growth event has completed. For a higher size, it can take more time there by a huge delay in processing for the request and in turn several performance issues.In addition, when the space is allocating, it may not be a contiguous space resulting a physical fragmentation of the database file on the disk. If the number of Auto Growth is high, then there will be more physical fragmentation.

How do you find the Auto Growth events?

This blog post is neither intended nor explained the cause of the growth or its resolution.Lets us look at it later. Here, We would see some of common methods to identify the Auto Growth events in SQL Server.

–Using default trace

Default trace is a very powerful way of capturing issues in SQL Server. Some of common EventClasses and its description is given below.

/*

EventClass Description
********************************************************

18 -Audit Server Starts And Stops
20 -Audit Login Failed
22 -Error log
46 -Object:Created
47 -Object:Deleted
55 -Hash Warning
69 -Sort Warnings
79 -Missing Column Statistics
80 -Missing Join Predicate
81 -Server Memory Change
92 -Data File Auto-Grow
93 -Log File Auto-Grow

116 -Audit DBCC Event
164 -Object:Altered
175 -Audit Server Alter Trace Event
*/

Now, lets look at the way to capture Auto Growth Event from trace as below.

DECLARE @filename NVARCHAR(1000);

-- Get the name of the current default trace
SELECT @filename = CAST(value AS NVARCHAR(1000))
FROM ::fn_trace_getinfo(DEFAULT)
WHERE traceid = 1 AND property = 2;

--To find the filename without rollover number
SET @filename = REVERSE(@filename);
SET @filename = REVERSE(SUBSTRING(@filename,CHARINDEX('_',@filename)+1,LEN(@filename))) 
					+ REVERSE(SUBSTRING(@filename,1,CHARINDEX('.',@filename)));

-- Get the details
SELECT 
  Trace.StartTime, Trace.EndTime,TraceEvent.name AS EventName,Trace.DatabaseName  
,Trace.Filename,Trace.EventClass,(Trace.IntegerData*8)/1024.0 AS GrowthMB 
,(Trace.duration/1000)AS DurationInMS
FROM ::fn_trace_gettable(@filename, DEFAULT) AS Trace 
INNER JOIN sys.trace_events AS TraceEvent ON Trace.EventClass = TraceEvent.trace_event_id  
WHERE (Trace.EventClass = 92  
    OR Trace.EventClass = 93) 
ORDER BY Trace.StartTime

–Using SQL Error log

SQL Server will provide the Auto Growth events in the Error log as below snapshot. The errorlog information contains the file name and database with the time taken to process the Auto Growth. Note, these are the events 5144 & 5145 logged only when autogrowth takes longer time or times out.

AutoGrowth_ErrorLog

–Using Live monitoring query

Using the script in the post, you would be able to see the wait types like LATCH_EX/PREEMPTIVE_OS_WRITEFILEGATHER occurring in the server along with the resource description as FGCB_ADD_REMOVE(A prominent type of Latch – File Group Control Block Add/Remove), which is an indication for Auto Growth Event.

These are my favorite methods to identify the Auto Growth events. If you have any other ways, I would like to request you to share the information here.

Live Monitoring Queries to troubleshoot issues in SQL Server

Here, I would like to share one of my favorite Live monitoring DMV Scripts.

It contains two sessions as below. This has been very helpful to me while monitoring the SQL Server Production issues on the floor.

1. Identify the requests in the SQL Server those are currently running

SELECT  r.session_id ,Getdate() 'CurrentDateTime',r.blocking_session_id 'Blocking Session ID',
	(Select Top 1 CON.client_net_address From sys.dm_exec_connections AS CON 
	where CON.session_id = r.session_id) Client_Address,
		Coalesce(Quotename(Db_name(qt.dbid)) + N'.' + Quotename(Object_schema_name(qt.objectid, qt.dbid)) + N'.' +      
				Quotename(Object_name(qt.objectid, qt.dbid)), '') AS command_text,
        r.[status] ,
        r.wait_type ,wait_resource,r.wait_time / (1000.0) 'Wait Time (in Sec)',
        r.scheduler_id ,
        SUBSTRING(qt.[text], r.statement_start_offset / 2,
            ( CASE WHEN r.statement_end_offset = -1
                   THEN LEN(CONVERT(NVARCHAR(MAX), qt.[text])) * 2
                   ELSE r.statement_end_offset
              END - r.statement_start_offset ) / 2) AS [statement_executing] ,
        DB_NAME(qt.[dbid]) AS [DatabaseName] ,
        r.cpu_time ,r.total_elapsed_time / (1000.0) 'Elapsed Time (in Sec)',
        r.reads ,r.writes ,r.logical_reads ,
        r.plan_handle,r.sql_handle
        ,s.login_name ,s.host_name ,s.program_name,s.host_process_id ,s.last_request_end_time,s.login_time
FROM    sys.dm_exec_sessions AS s
		INNER JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id
        CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS qt
WHERE   r.session_id > 50

2. Identify relevant information like blocking/wait type/queryplan etc.

SELECT
    [DOWT].[session_id],[DOWT].[exec_context_id],
    [DOWT].[wait_duration_ms],[DOWT].[wait_type],
    [DOWT].[blocking_session_id],[DOWT].[resource_description],
    CASE [DOWT].[wait_type]
        WHEN N'CXPACKET' THEN
            RIGHT ([DOWT].[resource_description],
            CHARINDEX (N'=', REVERSE ([DOWT].[resource_description])) - 1)
        ELSE NULL
    END AS [Node ID],[DES].[program_name],[DEST].text,
    [DER].[database_id],[DEQP].[query_plan],[DER].[cpu_time]
FROM sys.dm_os_waiting_tasks [DOWT]
INNER JOIN sys.dm_exec_sessions [DES] ON
    [DOWT].[session_id] = [DES].[session_id]
INNER JOIN sys.dm_exec_requests [DER] ON
    [DES].[session_id] = [DER].[session_id]
OUTER APPLY sys.dm_exec_sql_text ([DER].[sql_handle]) [DEST]
OUTER APPLY sys.dm_exec_query_plan ([DER].[plan_handle]) [DEQP]
WHERE [DES].[is_user_process] = 1
ORDER BY [DOWT].[session_id], [DOWT].[exec_context_id];

I’d like to grow my readership. If you enjoyed this blog post, please share it with your friends!

TEMPDB – Collation Issues with User databases in SQL Server

Problem Statement:

Today, We faced an issue with one of the projects we engaged with.Project team was experiencing issues having different collation for TEMPDB and USERDB.The error message is given below:

“Cannot resolve the collation conflict between “SQL_Latin1_Genral_CP1_CI_AS” and “Latin1_Genral_CI_AI” in the equal to operation”.

Troubleshooting:

This was a clear indication that the issue is with the collation mismatch. When we further analysed the procedure, we could identify there is a temp table used and being used to match the records with USERDB table.

To understand the issue with collation in detail, we checked the collation of TEMPDB database and USERDB and found the collation is set as “SQL_Latin1_Genral_CP1_CI_AS” and “Latin1_Genral_CI_AI”.

Use the below script to know the collation for databases:

Select name,COLLATION_NAME from sys.databases

As long as we are not sure of the difference in Collation between TEMPDB and USERDBs, as a quick fix, we recommanded to change the SQL Query as below while creating the temp tables, this would by default take the user database’s collation during the temp table creation:


CREATE TABLE #Table
(
VoucherID NVARCHAR(10) COLLATE database_default,
VocherName NVARCHAR(100) COLLATE database_default,
FileTypeID INT
)

Call To Action:

1. Please make sure your USERDBs and systemDBs are in the same collation unless there is a requirement for explicit change.
2. When you want to change the Collation for a USERDB, Please check the Collation of TEMPDB as well.

See Also:

https://msdn.microsoft.com/en-us/library/bb402915.aspx