5 – DBA as detective 125 different 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 DBA_Rep database, which ironically and for argument's sake is the same database that the fictitious A.R.G application uses. 5 – DBA as detective 126 With 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?" 5 – DBA as detective 127 DBCC: 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! 5 – DBA as detective 128 Figure 5.3: Results to Text for DBCC INPUTBUFFER. CREATE TABLE [dbo].[Important_Data]( [T_ID] [int] IDENTITY(1,1) 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. 5 – DBA as detective 129 Let'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(d, 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 something similar will never occur on one of your servers (although it would probably never occur twice). Wrapped in a transaction called T_Time, it inserts . 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,. 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. 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