March 2006 - Posts - Andrew Calvett

March 2006 - Posts

What is that SPID doing?
27 March 2006 17:44

This is certainly not a new topic but something that i felt was worth revisiting and reminding people about, especially because i find many people are not aware of the ability to extract the statement within a stored procedure being executed.

So, prior to SQL 2000 SP3, when we want to know what code a SPID is executing we have to use DBCC INPUTBUFFER (). The problem with this command is that its restricted to the first 256 characters and only returns the outermost statement executing. That means that if we have stored procedure 1 calling stored procedure 2 the input buffer will only tell us about stored procedure 1 and it may even get truncated!

I clearly remember reading the SP3 readme and thinking Christmas has come early as i found the entry about a new function being introduced called ::fn_get_sql. I've got to say right now this is the best present yet! It has made trouble shooting so much easier. Why? Well read on.

Running the code below will now show you the inner most statement executing and we now get up to 4000 characters. In the case of a stored procedure you see the whole procedure.

DECLARE @Handle binary(252)
SELECT @Handle = sql_handle FROM master..sysprocesses WHERE spid = 109 --CHANGE SPID NUMBER
SELECT * FROM ::fn_get_sql(@Handle)

The part that really got me? When it returns the code of a stored procedure you could be left wondering what statement within the stored procedure is executing. Fear not! They have that covered to. All you have to do is run the modified code below and the exact statement causing you a problem is identified.

DECLARE @Handle binary(20), @start int, @end int
SELECT @Handle = sql_handle, @start = stmt_start, @end = stmt_end
FROM master..sysprocesses WHERE sql_handle <> 0x00 AND spid = 226  --CHANGE SPID NUMBER
IF NOT EXISTS (SELECT * FROM ::fn_get_sql(@Handle))  PRINT 'Handle not found in cache'
ELSE
SELECT  'Current statement'=
 substring(text, (@start + 2)/2,
                                 CASE @end
                                      WHEN -1 THEN (datalength(text))
ELSE (@end -@start + 2)/2
                                    END)

FROM ::fn_get_sql(@Handle)

So, now i've reminded you of this really useful tool its time for a few "Battle Tips".

1) Make sure in query analyser your "maximum characters per column" is set to 4000. Otherwise you are only going to get 256....
2) If  SQL generates a "zero cost plan" it will not put it in cache because its not worth it. As its not in cache ::fn_get_sql won't return any information.
3) This one comes with a health warning..... If for some reason you need SQL to cache the zero cost plans so that ::fn_get_sql will always work then you can enable trace flag 2861. I would recommend you do not use this in production as the overhead is substantial and profiler should be used instead but some people might find it beneficial on a dev box.
4) I've not adjusted the script above to deal with parallel spids where you get multiple handles for 1 spid. Just a note, i keep on forgetting.  :D

There are many uses for this function and i encourage you to explore them. SQL 2005 makes life even easier through DMV's but thats another blog......

 

by ACALVETT | with no comments
Filed under: , ,
SQL 2005 - Log Shipping Monitoring?
12 March 2006 18:08
I took a look at log shipping in 2005 for the first time the other day and as i was curious to see how the monitor functionality had been implemented in SQL Server Management Studio i went hunting for it. I've got to say i was greeted with nothing but disappointment and left feeling that i now have a huge mountain to climb before it can be used in production!

We currently have 15 databases shipped to multiple destinations and in SQL 2000 we monitor and manage from a central monitor server. In Enterprise Manager there is a log shipping monitor node under management and any databases that have failed are marked with a red cross and we can right click and suppress the alerts whilst we investigate and the investigation often starts with a right click to view the relevant history for the database in question. Amongst other things we can also automatically suppress alerts for periods of time.

Now, what did i find in 2005? After a good hunt around i found a report that you get to by going to the summary page at the server level and choose "Transaction Log Shipping status". I then found a single job on the monitor server responsible for generating the alerts for all the databases. As for viewing the histories, its a case of find the jobs or run a query against the relevant monitor tables!

In SQL 2005, log shipping has been wrapped up into its own executable and divorced from maintenance plans. I was expecting to see a number of improvements over SQL 2000 or, as a minimum, be on the same level but i was not prepared to find that out of the box it was going to be far more difficult to use! Why? Because the monitor tool in 2000 was simple and with reasonable instruction anyone could use it. I now feel i need to write at least 1 more report and i need to come up with a way of suppressing individual alerts and introducing suppressions for certain time periods to meet our business needs and ensure its maintainable by people who are not DBA's.

I just don't understand why Microsoft have done this! :(
by ACALVETT | with no comments
Filed under: