数据库处于“恢复”状态中。

654
我备份了一个数据库。
BACKUP DATABASE MyDatabase
TO DISK = 'MyDatabase.bak'
WITH INIT --overwrite existing

然后尝试恢复它:
RESTORE DATABASE MyDatabase
   FROM DISK = 'MyDatabase.bak'
   WITH REPLACE --force restore over specified database

现在数据库被卡在恢复状态中。
有些人推测这是因为备份中没有日志文件,需要使用以下方法进行回滚:
RESTORE DATABASE MyDatabase
WITH RECOVERY 

除此之外,当然是失败了。
Msg 4333, Level 16, State 1, Line 1
The database cannot be recovered because the log was not restored.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

在灾难情况下,你最不希望的就是一个无法恢复的恢复。
备份包含了数据和日志文件:
RESTORE FILELISTONLY 
FROM DISK = 'MyDatabase.bak'

Logical Name    PhysicalName
=============   ===============
MyDatabase    C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MyDatabase.mdf
MyDatabase_log  C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\MyDatabase_log.LDF

6
我遇到了完全相同的问题,尝试了所有的解决方案都失败了。有趣的是,我直接登录到 SQL 服务器上,并通过 SSMS 发出了 DROP DATABASE db 命令,这样就成功了(之前我是通过另一台机器上的 SSMS 发出指令)。我猜其他的解决方案也会起作用的。 - Salman A
29个回答

910

我曾经遇到这样的情况:使用Symantec Backup Exec 11d将一个数据库恢复到SQL Server 2005标准版实例时,恢复作业完成后该数据库仍处于“恢复”状态。我的磁盘空间没有问题——数据库只是没有从“恢复”状态中恢复出来。

我对SQL Server实例运行了以下查询,发现数据库立刻变得可用:

RESTORE DATABASE <database name> WITH RECOVERY

6
我们的一个数据库在还原过程中卡了两个小时。我们从另一台机器上运行了这个命令来连接主数据库,问题得到了解决。谢谢! - Pete
19
+1,但有点意外。运行时,我收到了一个错误消息,说数据库已经完全恢复。但它仍然显示为“恢复中”状态。所以我在管理工具中右键单击它,点击刷新,然后它就回到正常状态了。 - dario_ramos
3
我使用 Mng Studio 向导进行了还原,输入了一个新的数据库名称,但错误地将文件名设为现有数据库的相同名称。我收到了“还原失败但日志尾部成功”的错误提示,导致该数据库附加到这些文件上一直处于恢复状态。这个命令似乎已经将数据库还原回其之前的状态。 - Chris
6
这很有效。我试图将备份恢复到一个辅助数据库,但由于某种原因,我的主数据库进入了还原状态。这实际上恢复了我的数据库。非常感谢! - Aravindh
2
一些SSMS还原向导的默认设置会使源数据库处于正在还原状态,这样您就可以继续恢复各种备份或日志文件,而不必担心用户,这个命令是一旦完成后将数据库恢复正常的适当方式。 - Tim Lehner
显示剩余11条评论

477

在恢复数据库的过程中,您需要使用 WITH RECOVERY 选项,使得数据库在还原完成后可以在线上访问。

当然,只有在您不想要恢复任何事务日志备份的情况下才是这样。也就是说,您只想恢复一个数据库备份,然后可以访问该数据库。

您的命令应该像这样:

RESTORE DATABASE MyDatabase
   FROM DISK = 'MyDatabase.bak'
   WITH REPLACE,RECOVERY

您可能会更成功地使用SQL Server Management Studio中的恢复数据库向导。这样,您可以选择特定的文件位置、覆盖选项和WITH Recovery选项。


