Running sp_who2 on the affected server reveals that there are indeed blocked processes, as is evidenced by the BlkBy field in the results, see Figure 5.1.. Finding out who is running the
Trang 1different and, in my opinion, too difficult to maneuver when trying to home in on
a problem as quickly as possible That is primarily the reason I am compelled to run both 2005 and 2008 versions of the client tools
Sp_who2, on the other hand, always works and the results are generally instantaneous It displays, among many other things, any blocking on the SQL Server instance on which the problem has been reported Running sp_who2 on the affected server reveals that there are indeed blocked processes, as is evidenced
by the BlkBy field in the results, see Figure 5.1
Figure 5.1: Blocked processes uncovered by sp_who2.
I can tell at first glance that SPID 55 is blocked by SPID 51, and that SPID 54 is blocked by 55 I can also see that the database context of the blocking SPID is the
database, which ironically and for argument's sake is the same database
Trang 2With sp_who2, I have discovered a blocking process and it has been blocking for quite some time now Users are getting frantic, and soon this will escalate and there will be three or four people at my cubicle, who otherwise would not give the SQL Server infrastructure a second glance, laser beam focused on my every action, and fully expecting me to solve the problem quickly
In order to do so, I am going to have to find fast answers to the following questions:
• Who is running the query and from where?
• What is the query doing?
• Can I kill the offending query?
• If I kill the query, will it rollback successfully and will this free up the blocked processes?
Who is running the query?
Finding out who is running the query, and from where, is usually easy and, in fact, may be readily apparent from the output of sp_who2 In this case, figure 5.1 tells
me that the query is being executed by sa from Microsoft SQL Server Management Studio and it is coming from the local server "G"
However, in the real world, it might not always be quite so straightforward to answer the "who" question Some applications use a generic login as an abstraction from the user The user may possess a valid login account, but this account is not used to directly connect to the database Instead, the account is controlled by the application, and usually stored in a table within the application database In these cases, you will often see the generic application login and not the user's login
What you may also find is that the query is issued by an application residing on another server, potentially a web server, in which case the ProgramName field from the sp_who2 results will likely show ".Net Client" That does not tell you much You may also see the Web server name but, again, this may be expected Occasionally, you may strike lucky and see an unexpected application, like Management Studio, Query Analyzer, Microsoft Access or some other application that should not be connecting to production data directly, outside of the front end application If so, then you have made progress and can continue with the confidence that you now have a user name, program name and location If you have not captured anything out of the ordinary, that is OK; you will still be able to find the answer to the next most important question, "What is the query doing?"
Trang 3DBCC: What is the query doing?
Microsoft has been kind enough to provide us with many tools to diagnose such issues One such tool is the DBCC set of commands DBCC, which if you are a SQL Server DBA you are very familiar with, can be used for a variety of important tasks, from checking for and fixing corrupt databases (DBCC CHECKDB), which I cover in Chapter 8, to checking how memory is being used on your SQL Server instance (DBCC MEMORYSTATUS) There is another DBCC command,
INPUTBUFFER, which allows you to see the underlying query that a specific SPID
is executing It is quite helpful, nay, indispensible, for the sleuthing DBA
Using DBCC INPUTBUFFER is as easy as passing in the SPID number, as shown in Figure 5.2, to uncover the "Bad Query" that is blocking the other process
Figure 5.2: Output of DBCC INPUTBUFFER.
As you can see the output lacks formatting when returned in a grid format I could expand the EventInfo field to get a better look at the query, but it would still lack proper formatting Returning the results to text, which is simply a matter of clicking the "Results to Text" button on the Management Studio toolbar, usually delivers better results, as shown in Figure 5.3
Clearly, someone has been tasked with filling the Important_Data table (shown
in Listing 5.1 for those who want to work through the example) with values and will do whatever it takes to get the job done!
Trang 4Figure 5.3: Results to Text for DBCC INPUTBUFFER
CREATE TABLE [dbo] [Important_Data] (
[T_ID] [int] IDENTITY ( , ) NOT NULL,
[T_Desc] [nchar] ( 40 ) NOT NULL,
[T_Back] [datetime] NULL,
[T_Square] [uniqueidentifier] NULL
) ON [PRIMARY]
GO
Listing 5.1: CREATE statement for Important_Data table
Trang 5Let's take a look at this "Bad Query" in all its ugly glory, as shown in Listing 5.2
BEGIN Tran T_Time
DECLARE @SQL_Alphabet varchar ( 26 )
SET @SQL_Alphabet = '
ABCDEFGHIJKLMNOPQRSTUVWXYZ'
DECLARE @rnd_seed int
SET @rnd_seed = 26
DECLARE @DT datetime
SET @DT = '05/21/1969'
DECLARE @counter int
SET @counter = 1
DECLARE @tempVal NCHAR ( 40 )
WHILE @counter < 100
BEGIN
SET @tempVal = SUBSTRING ( @SQl_alphabet , Cast ( RAND ()
* @rnd_seed as int ) + 1 , CAST ( RAND () @rnd_seed as int ) + 1 )
Insert Into Important_Data WITH XLOCK )
Values (
@tempVal ,
DATEDIFF ( , cast ( RAND () 10000 as int ) + 1 ,
@DT ),
NewID ()
)
WAITFOR DELAY '00:00:01'
SET @counter = @counter + 1
END
Exec xp_cmdshell 'C:\Windows\notepad.exe'
Commit Tran T_Time
Listing 5.2: Really "Bad Query"
If I saw this query on a real system, my concern would begin to build at around line 15, and by line 24 I think I would be a bit red-faced At line 29, where I see the query call xp_cmdshell and execute Notepad.exe, I would need a warm blankie and soft floor where I would lie in a fetal position for a few hours thinking about happy things
Of course, at this stage I should make it clear that this query is an exercise in the ridiculous; it is one that I specifically designed to cause locking and blocking so that I could demonstrate how to resolve similar issues on your servers The "bad query" is not the work of a reasonable person but that does not mean that