【问题标题】:When restoring a backup, how do I disconnect all active connections?恢复备份时,如何断开所有活动连接?
【发布时间】:2010-11-12 08:33:48
【问题描述】:

由于活动连接,My SQL Server 2005 不会恢复备份。怎么强制?

【问题讨论】:

  • 您是否总是想要终止与您想要“恢复”的数据库的所有连接?或者有时您不想终止现有连接?另外,您是否需要担心连接池?

标签: sql-server sql-server-2005 backup restore disconnect


【解决方案1】:

您想将您的数据库设置为单用户模式,进行还原,然后将其设置回多用户:

ALTER DATABASE YourDB
SET SINGLE_USER WITH
ROLLBACK AFTER 60 --this will give your current connections 60 seconds to complete

--Do Actual Restore
RESTORE DATABASE YourDB
FROM DISK = 'D:\BackUp\YourBaackUpFile.bak'
WITH MOVE 'YourMDFLogicalName' TO 'D:\Data\YourMDFFile.mdf',
MOVE 'YourLDFLogicalName' TO 'D:\Data\YourLDFFile.ldf'

/*If there is no error in statement before database will be in multiuser
mode.  If error occurs please execute following command it will convert
database in multi user.*/
ALTER DATABASE YourDB SET MULTI_USER
GO

