今天我试图在已经存在的数据库上恢复数据库,我只需右键单击 SSMS 中的数据库 --> 任务 --> 脱机,这样我就可以恢复数据库。
一个小的弹出窗口出现并显示Query Executing.....
了一段时间,然后抛出一个错误说Database is in use cannot take it offline
。我从中收集到该数据库的一些活动连接,因此我尝试执行以下查询
USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
再次在这一点上,SSMS 显示Query Executing.....
了一段时间,然后抛出以下错误:
Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'My_DatabaseName'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
在此之后,我无法通过 SSMS 连接到数据库。当我尝试使用 SSMS 使其脱机时,它抛出了一个错误消息:
Database is in Transition. Try later .....
在这一点上,我根本无法触及数据库,我尝试过的任何操作都返回了相同的错误消息Database is in Transition
。
我在谷歌上阅读了一些人们遇到类似问题的问题,他们建议关闭 SSMS 并再次打开它,我也是如此,因为它只是一个开发服务器,我刚刚使用 SSMS 删除了数据库并在新数据库上恢复。
我的问题是什么可能导致这种情况?以及如何避免这种情况在未来发生,如果我将来遇到同样的情况,除了删除整个数据库之外,还有其他方法可以解决它吗???
谢谢
复制品
在新的查询窗口中输入以下内容
<YourDatabase>
->Tasks
->Take Offline
打开第二个新查询窗口并输入以下内容:
系统将提示您以下消息:
发生这种情况的原因可以从与以下类似的诊断查询中找到:
对于它的价值,您不需要对象资源管理器来重现此错误。您只需要一个尝试相同操作的被阻止请求(在这种情况下,使数据库脱机)。有关 T-SQL 中的三个步骤,请参见以下屏幕截图:
您最有可能看到的是您的对象资源管理器会话被另一个会话阻止(由 显示
blocking_session_id
)。该对象资源管理器会话将尝试获取X
数据库上的排他锁 ( )。在上述重现的情况下,对象资源管理器会话被授予更新锁 (U
) 并尝试转换为排他锁 (X
)。它有一个 wait_typeLCK_M_X
,被第一个查询窗口表示的会话阻塞(在数据库上获取use <YourDatabase>
共享锁 (S
))。然后这个错误来自另一个试图获得锁的会话,并且这个错误消息导致会话拒绝访问试图转换到不同状态的数据库(在这种情况下,在线状态到离线过渡)。
下次你应该怎么做?
首先,不要惊慌,也不要开始删除数据库。您需要采取故障排除方法(使用与上述类似的诊断查询)来找出您看到的原因。有了这样的消息,或者当某些东西出现“挂起”时,您应该自动假设缺乏并发性并开始深入研究阻塞(
sys.dm_tran_locks
这是一个好的开始)。作为旁注,我真的相信你最好在采取任何随机行动之前找出问题的根源。不仅是这个操作,而且适用于所有你不期望的行为。知道是什么真正导致了你的问题,很明显这真的没什么大不了的。你基本上有一个阻塞链,而父阻塞器是你很可能刚刚发出的
KILL
,或者如果它是你不想要的会话请求,KILL
那么你可以等到它完成。无论哪种方式,您都知道根据您的特定情况(回滚或等待提交)做出正确和谨慎的决定。另一件值得注意的事情,这是我总是选择 T-SQL 替代方案而不是 GUI 的原因之一。您确切地知道您正在使用 T-SQL 执行什么以及 SQL Server 在做什么。毕竟,您发出了明确的命令。当您使用 GUI 时,实际的 T-SQL 将是一个抽象。在这种情况下,我查看了被阻止的对象资源管理器尝试使数据库脱机,结果是
ALTER DATABASE <YourDatabase> SET OFFLINE
. 没有尝试回滚,这就是它无限期等待的原因。在您的情况下,如果您想回滚在该数据库上具有锁定的会话,ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATE
那么如果您最初确定回滚是可以的,那么您很可能就足够了。只需关闭 SQL Server Management Studio (SSMS) 并重新打开即可解决我的问题。
无需执行任何操作,只需
SqLWB.exe
从任务管理器中终止进程,打开 SQL Server,右键单击数据库并使其脱机。如果它不起作用,则在会话被终止后,键入命令然后离线。它也适用于我。