3
我从未在执行他所做的操作时使用过恢复语句。使用 WITH REPLACE 应该就足够了。 - Sam
8
是的,我之前使用了NORECOVERY,但恢复过程卡住了。现在改用WITH RECOVERY和REPLACE,恢复过程不再卡住了。 - Junior Mayhé
@JohnSansom 当然,使用SQL Management Studio中的还原选项是恢复数据库最可靠的方法,但有时候人们会分发没有管理工具的SQL Server Express版本(比如我们公司),需要提供自己的工具来执行这些操作。 - Jerry Dodge
3
如果同一数据库上之前的还原操作处于暂停/休眠状态,那么是的。简单地停止/取消正在进行中的还原操作应该会产生相同的效果。 - John Sansom
在我的情况下,我需要删除数据库(并且失去其中所有的数据),然后再进行恢复。 - deldev
显示剩余8条评论

113

这是如何操作的:

  1. 停止服务(MSSQLSERVER);
  2. 重命名或删除数据库和日志文件(C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data...)或您存放文件的任何位置;
  3. 启动服务(MSSQLSERVER);
  4. 删除问题数据库;
  5. 再次恢复数据库。

9
为什么不直接删除数据库?这样您就不必停止服务。 - ErikE
9
对于我来说,SQL Server 表示在还原过程中无法删除数据库,即使实际上并未进行还原。 - Erik Philips
8
在我的情况下,使用SQL命令 drop database <dbname> 在查询窗口中删除处于“正在还原…”状态的数据库就足够了。然后我右键单击数据库并选择刷新,这将在管理工具中删除该条目。之后我进行了新的还原,一切都正常(注意,将其脱机不起作用,重启SQL服务也不起作用,服务器重新启动也不起作用)。 - Matt
我支持这个答案。对我来说,适用于SQL 2014。 - Andez
@JimsonKannantharaJames - 看起来它也帮助了其他人,所以我将其提升为答案。(https://dev59.com/bHRB5IYBdhLWcg3wxZ1K#51405958) - Matt
显示剩余8条评论

93

我曾经遇到过停止日志备份次要服务器的类似事件。 在从主服务器删除该服务器并停止日志备份后,次要服务器上的数据库在命令后陷入恢复状态。

RESTORE DATABASE <database name> WITH RECOVERY

数据库消息:

还原数据库成功处理了0页,用时18.530秒(0.000 MB/秒)。

在那18秒后,数据库可再次使用。


6
当你已经恢复了数据库但忘记了RECOVERY选项时,这将非常有用。 - JBickford
3
这就是我需要的,以便在将此数据库的备份还原到不同的数据库名称后使其离开“正在还原”状态。非常感谢。 - Sean

92

我在使用SQL Management Studio进行恢复时遇到了类似的问题。我尝试将数据库的备份还原到一个新的具有不同名称的数据库中,但一开始失败了。在修复新数据库的文件名后,操作成功执行 - 无论如何,我所描述的问题仍然发生,即使我第一次就做对了。因此,在恢复完成后,原始数据库的名称旁边仍带有“(正在还原...)”。考虑到上面(Bhusan的)论坛答案,我尝试在查询编辑器中运行以下命令:

RESTORE DATABASE "[NAME_OF_DATABASE_STUCK_IN_RESTORING_STATE]"

问题得到解决。一开始因为数据库名称包含特殊字符而遇到了困难。我通过在名称周围添加双引号来解决这个问题,单引号不起作用,会导致“附近语法不正确”的错误。

这是我尝试解决这个问题(将数据库卡在恢复状态)所采取的最小解决方案,我希望它可以应用于更多情况。


2
完美地工作了 - 不需要再次拆卸和重新启动。每个80+ Gb的3个数据库需要一些时间!谢谢! - Christer
1
我在生产环境中差不多完成了它。我先在本地尝试了一下,最终陷入了同样的情况,发现了您的评论。教训是:在重要情况下使用脚本,并不要信任 SSMS。 - Mariusz
1
当我将数据库的一个仅限复制文件备份还原到新数据库时,出现了这个问题。原始数据库显示错误。这个解决方案起作用了,我得到的响应是“RESTORE DATABASE successfully processed 0 pages in 0.263 seconds (0.000 MB/sec)。”,所以看来SQL Server只是对数据库的状态感到困惑。 - R. Schreurs
1
对我来说有效,但只有在我删除双引号时才有效 - 我只将[MY_DB_NAME]作为参数。 - StackOverflowUser
1
立即生效。感谢提示。最简单的解决方案。 - FunMatters

39

好的,我有类似的问题,就像Pauk的情况一样,这是由于服务器在恢复过程中磁盘空间不足而导致永久性恢复状态。

如何结束这种状态而不停止SQL Server服务?

我找到了一个解决方案 :)