参考:Pinal Dave (http://blog.SQLAuthority.com)

官方参考:https://msdn.microsoft.com/en-us/library/ms345598.aspx

【讨论】:

  • 与其发出 IMMEDIATE ROLLBACK ,不如只在特定的 DELAY 之后 ROLLBACK ,从而给用户查询一个自然完成的机会。
  • 好点,更新为回滚以包含 AFTER 60 命令以允许完成当前查询
  • 嗨@brendan,如果回滚时间超过 60 秒怎么办?谢谢
  • 如果您正在恢复数据库,无论您是ROLLBACK IMMEDIATE 还是ROLLBACK AFTER 60,打开的事务都将丢失。保存该数据的唯一方法是在回滚后执行另一次备份。但是您正在从不同的备份中恢复。那么,等待有什么意义呢?我错过了什么吗?
  • @DMason,我也很好奇这个问题。使用带有回滚模式的 single_user 是否会在等待期间阻止新连接?如果是这样,我想知道这是否是一种至少让只读操作完成而不是突然结束它们的更清洁/更好的方式?
【解决方案2】:

SQL Server 管理工作室 2005

当您右键单击数据库并单击Tasks,然后单击Detach Database,它会弹出一个包含活动连接的对话框。

通过单击“消息”下的超链接,您可以终止活动连接。

然后您可以在不分离数据库的情况下终止这些连接。

更多信息here

SQL Server 管理工作室 2008

SQL Server Management Studio 2008 的界面已更改,步骤如下(通过:Tim Leung

  1. 在对象资源管理器中右键单击服务器并选择“活动监视器”。
  2. 打开后,展开进程组。
  3. 现在使用下拉菜单按数据库名称过滤结果。
  4. 通过选择右键单击“终止进程”选项终止服务器连接。

【讨论】:

  • 如果您遇到与@Ryan 相同的问题,可能是因为您使用的是 Management Studio 2008(或更高版本),而不是 Management Studio 2005。在 Management Studio 2008 中做同样的事情,在对象资源管理器中右键单击您的服务器并选择“活动监视器”。当它打开时,展开 Processes 组。现在使用下拉菜单按数据库名称过滤结果。您现在可以通过选择右键单击“终止进程”选项来终止您的连接。
【解决方案3】:

这段代码对我有用,它会杀死数据库的所有现有连接。 您所要做的就是更改 Set @dbname = 'databaseName' 行,使其具有您的数据库名称。

Use Master
Go

Declare @dbname sysname

Set @dbname = 'databaseName'

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(@dbname)
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = min(spid) from master.dbo.sysprocesses
        where dbid = db_id(@dbname) and spid > @spid
End

在此之后我能够恢复它

【讨论】:

  • 这是最快的方法(SingleUserMode * 20 = 60s,Kill * 20 = 5s)。
  • 它对我不起作用。数据库仍在使用中。我使用 SQL Server 2008。
  • 我发现多次运行该代码,一个接一个,最终会成功。有时有些东西会在您的 KILL 和恢复之间潜入。有时你必须一个接一个地运行 kill THEN 恢复。
  • 完全取决于应用程序尝试重新连接的积极性。几个懒惰的用户?效果很好。在一秒钟内重新连接的大容量应用服务器?没那么多。
【解决方案4】:

试试这个:

DECLARE UserCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT
    spid
FROM
    master.dbo.sysprocesses
WHERE DB_NAME(dbid) = 'dbname'--replace the dbname with your database
DECLARE @spid SMALLINT
DECLARE @SQLCommand VARCHAR(300)
OPEN UserCursor
FETCH NEXT FROM UserCursor INTO
    @spid
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @SQLCommand = 'KILL ' + CAST(@spid AS VARCHAR)
    EXECUTE(@SQLCommand)
    FETCH NEXT FROM UserCursor INTO
        @spid
END
CLOSE UserCursor
DEALLOCATE UserCursor
GO

【讨论】:

    【解决方案5】:

    重新启动 SQL Server 将断开用户连接。我找到的最简单的方法 - 如果您想使服务器脱机,也很好。

    但由于某些非常奇怪的原因,“脱机”选项不能可靠地执行此操作,并且可能会挂起或混淆管理控制台。重启后离线工作

    有时这是一个选项 - 例如,如果您停止了作为连接源的网络服务器。

    【讨论】:

    • +1。接受的答案不适用于 SQL Express(例如在开发环境中),因为 SQL Express 没有活动监视器
    • @MattFrear:这不是真的!至少在 2008 R2 Express 中,我在服务器节点上看到了一个工具栏按钮和一个上下文菜单条目。
    • 重新启动整个 SQL 服务器将终止与所有数据库的连接。一台服务器可能支持许多数据库,但现在只需要恢复一个。
    • 这绝对是终止与 1 个数据库的连接的最糟糕方法。特别是如果您还有许多其他数据库仍在被其他用户使用。我强烈建议不要使用这种方法。这是 100%,完全矫枉过正!
    • @JohnWaclawski 我不知道最坏的情况,但肯定是最懒惰的——这就是我有时说的原因。无论如何,它并没有真正比其他方法节省任何时间
    【解决方案6】:

    我在 SQL Server 2008 中自动执行还原过程时遇到了这个问题。 我的(成功的)方法是结合了所提供的两个答案。

    首先,我运行了所述数据库的所有连接,并将它们杀死。

    DECLARE @SPID int = (SELECT TOP 1 SPID FROM sys.sysprocess WHERE dbid = db_id('dbName'))
    While @spid Is Not Null
    Begin
            Execute ('Kill ' + @spid)
            Select @spid = top 1 spid from master.dbo.sysprocesses
            where dbid = db_id('dbName')
    End
    

    然后,我将数据库设置为 single_user 模式

    ALTER DATABASE dbName SET SINGLE_USER
    

    然后,我运行还原...

    RESTORE DATABASE and whatnot
    

    再次终止连接

    (same query as above)
    

    并将数据库设置回多用户。

    ALTER DATABASE dbName SET MULTI_USER
    

    这样,在设置为单一模式之前,我确保没有连接挂起数据库,因为如果有的话,前者会冻结。

    【讨论】:

      【解决方案7】:

      这些都不适合我,无法删除或断开当前用户。也看不到与数据库的任何活动连接。重新启动 SQL Server(右键单击并选择重新启动)允许我这样做。

      【讨论】:

        【解决方案8】:

        补充已经给出的建议,如果您有一个通过 IIS 运行的 Web 应用程序使用数据库,您可能还需要在恢复时停止(不回收)该应用程序的应用程序池,然后重新开始。停止应用程序池会终止活动的 http 连接并且不再允许,否则最终可能会导致触发连接到数据库的进程,从而锁定数据库。这是一个已知问题,例如 Umbraco 内容管理系统在恢复其数据库时的问题

        【讨论】:

          【解决方案9】:

          以上都不适合我。我的数据库没有使用 Activity Monitor 或 sp_who 显示任何活动连接。我最终不得不:

          • 右键单击数据库节点
          • 选择“分离...”
          • 选中“断开连接”框
          • 重新附加

          不是最优雅的解决方案,但它可以工作,并且不需要重新启动 SQL Server(对我来说不是一个选项,因为 DB 服务器托管了许多其他数据库)

          【讨论】:

          • 这完全是矫枉过正。使用上面的 KILL 代码。为我处理数百个恢复工作。
          • 我正在使用的数据库不会杀死一切——但是,这可能是他们的设置问题。我同意这通常要容易得多。
          【解决方案10】:

          我更喜欢这样做,

          alter database set offline with rollback immediate

          然后恢复您的数据库。 之后,

          alter database set online with rollback immediate

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-03-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-07-29
            • 1970-01-01
            • 2011-01-11
            相关资源
            最近更新 更多