views:

672

answers:

3

Hi,

I'm currently in the process of detaching a development database on the production server. Since this is a production server I don't want to restart the sql service. That is the worst case scenario.

Obviously I tried detaching it through SSMS. Told me there was an active connection and I disconnected it. When detaching the second time it told me that was impossible since it was in use.

I tried EXEC sp_detach_db 'DB' with no luck.

I tried getting the database offline. That ran for about 15 minutes when I got bored and turned it off.

Anyway, I tried everything ... I made sure all connections were killed using the connections indicator in detach database using SSMS.

The following returned 0 results:

USE master SELECT * FROM sys.sysprocesses WHERE dbid = DB_ID('DB')

And the following is running for 18 minutes now:

ALTER DATABASE DB SET OFFLINE WITH ROLLBACK IMMEDIATE

I did restart SMSS regularly during all this to make sure SSMS wasn't the culprit by locking something invisibly.

Isn't there a way to brute force it? The database schema is something I'm pretty fond of but the data is expendable.

Hopefully there is some sort of a quick fix? :)

The DBA will try to reset the process tonight but I'd like to know the fix for this just in case.

Thx!

ps: I'm using DTC ... so perhaps this might explain why my database got locked up all of a sudden?

edit:

I'm now doing the following which results in an infinite execution of the final part. The first query even returns 0, so I suppose the killing of the users won't even matter.

USE [master] GO

SELECT * FROM sys.sysprocesses WHERE dbid = DB_ID('Database')

GO

DECLARE @return_value int

EXEC @return_value = [dbo].[usp_KillUsers] @p_DBName = 'Database'

SELECT 'Return Value' = @return_value

GO

ALTER DATABASE Database SET OFFLINE WITH ROLLBACK IMMEDIATE

GO

+1  A: 

How are you connecting to SQL Server? Is it possible that you're trying to detach the database while you yourself are connected to it? This can block a Detach, depending on the version of SQL Server involved.

You can try using the DAC for stuff like this.

CodeByMoonlight
Also for such tasks I like to place an explicit "use master" at the start to ensure I'm not using the DB I'm trying to detach.
KeeperOfTheSoul
I'm 100% certain I'm not using the database. I checked every place you can check to make sure no connections are active on that database.
SpoBo
A: 

Try killing all connections before detaching the database, IE:

    USE [master]
GO
/****** Object:  StoredProcedure [dbo].[usp_KillUsers]    Script Date: 08/18/2009 10:42:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_KillUsers]
  @p_DBName SYSNAME = NULL
AS

/* Check Paramaters                    */
/* Check for a DB name                 */
IF (@p_DBName IS NULL)
BEGIN
  PRINT 'You must supply a DB Name'
  RETURN
END -- DB is NULL
IF (@p_DBName = 'master')
BEGIN
  PRINT 'You cannot run this process against the master database!'
  RETURN
END -- Master supplied
IF (@p_DBName = DB_NAME())
BEGIN
  PRINT 'You cannot run this process against your connections database!'
  RETURN
END -- your database supplied

SET NOCOUNT ON

/* Declare Variables                   */
DECLARE @v_spid INT,
        @v_SQL  NVARCHAR(255)

/* Declare the Table Cursor (Identity) */
DECLARE c_Users CURSOR
   FAST_FORWARD FOR
 SELECT spid
   FROM master..sysprocesses (NOLOCK)
  WHERE db_name(dbid) LIKE @p_DBName

OPEN c_Users

FETCH NEXT FROM c_Users INTO @v_spid
WHILE (@@FETCH_STATUS <> -1)
BEGIN
  IF (@@FETCH_STATUS <> -2)
  BEGIN
    SELECT @v_SQL = 'KILL ' + CONVERT(NVARCHAR, @v_spid)
--    PRINT @v_SQL
    EXEC (@v_SQL)
  END -- -2
  FETCH NEXT FROM c_Users INTO @v_spid
END -- While

CLOSE c_Users
DEALLOCATE c_Users

This is a script to kill all user connections to a database, just pass the database name, and it will close them. Then you can try to detach the database. This script is one I found a while back and I cannot claim it as my own. I do not mean this as any sort of plagarism, I just don't have the source.

Mitch
Tested it, returned 0, so I guess all connections were closed. After that bringing it offline still failed. Told me it couldn't get a lock on the database.
SpoBo
A: 

SELECT DISTINCT req_transactionUOW FROM syslockinfo

KILL 'number_returned' (the one(s) with process_id -2)

The cause was DTC being a little bit annoying and locking up the database completely with a failed transaction. Now I would like to know the reason why this happened. But at least it gives me the ability to reset the broken transactions when the problem re-occurs.

I'm posting it here since I'm sure it'll help some people who are experiencing the same issues.

SpoBo