Drop database *dbname*

35

默认情况下,在执行RESTORE DATABASE/RESTORE LOG命令时,会使用WITH RECOVERY选项。如果您卡在“正在恢复”过程中,可以通过执行以下操作将数据库恢复为在线状态:

执行RESTORE DATABASE [DatabaseName] WITH RECOVERY;

执行上述命令后,数据库将进入可用状态。

RESTORE DATABASE YourDB WITH RECOVERY
GO

如果需要还原多个文件,CLI命令分别需要使用WITH NORECOVERY和WITH RECOVERY - 命令中只有最后一个文件应该使用WITH RECOVERY将数据库恢复在线状态:

RESTORE DATABASE YourDB FROM DISK = 'Z:\YourDB.bak'
WITH NORECOVERY
GO
RESTORE LOG YourDB FROM DISK = 'Z:\YourDB.trn'
WITH RECOVERY
GO

您还可以使用 SQL Server Management Studio 向导:

输入图像描述

也有虚拟恢复过程,但您需要使用第三方解决方案。通常情况下,您可以使用数据库备份作为在线数据库。ApexSQL 和 Idera 都有自己的解决方案。SQL Hammer 对 ApexSQL Restore 进行了评测。如果您处理大量备份,则虚拟恢复是一种好的解决方案。恢复过程要快得多,还可以节省磁盘空间。您可以在这里查看信息图表进行一些比较。


28

右键数据库,选择任务 --> 恢复 --> 事务日志。 在事务文件中,如果您看到一个文件被选中,则 SQL Server 正试图从该文件进行恢复。 取消选中该文件,然后点击“确定”。数据库已经恢复。......

这个方法解决了我的问题,希望能对某些人有所帮助。


非常好!我需要停止“还原”状态才能继续使用数据库。谢谢。 - AmyNguyen
这是对我有效的那一个。非常感谢。 - undefined

24

这可能很明显,但是我刚刚遇到了这个问题:

如果您正在进行尾部日志备份,则 SSMS 恢复向导中勾选此选项也会导致此问题 -“将源数据库保留在恢复状态(WITH NORECOVERY)”

输入图像描述


8
如果您处于此状态,则最好的选择是:
  1. 右键单击数据库,选择任务->还原->事务日志
  2. 找到用于尾部日志备份的备份文件
  3. 还原备份文件 还原应该成功并使数据库重新上线。
- Ryan Gross

17

我搞清楚原因了。

如果发出 RESTORE DATABASE 命令的客户端在还原期间断开连接,还原将会卡住。

很奇怪的是,当服务器接收到客户端连接请求并开始还原数据库时,除非客户端始终保持连接,否则服务器将无法完成还原。


12
所有的SQL命令都要求客户端始终保持连接。 - mrdenny
2
@mrdenny:我本来以为当客户端断开连接时,更改会被撤销。 - Ian Boyd
1
我使用微软的PHP PDO驱动运行此命令时遇到了相同的问题。但是,当使用微软SQL Server管理工具运行时,它可以正常工作。我想知道如何使我的PHP应用程序始终保持连接? - channa ly
这里也发生了类似的情况,数据库在可能的连接中断后被卡在恢复/单用户模式。从新会话中杀死了所有其他SPID,但仍然卡住了。最终通过删除数据库来解决问题。 - crokusek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接