PREEMPTIVE_OS_DEVICEIOCONTROL: DBCC CHECKDB Will Not Stop

A DBCC CHECKDB session waiting on PREEMPTIVE_OS_DEVICEIOCONTROL won’t end, even after you stop the job and kill the SPID. I work as an on-demand consultant for teams with SQL Server problems. The DBA at one of my clients asked me about this. Here is what we saw and how we cleared it.

Gouache painting of a paper kite caught high in the branches of a bare tree by its tangled string, with one vermilion ribbon trailing from its tail

The Error

Killing the session didn’t end it. SQL Server answered with a rollback message that never moved:

SPID xxxx: transaction rollback in progress. Estimated rollback completion: 0%. Estimated time remaining: 0 seconds.

The same session showed this wait type:

PREEMPTIVE_OS_DEVICEIOCONTROL

What the Client Saw

The client ran a weekly DBCC CHECKDB job across their user databases. For reasons nobody knew, it took longer than expected. Business hours were close, so they had a second job to stop it. They called it the terminator job.

According to the job history, the terminator job ran successfully. The CHECKDB session was still there in sys.sysprocesses. We joined a GoToMeeting session and tried a few things.

Gouache painting of the same bare tree with the kite untangled and flying free above it, its vermilion ribbon streaming behind

How to Check

These are the checks we made on the stuck session:

  1. The session was waiting on PREEMPTIVE_OS_DEVICEIOCONTROL.
  2. The wait time kept growing in sys.dm_exec_requests.
  3. The CPU and IO columns in sys.dm_exec_requests did not change.
  4. We ran DBCC OPENTRAN to find the oldest active transaction.
  5. It gave some clues about DTC, so we restarted MSDTC. That didn’t help.

Why It Happens

The wait type tells the story. Something that controls IO was stopping CHECKDB from finishing. The PREEMPTIVE_OS part means SQL Server had handed the operation to the operating system. The session was waiting outside SQL Server.

I recalled my earlier post about the KILLED/ROLLBACK state of a SPID. In short, nothing in SQL Server can fix a session in this state. A service or server restart is the only way out.

The Fix

For this wait, we restarted SQL Server to get rid of the SPID. The restart cleared the session.

How to Prevent It

Give the weekly CHECKDB a window that ends well before business hours, so nobody needs a terminator job. And before you kill a long session, look at its wait type. A PREEMPTIVE wait means the problem is outside SQL Server.

This wait is not common. If you see it, you now know what we did.

Quick reference card: PREEMPTIVE_OS_DEVICEIOCONTROL

A killed session is not a finished session, it is a request waiting on the operating system.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Error Messages, SQL Server, SQL Server DBCC, SQL Transactions, SQL Wait Stats
Previous Post
Asynchronous Statistics Updates: When They Help and When They Hurt
Next Post
SQL Authroity News – Optimizing Lazy Spool – PASS Blog

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.