Where is the key to the LOCK?

This past Friday evening, a simple data import process (that has been working for several months), decided to not work correctly.  Because there was no “early warning” type of notifications systems on the SQL 2005 server, the SQL Agent Job was actually running when Monday morning rolled around.

Using Idera’s SQL Check, I quickly noticed that there was a process that had a lock on a table that was causing some MAJOR problems.  Four different SQL processes was waiting on this lock.  And of course my supervisor was getting calls left and right from end users because their applications were not working.

I had to figure out what was going on.  I was able to get a list of processes and which one was causing all the problem with the sp_who2 command.


However, this returned a “bias” HOST NAME.  I am not really sure why. But I confirmed with networking that the returned hostname and IP address do not exist on our network, but that is for another day.

I needed to know an accurate way to get all the information I needed at that moment when a job wrongs long.  This code is probably providing way more information than I really need, but sometimes more is better.  Even though the “host_name” is returning a “bogus” host name; the client_net_address is not!  This valid IP address is very important to locating the culprit machine.

    ,db_name(R.database_id) AS [DB Name]
    ,(S.total_elapsed_time/1000) AS [Total Sec]
FROM sys.dm_exec_connections AS C
JOIN sys.dm_exec_requests AS R
    ON C.session_id=R.session_id
JOIN sys.dm_exec_sessions AS S
    ON C.session_id=S.session_id
ORDER BY session_id

Using Thomas LaRock’s  HOW TO: Find Currently Running Long SQL Agent Jobs, I setup up a simple 2 step SQL Agent job to check for 1) long running jobs and 2) session information (using the code above).  A simple “save results to txt file” allows me to export the results to and study them later.

USE [msdb]
/****** Object:  Job [job_WH_MonitorDatabase]    Script Date: 10/30/2012 13:57:18 ******/
SELECT @ReturnCode = 0
/****** Object:  JobCategory [xx] Script Date: 10/30/2012 13:57:18 ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'xxx' AND category_class=1)
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'xxx'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback


EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'job_MonitorDatabase', 
        @notify_email_operator_name=N'xx', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [Monitor]    Script Date: 10/30/2012 13:57:18 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Monitor', 
        @os_run_priority=0, @subsystem=N'TSQL', 
        @command=N'exec usp_LongRunningJobs', 
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [RecordProcesses]    Script Date: 10/30/2012 13:57:18 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RecordProcesses', 
        @os_run_priority=0, @subsystem=N'TSQL', 
    sysp.spid AS [SPID]
    ,sysp.status AS [Status]
    ,sysp.hostname AS [Host Name]
    ,cn.client_net_address AS [Client IP]
    ,db_name(sysp.dbid) AS [DB Name]
    ,convert(sysname, rtrim(sysp.loginame)) as [Login]
    ,sysp.program_name AS [Program]
    ,sysp.cmd AS [CMD Status]
    ,sysp.cpu AS [CPU usage]
    ,sysp.physical_io [IO]
    ,sysp.blocked AS [Blocked By]
    ,sysp.waitresource AS [Wait Resource]
from master.dbo.sysprocesses AS sysp
INNER JOIN sys.dm_exec_connections AS cn 
    ON sysp.spid=cn.session_ID
WHERE sysp.dbid > 4 AND sysp.cmd <> ''AWAITING COMMAND''
ORDER BY sysp.hostname', 
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'Daily', 
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
GOTO EndSave

Thanks for your time!  I will let you know how it turns out.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s