【问题标题】:unable to restore database in sql server (single_user)无法在 sql server (single_user) 中恢复数据库
【发布时间】:2010-09-03 20:58:19
【问题描述】:

我正在尝试在我的 sql server 2005 express edition 中恢复数据库。我知道要恢复数据库,我需要将其设置为单个用户。我正在给出这个命令以使其成为单个用户

USE [master]
ALTER DATABASE database_name SET SINGLE_USER WITH ROLLBACK IMMEDIATE

这个命令正确执行,我什至可以在这个数据库的对象资源管理器中看到一个小图像,表明现在是单个用户。

现在我正在尝试通过以下步骤恢复数据库 ->右键单击数据库和任务,然后恢复数据库。我正在选择备份文件所在的路径,然后单击还原。

但我仍然收到错误“由于数据库正在使用(microsoft.sqlserver.smo),无法获得独占访问权限。我错过了什么吗?我已经用谷歌搜索过了,所有大多数网站都建议数据库需要在单用户模式下,仅此而已。

我没有尝试数据库方法的分离和附加。我以前从未这样做过,想知道这样做是否安全。

编辑:感谢您的回答。两人都建议了我相同的答案,所以我将一个答案标记为已选择。

我什至从选项中选择了覆盖现有数据库。

【问题讨论】:

    标签: sql-server sql-server-2005-express


    【解决方案1】:

    首先,最好备份和恢复,而不是分离和附加。

    其次,您用于将数据库设置为 SINGLE_USER 的会话很可能是您尝试运行还原时仍然拥有它的会话(因为您使用的是 GUI,它在其下连接自己的会话,因此无法访问)。

    要么以文本命令的形式执行恢复,要么切换查询窗口以首先使用另一个数据库,例如 master。或者您可以关闭查询窗口,使其不再连接。

    您可以随时查看谁与select * from master.dbo.sysprocesses 有联系。

    更新

    假设您要恢复的数据库已经存在,并且如果您在磁盘上有一个备份文件(其中没有多个备份)并且在恢复完整备份后无需恢复日志文件,则恢复via script 超级超级简单:

    RESTORE DATABASE DBName FROM DISK = 'C:\path\DBNameBackup.bak';
    

    学习此语法将使您的生活更轻松,因为当您设置 SINGLE_USER 时,您已经处于连接的唯一会话中。另外,我发现输入恢复命令比使用 GUI 更快,而且我喜欢我对事物的控制。重复这一点最终会在您的脑海中巩固它,您不必再查找语法。

    恢复日志文件甚至没有那么难。只需记住一件简单的事情,WITH NORECOVERY:

    RESTORE DATABASE DBName FROM DISK = 'C:\path\DBNameBackup.bak' WITH NORECOVERY;
    RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackup1.log' WITH NORECOVERY;
    RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackup2.log' WITH NORECOVERY;
    RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackup3.log' WITH NORECOVERY;
    ... 4 5 6 7 and so on
    RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackupX.log' WITH RECOVERY;
    

    那里...您已经非常轻松地恢复了您的日志文件。您甚至可以使用WITH STOPAT 恢复到准确的时间点!此外,如果您忘记并意外提交了最后一个日志恢复语句WITH NORECOVERY,那么您只需发出RESTORE DATABASE DBName WITH RECOVERY; 来执行使数据库可用的最后步骤(回滚未提交的事务等)。

    【讨论】:

      【解决方案2】:

      您可以使用此脚本杀死所有使用数据库的进程,然后再次尝试恢复它:

      declare @sql as varchar(20), @spid as int
      select @spid = min(spid)  from master..sysprocesses  where dbid = db_id('<database_name>') 
      and spid != @@spid    
      
      while (@spid is not null)
      begin
          print 'Killing process ' + cast(@spid as varchar) + ' ...'
          set @sql = 'kill ' + cast(@spid as varchar)
          exec (@sql)
      
          select 
              @spid = min(spid)  
          from 
              master..sysprocesses  
          where 
              dbid = db_id('<database_name>') 
              and spid != @@spid
      end 
      
      print 'Process completed...'
      

      【讨论】:

        【解决方案3】:
        • 转到左侧列表中“常规”下方的“选项”项。
        • 确保选中“覆盖现有数据库”(“还原选项”部分)。

        祝你好运。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-23
          相关资源
          最近更新 更多