September 29, 2016
What tools in SQL Server will notify you about blocking and help track the queries behind your toughest blocking and deadlocking problems?
Watch the 21 minute video, subscribe to the podcast, or read the episode notes and links below.
Dear SQL DBA,
What is the best way to set up blocking and deadlock alerts on the server? I want to be notified automatically without any impact on the prod server.
I have tried alerts with SQL server performance condition alerts with SQL server agent. They do not show the queries or tables involved etc?
Woo hoo, I love this question!
So first off, I’m going to answer this discussing the free, built-in tools with SQL Server. If you have a budget for custom monitoring tools, you can buy fancy tools that have customized notifications for blocking and which capture the queries and plans involved. If that’s the case, set up free trials against a test system.
But not everyone has budget for every single SQL Server instance. So it’s extremely useful to know what SQL Server offers to help you with this.
And by the way, if you’re going to be at the SQLPASS Summit in Seattle in just under a month, I’m giving a session that shows different blocking scenarios. Come see my session, The Great Performance Robbery: Locking Problems and Solutions on Thursday, Oct 27th at 10:45AM in room 6C.
Free, simple blocking notifications
I like to set up blocking notifications with a simple SQL Server agent alert on the “SQLServer: General Statistic: Processes Blocked” performance counter.
This will not give you the queries involved in the blocking – don’t worry, we’ll cover tracking that in the next step.
This alert is low impact and it will let you know when you need to look at the SQL Server.
To get this alert to work, you’ll need to:
- Configure the SQL Server Agent service to auto start
- Set up database mail, enable it on the SQL Server Agent, and then restart the SQL Server Agent
- Configure an Operator in the SQL Server Agent
- Create a new ‘performance’ style alert, base it on the “Processes Blocked” counter, and tell it who to notify
A few things to note:
- The SQL Agent doesn’t poll counters constantly - and we want this to be lightweight, so that’s a good thing. It will only poll every 15-30 seconds, and there’s no published guaranteed SLA on that polling frequency.
- If you really need something more sensitive and reliable, you need a monitoring system fully independent / outside of the SQL Server to be polling in and checking it for availability and performance.
- You can configure the alert to only fire every X minutes. I highly recommend that, so you don’t get an inbox of alerts every 20 seconds
Create some blocking in a test database or in tempdb and make sure the alert works.
I have example code to create blocking and deadlocks for your dev environments in my post, Deadlock Code for the WorldWideImporters Sample Database.
For production databases, you can create a temp table and write similar code to create blocking in those.
Finding the queries involved with the Blocked Process Report
OK, we’ve got notifications. We need SQL Server to give us more information on who is involved in the blocking.
I like to use the built-in Blocked Process Report for this. This has been in SQL Server for a long time, and it’s extremely useful.
The Blocked Process Report shows you the “input buffer” of the commands involved - it may be partial information and not the full text of the query. It will also show you the login name for who is running what, and the type of lock requests involved.
The Blocked Process Report is pretty lightweight, because SQL Server has to frequently wake up and look for blocking situations that can’t resolve themselves. By default, the deadlock monitor wakes up every 5 seconds and looks around to see if there is a deadlock which it needs to break. You may enable a feature called the ‘Blocked Process Report’ that tells SQL Server to additionally issue a report on any blocking which it finds.
To get this to work, you need to:
- Enable the sp_configure option for the blocked process threshold. This defaults to ‘0’, which is off. You configure the threshold to the number of seconds you’d like the threshold to be. This should be a value of 5 or higher, because making the deadlock monitor run constantly could tank your performance. A good ‘starting’ value is 30 seconds.
- You also need to set up a trace to collect an event called the ‘blocked process report’. Setting the threshold causes the event to be output, but SQL Server won’t collect it for you unless you start a SQL Trace or an Extended events trace that collects that event.
Once you have the trace file, you can copy it off of the production server to interpret it.
Michael J Swart has written a great free tool called the Blocked Process Report Viewer to help interpret the blocking chains. It’s free at https://sqlblockedprocesses.codeplex.com.
The viewer makes it easier to see the root of the blocking chain and who was blocking whom.
This trace is pretty lightweight, but with any trace you want to make sure that you don’t add a bunch of events that you don’t need, and that you periodically clean up the files and don’t let it impact drive space.
When I talk about running traces, I don’t mean running Profiler
We’re entering dangerous territory here. Whenever you talk about tracing in SQL Server these days, someone gets offended.
Here’s what you need to know. There’s two main ways to run a trace:
- SQL Trace. This is the old school option. You can run this using…
- The Profiler client (I don’t like this option)
- A Server Side trace scripted out from Profiler (much better!). You can get up to speed on Server Side Traces reading this article on generating a service side trace by Jen McCown. (Note that she wrote this article back in 2009. That’s fine, SQLTrace hasn’t been changing since then.)
- Extended Events. This is much easier to use on SQL Server 2012 and higher than in previous versions because a GUI was introduced in Management Studio for it under Object Explorer.
I do not like leaving the Profiler application running because I’ve seen it do everything from slowing down performance to filling up drives over the years. And creating Server Side traces isn’t very hard if you do want to use SQL Trace.
I personally only like to have a trace running if I know I need it and am going to look at it. So I only enable this when I have a blocking problem. Whenever you choose to leave a trace running, you need to periodically check in on the files its created and clean up after it.
Detecting and handling deadlocks
What about locking problems where SQL Server has to step in and kill one of the queries?
You have a few built in options about how to get info on this. There are some trace flags that you can turn on which cause some information about who is involved in the deadlock to be printed to the SQL Server Error Log. This isn’t my preferred option because the information is very hard to parse through and read.
I find it more helpful to get a ‘deadlock graph’, which is a picture of how the locking fight went down.
On older versions of SQL Server, you can capture the deadlock graph with a server side trace.
On newer versions of SQL Server, you can capture this with an Extended Events trace.
A great resource for deciding how to capture deadlock information is Jonathan Kehayias' excellent Simple Talk article, Handling Deadlocks in SQL Server. He covers how to collect the graphs, shows examples of how they look, and gets you started tackling them.
If you get through this point and need to get really fancy with deadlocks, Michael J Swart recently wrote about using Event Notifications to collect execution plans related to deadlocks in his post, “Build Your Own Tools”. Just don’t try to run before you walk: this is pretty advanced stuff and you need to be comfortable using Service Broker, which is part of Event Notifications behind the scenes.
Updates, Oct 12, 2016:
- Deadlock alerting: While it’s always better for the application itself to catch, handle, and log/alert on failed queries (not just deadlocks, but timeouts and anything else)… if your application can’t do that, and you can’t change it, check out this SQL Magazine article by Michael Campbell on alerting on deadlocks from SQL Server.
- Also, thanks to Johan for pointing out that the free SQL Sentry Plan Explorer client tool is also able to display deadlock graphs. Just save them as an XDL file and you can open and view them.
Quick recap - getting more info on blocking
A fast rundown of the free, built-in tools we covered:
- I like to use a simple, light, performance alert in the SQL Server agent for notification about blocking
- I like the Blocked Process report to find out who’s blocking whom - collected by a server side SQL Trace or Extended events
- I find collecting deadlock graphs with either a server side SQL Trace or Extended Events to be the most helpful way to figure out who’s involved in the nastiest blocking tangles.
Want to submit a Dear SQL DBA Question?
Want clarification on some of the basics? Got a question that jumped into your mind reading or listening to this? I’d love to hear it– asking is always free and easy!