SQL-Server:错误 - 无法获得独占访问权限,因为数据库正在使用中

问题描述 投票:0回答:18

我实际上正在尝试制作一个脚本(在 Sql Server 2008 中)来从一个备份文件恢复一个数据库。我编写了以下代码,但出现错误 -

Msg 3101, Level 16, State 1, Line 3
Exclusive access could not be obtained because 
the database is in use.
Msg 3013, Level 16, State 1, Line 3
RESTORE DATABASE is terminating abnormally.

如何解决这个问题?

IF DB_ID('AdventureWorksDW') IS NOT NULL 
BEGIN 
RESTORE DATABASE [AdventureWorksDW] 
FILE = N'AdventureWorksDW_Data' 
FROM  
DISK = N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\Backup\AdventureWorksDW.bak' 
WITH  FILE = 1, 
MOVE N'AdventureWorksDW_Data' 
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW.mdf', 
MOVE N'AdventureWorksDW_Log'  
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW_0.LDF', 
NOUNLOAD,  STATS = 10 
END
sql sql-server sql-server-2008
18个回答
458
投票
  1. 设置恢复文件的路径。
  2. 单击左侧的“选项”。
  3. 取消选中“恢复前进行尾部日志备份”
  4. 勾选复选框 - “关闭与目标数据库的现有连接”。
  5. 单击“确定”。

135
投票

我假设如果您要恢复数据库,您不关心该数据库上的任何现有事务。正确的?如果是这样,这应该对你有用:

USE master
GO

ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
--This rolls back all uncommitted transactions in the db.
WITH ROLLBACK IMMEDIATE
GO

RESTORE DATABASE AdventureWorksDW
FROM ...
...
GO

现在,还有一件需要注意的事情。将数据库设置为单用户模式后,其他人可能会尝试连接到该数据库。如果他们成功,您将无法继续进行恢复。这是一场比赛!我的建议是同时运行所有三个语句。


76
投票

在恢复数据库之前执行此查询:

alter database [YourDBName] 
set offline with rollback immediate

恢复后的这个:

  alter database [YourDBName] 
  set online

18
投票

将原始数据库离线对我有用


16
投票

对我来说,解决方案是:

  1. 在左侧的 optoins 选项卡中选中覆盖现有数据库(使用替换)。

  2. 取消选中所有其他选项。

  3. 选择源数据库和目标数据库。

  4. 点击确定。

就是这样。


9
投票

在恢复数据库之前,使用以下脚本查找并终止所有打开的数据库连接。

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...'

希望这会有所帮助...


5
投票

我刚刚重新启动了 sqlexpress 服务,然后恢复就完成了


4
投票

我认为您只需要在尝试恢复之前将数据库设置为单用户模式,如下所示,只需确保您正在使用

master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER

4
投票

我在尝试恢复 MS SQL Server 2012 上的数据库时遇到了此问题。

这对我有用

我必须首先在备份文件上运行下面的

RESTORE FILELISTONLY
命令来列出逻辑文件名:

RESTORE FILELISTONLY 
    FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\my_db_backup.bak'

这分别显示了数据库的数据和日志文件的 LogicalName 和相应的 PhysicalName

LogicalName      PhysicalName               
com.my_db        C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\com.my_db.mdf
com.my_db_log    C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\com.my_db_log.ldf

我所要做的就是简单地在我的数据库恢复脚本中分别替换数据库的数据和日志文件的LogicalName和相应的PhysicalName

USE master;
GO

ALTER DATABASE my_db SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO

    
RESTORE DATABASE my_db
    FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Backup\my_db_backup.bak'
    WITH REPLACE,
    MOVE 'com.my_db' TO 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\com.my_db.mdf',
    MOVE 'com.my_db_log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\com.my_db_log.ldf'
GO
    
ALTER DATABASE my_db SET MULTI_USER;
GO

数据库恢复任务成功运行:

仅此而已。

我希望这有帮助


3
投票
Use Master
alter database databasename set offline with rollback immediate;

--Do Actual Restore
RESTORE DATABASE databasename
FROM DISK = 'path of bak file'
WITH MOVE 'datafile_data' TO 'D:\newDATA\data.mdf',
MOVE 'logfile_Log' TO 'D:\newDATA\DATA_log.ldf',replace

alter database databasename set online with rollback immediate;
GO

2
投票

将数据库设置为单用户模式对我来说不起作用,但将其脱机,然后将其重新联机确实有效。它位于数据库的右键菜单中的“任务”下。

请务必选中对话框中的“删除所有活动连接”选项。


1
投票

当没有足够的磁盘空间来恢复 Db 时,我收到此错误。清理一些空间就解决了。


1
投票

Vinu M Shankar 的解决方案对我有用。

但我必须选中:“在恢复之前进行尾部日志备份”复选框才能正常工作。


0
投票

这是我将数据库从生产恢复到开发的方法:

注意:我通过 SSAS 作业来每天将生产数据库推送到开发:

Step1:删除开发中前一天的备份:

declare @sql varchar(1024);

set @sql = 'DEL C:\ProdAEandAEXdataBACKUP\AE11.bak'
exec master..xp_cmdshell @sql

Step2:将生产数据库复制到开发:

declare @cmdstring varchar(1000)
set @cmdstring = 'copy \\Share\SQLDBBackup\AE11.bak C:\ProdAEandAEXdataBACKUP'
exec master..xp_cmdshell @cmdstring 

Step3:通过运行.sql脚本恢复

SQLCMD -E -S dev-erpdata1 -b -i "C:\ProdAEandAEXdataBACKUP\AE11_Restore.sql"

AE11_Restore.sql 文件中的代码:

RESTORE DATABASE AE11
FROM DISK = N'C:\ProdAEandAEXdataBACKUP\AE11.bak'
WITH MOVE 'AE11' TO 'E:\SQL_DATA\AE11.mdf',
MOVE 'AE11_log' TO 'D:\SQL_LOGS\AE11.ldf',
RECOVERY;

0
投票

解决方案1:重新启动SQL服务并尝试恢复DB 解决方案2:重新启动系统/服务器并尝试恢复数据库 解决方案 3:收回当前数据库,删除当前/目标数据库并尝试恢复数据库。


0
投票

当我不知道其他人在另一个 SSMS 会话中连接到数据库时,我收到了此错误。在我将它们注销后,恢复成功完成。


0
投票

就我而言,虽然我尝试了上述所有解决方案,但有效的是重新启动 SSMS。


0
投票

我希望您不介意要恢复的数据库内的数据。如果是这样;在选项下

  • 转到恢复选项
  • 选择下面的 RESTORE WITH NORECOVERY 选项 恢复状态
  • 点击确定

以上对我有用。

© www.soinside.com 2019 - 2024. All rights reserved.