Category Archives : Tips and Tricks

IIS 8.5 Dynamic Compression Issue

Windows Server 2012 R2 comes with IIS 8.5, and in this release an issue has been found in relation to the Dynamic Compression module.  The module sets the “Vary” header which is used to specify caching properties that the browser uses to determine whether the response should be cached or not. 

In IIS 8.0 and earlier, the Dynamic Compression module was overwriting the Vary header with the value “Accept-Encoding”, and as it happens this is the correct value to ensure that dynamic content is correctly cached – but – according to IIS it should be appending this value to the existing value and not overwriting it.

As it happens, this was supposed to be fixed in IIS 8.5 but the fix appears to be broken.   In IIS 8.5 (which ships with Windows Server 2012 R2) the Vary header is being set to “*” and the “Accept-Encoding” from the Dynamic Compression module is not appended.  The result of this is that no dynamic content is being cached by the browser.


Thankfully there is an easy workaround in IIS 8.5 for this:

1. Select an IIS site, and go to Configuration Editor.


2. Select system.web/caching/outputCache section, then set the omitVaryStar property to true



Setting this value results in the Vary header being returned with a value of “Accept-Encoding” and the browser then caches the dynamic content.

Bad disk – but which one?

You might be unlucky enough to occasionally run into issues with a hard drive which has issues, and Windows will attempt to warn you via the System Log.  However, as the issues are logged from a low level (below the UI level), the disk identifier can be a bit cryptic.  Here’s an example:

“The device, \Device\Harddisk5\DR5, has a bad block.”


Which might be a little less than helpful, especially if you mainly know your disks by their assigned drive letters.  Fortunately, there’s a Microsoft KB article on this topic:

However, that’s a bit dated.  After trawling through some forums, I found a really succinct translation in an answer on this thread:


DR# means drive, removable, and then the number Windows 7 has assigned that removable drive. # is the USB host controller ID assigned by Windows during setup. If you switch your HD to another USB port, the number should change.

In my case, this translation was spot on.  I had an external drive attached which actually had faulted and I was in the process of data recovery and (ultimately) a reformat:


So if you’re reading this – condolences – and I hope this article has helped you find the drive which is causing you some grief.  For help with disks, check out this page of really useful free disk data recovery tools.

I’ve been using TestDisk quite successfully, although it isn’t for a novice user.  If you’re not sure what you’re doing, read the documentation very carefully!

If you want to read an inspired answer on Server Fault, the first answer is enlightening.


A very quick guide to deadlock diagnosis in SQL Server

Recently I was asked about diagnosing deadlocks in SQL Server – I’ve done a lot of work in this area way back in 2008, so I figure it’s time for a refresher.  If there’s a lot of interest in exploring SQL Server and deadlocks further, I’m happy to write an extended article going into far more detail.  Just let me know.

Before we get into diagnosis and investigation, it’s a good time to pose the question: “what is a deadlock?”:

From TechNet:

A deadlock occurs when two or more tasks permanently block each other by each task having a lock on a resource which the other tasks are trying to lock. The following graph presents a high level view of a deadlock state where:

  • Task T1 has a lock on resource R1 (indicated by the arrow from R1 to T1) and has requested a lock on resource R2 (indicated by the arrow from T1 to R2).

  • Task T2 has a lock on resource R2 (indicated by the arrow from R2 to T2) and has requested a lock on resource R1 (indicated by the arrow from T2 to R1).

  • Because neither task can continue until a resource is available and neither resource can be released until a task continues, a deadlock state exists.

Diagram showing tasks in a deadlock state

The SQL Server Database Engine automatically detects deadlock cycles within SQL Server. The Database Engine chooses one of the sessions as a deadlock victim and the current transaction is terminated with an error to break the deadlock.

Basically, it’s a resource contention issue which blocks one process or transaction from performing actions on resources within SQL Server.  This can be a serious condition, not just for SQL Server as processes become suspended, but for the applications which rely on SQL Server as well.


The T-SQL Approach

A fast way to respond is to execute a bit of T-SQL on SQL Server, making use of System Views.  The following T-SQL will show you the “victim” processes, much like activity monitor does:

select * from sys.sysprocesses where blocked > 0

Which is not particularly useful (but good to know, so you can see the blocked count).  To get to the heart of the deadlock, this is what you want (courtesy of this SO question/answer):

SELECT Blocker.text –, Blocker.*, *
FROM sys.dm_exec_connections AS Conns
INNER JOIN sys.dm_exec_requests AS BlockedReqs
    ON Conns.session_id = BlockedReqs.blocking_session_id
INNER JOIN sys.dm_os_waiting_tasks AS w
    ON BlockedReqs.session_id = w.session_id
CROSS APPLY sys.dm_exec_sql_text(Conns.most_recent_sql_handle) AS Blocker

This will show you line and verse (the actual statement causing the resource block) – see the attached screenshot for an example.


However, the generally accepted way to determine and diagnose deadlocks is through the use of SQL Server trace flags. 

SQL Trace Flags

They are (usually) set temporarily, and they cause deadlocking information to be dumped to the SQL management logs.  The flags that are useful are flags 1204 and 1222.  From TechNet:

Trace flags are set on or off by using either of the following methods:

· Using the DBCC TRACEON and DBCC TRACEOFF commands.

For example, DBCC TRACEON 2528: To enable the trace flag globally, use DBCC TRACEON with the -1 argument: DBCC TRACEON (2528, -1). To turn off a global trace flag, use DBCC TRACEOFF with the -1 argument.

· Using the -T startup option to specify that the trace flag be set on during startup.

The -T startup option enables a trace flag globally. You cannot enable a session-level trace flag by using a startup option.  So to enable or disable deadlock trace flags globally, you’d use the following T-SQL:

DBCC TRACEON (1204, -1)
DBCC TRACEON (1222, -1)

DBCC TRACEOFF (1204, -1)
DBCC TRACEOFF (1222, -1)

Due to the overhead, it’s best to enable the flag at runtime rather than on start up.  Note that the scope of a non-startup trace flag can be global or session-level.

Basic Deadlock Simulation

By way of a very simple scenario, you can make use of SQL Management Studio (and breakpoints) to roughly simulate a deadlock scenario.

Given the following basic table schema:

CREATE TABLE [dbo].[UploadedFile](
    [Id] [int] NOT NULL,
    [Filename] [nvarchar](50) NOT NULL,
    [DateCreated] [datetime] NOT NULL,
    [DateModified] [datetime] NULL,
    [Id] ASC

With some basic test data in it:


If you create two separate queries in SQL Management Studio, use the following transaction (Query #1) to lock rows in the table:

SELECT [Id],[Filename],[DateCreated],[DateModified]
FROM [dbo].[UploadedFile]
WHERE DateCreated > ‘2015-01-01′

Now add a “victim” script (Query #2) in a separate query session:

UPDATE [dbo].[UploadedFile]
SET [DateModified] = ‘2014-12-31′
WHERE DateCreated > ‘2015-01-01′

As long as you set a breakpoint on the ROLLBACK TRANSACTION statement, you’ll block the second query due to the isolation level of the transaction which wraps query #1.


Now you can use the diagnostic T-SQL to examine the victim and the blocking transaction. Enjoy!