分离数据库/脱机失败

时间:2009-08-18 15:31:47

标签: tsql transactions locking msdtc

我目前正在生产服务器上分离开发数据库。由于这是一个生产服务器,我不想重启sql服务。这是最糟糕的情况。

显然我试过通过SSMS分离它。告诉我有一个活跃的连接,我断开了它。第二次分离时,它告诉我,因为它正在使用中,所以不可能。

我试过EXEC sp_detach_db'DB'而没有运气。

我尝试让数据库脱机。当我感到无聊并将其关闭时,这种情况持续了大约15分钟。

无论如何,我尝试了一切......我确保使用SSMS使用分离数据库中的连接指示符来杀死所有连接。

以下返回0结果:

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

以下现在运行18分钟:

ALTER DATABASE DB设置为OFFLINE,ROLLBACK IMMEDIATE

我确实在所有这些过程中定期重启SMSS,以确保SSMS不是隐形锁定的罪魁祸首。

有没有办法蛮力呢?数据库模式是我非常喜欢的,但数据是可以消耗的。

希望有某种快速解决方法吗? :)

DBA今晚会尝试重置这个过程,但我想知道这个问题的解决方案以防万一。

THX!

ps:我正在使用DTC ...所以也许这可以解释为什么我的数据库被突然锁定了?

编辑:

我现在正在执行以下操作,这会导致最终部分的无限执行。第一个查询甚至返回0,所以我认为杀死用户甚至不重要。

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 ='数据库'

选择'返回值'= @return_value

GO

ALTER DATABASE数据库设置OFFLINE,ROLLBACK IMMEDIATE

GO

3 个答案:

答案 0 :(得分:1)

您是如何连接到SQL Server的?您是否有可能在自己连接数据库时尝试分离数据库?这可以阻止分离,具体取决于所涉及的SQL Server版本。

您可以尝试使用DAC这样的内容。

答案 1 :(得分:1)

在分离数据库之前尝试终止所有连接,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

这是一个杀死数据库所有用户连接的脚本,只需传递数据库名称,它就会关闭它们。然后,您可以尝试分离数据库。这个脚本是我之前发现的那个,我不能把它当作我自己的。我并不是说这是任何形式的庸俗,我只是没有来源。

答案 2 :(得分:1)

SELECT DISTINCT req_transactionUOW FROM syslockinfo

KILL 'number_returned'(具有process_id -2的那个)

原因是DTC有点烦人,并且在事务失败的情况下完全锁定数据库。现在我想知道发生这种情况的原因。但至少它让我能够在问题再次发生时重置已损坏的交易。

我在这里发帖,因为我相信它会帮助一些遇到同样问题的人。