退出单用户模式

267

目前,我的数据库处于单用户模式。当我尝试扩展我的数据库时,会出现以下错误:

数据库 'my_db' 不可用。(ObjectExplorer)

此外,当我尝试删除数据库时,也会出现以下错误:

无法更改数据库 'my_db' 的状态或选项。该数据库处于单用户模式,并且当前有用户连接到该数据库。

我该如何退出单用户模式?我没有用户正在使用这个数据库。

当我尝试使用IIS浏览我的网站时,会出现以下错误:

在执行当前网页请求的过程中生成了一个未处理的异常。有关异常来源和位置的信息可以使用下面的异常堆栈跟踪来识别。

我感觉单用户模式是导致这个问题的原因。


你可能已经分离了数据库。请先断开连接,然后重新连接服务器。然后右键单击数据库文件夹,选择“附加”,并从硬盘上选择你的数据库mdf文件。你会发现单用户模式不再存在。 - Praveen Patel G
20个回答

484

SSMS通常在后台使用多个数据库连接。在更改访问模式之前,您需要终止这些连接:

  1. 首先,确保对象资源管理器指向系统数据库,如master。
  2. 其次,执行sp_who2并查找到所有连接到数据库'my_db'的连接。通过执行KILL { session id }来杀死所有连接,其中session id是由sp_who2列出的SPID
  3. 第三步,打开新的查询窗口。

完成以上三个步骤后,执行以下代码。

-- Start in master
USE MASTER;

-- Add users
ALTER DATABASE [my_db] SET MULTI_USER
GO

请参见我的博客文章,讲述数据库文件的管理。虽然该文章是关于移动文件的,但用户管理也是相同的。


5
当我使用'sp_who2'命令时,我没有看到任何与'my_db'相关联的DBName。我没有终止这些连接中的任何一个。运行了这些命令后,我收到了相同的错误 =[:' “无法在此时更改数据库'my_db'的状态或选项。该数据库处于单用户模式,并且当前有用户连接到它。Msg 5069,Level 16,State 1,Line 1 ALTER DATABASE语句失败。” - Liondancer
2
你确定你在 master 分支下,sp_who2 命令没有显示数据库 my_db 的任何行,并且你的对象资源管理器中也不是在 my_db 数据库上。 - CRAFTY DBA
1
尝试断开并重新连接SSMS。必须有某些内容连接到该数据库。另一个选项是使用专用管理员控制台(DAC)进行连接。这假设您是系统管理员。然后终止有问题的spid。 - CRAFTY DBA
2
另外,下载我的usp_who2脚本(http://craftydba.com/wp-content/uploads/2011/09/usp-who2.txt)。执行它。它将把该实用程序放置在msdb.dbo.usp_who2中。它将sp_who2的结果保存到tempdb中的一个表中,根据数据库名称进行过滤。请发布错误的图像以帮助我们更好地解决问题。祝你好运。 - CRAFTY DBA
3
找到SPID,使用以下命令: Kill 100。这里的数字100是会话(SPID)的编号。 - CRAFTY DBA
显示剩余6条评论

74

首先,找到并KILL掉所有当前运行的进程。

然后,运行以下T-SQL将数据库设置为MULTI_USER模式。

USE master
GO
DECLARE @kill varchar(max) = '';
SELECT @kill = @kill + 'KILL ' + CONVERT(varchar(10), spid) + '; '
FROM master..sysprocesses 
WHERE spid > 50 AND dbid = DB_ID('<Your_DB_Name>')
EXEC(@kill);

GO
SET DEADLOCK_PRIORITY HIGH
ALTER DATABASE [<Your_DB_Name>] SET MULTI_USER WITH NO_WAIT
ALTER DATABASE [<Your_DB_Name>] SET MULTI_USER WITH ROLLBACK IMMEDIATE
GO

这个解决方案在我的SQL Server 2016上不起作用。如果我查询master..sysprocesses,会看到几行出现,但是然后这些行被替换为一个错误消息,指定的数据库处于单用户模式等。 - youcantryreachingme
@youcantryreachingme,请在此处提供您在SQL Server 2016中收到的错误消息,这样我/其他人就能帮助您解决问题。 - Sathish
无法在此时更改数据库'my_db'的状态或选项。该数据库处于单用户模式,并且当前有用户连接到它。 - youcantryreachingme
执行此脚本时,请确保您的新查询不来自当前处于单用户模式的数据库。 - Circle Hsiao
这在我的SQL 2016中有效。使用@CRAFTYDBA的方法,我无法杀死新的SPID,它会在瞬间启动并再次锁定数据库。这种方法一举解决了这个问题。谢谢! - MJA

40
  1. 右键单击数据库,选择“属性”
  2. 选择“选项”页面
  3. 向下滚动到“其他选项”并更改“限制访问”字段

SQL Server选项页面的截图


4
这个解决方案对我在 SQL Server 2016 上不起作用。尝试访问属性会显示一个错误,指出数据库处于单用户模式并且已经有一个用户连接。 - youcantryreachingme
1
在SQL Server 2017上对我有效。SSMS询问我是否想关闭现有连接,我选择了是。可能是一个新功能。 - Gustaf Liljegren
同样对我有用,SQL Server -v: 2012 - Jdslk
1
你必须关闭任何可能连接到相关数据库的查询窗口。这可能不是显而易见的问题,但如果按照其他用户建议运行sp_who2,你就能知道是否仍有挂起的查询窗口。在打开新的查询窗口之前,请确保在对象资源管理器中选择“系统数据库\master”。 - Thick_propheT

33

要退出单用户模式,请尝试:

ALTER DATABASE [my_db] SET MULTI_USER

要切换回单用户模式,可以使用:

ALTER DATABASE [my_db] SET SINGLE_USER


1
我收到了以下错误信息: “无法在此时更改数据库'my_db'的状态或选项。该数据库处于单用户模式,并且当前有用户连接到它。 Msg 5069,Level 16,State 1,Line 1 ALTER DATABASE语句失败。” - Liondancer
1
你能停止并重新启动数据库(显然,如果这不是一个会影响其他用户的生产系统),然后重试命令吗?正如@CRAFTYDBA所述,该命令应从主数据库执行。 - rsbarro
1
我展开了“系统数据库”,右键单击“master”,选择“新查询”,并尝试在您和@CRAFTYDBA的命令中执行。同样的错误 =[ - Liondancer
1
你尝试过停止并重新启动数据库以终止现有连接吗?您还可以在此处查找更多终止与数据库的连接的方法:https://dev59.com/CnVD5IYBdhLWcg3wWKLc - rsbarro
1
是的,我做了。我刚刚再次执行了它,以确保我做了那件事哈哈。 - Liondancer
2
在左侧窗格中右键单击服务器,然后单击“断开连接”。确保您的数据库只有一个 SSMS 标签打开(右键单击并选择“断开其他连接”),然后执行语句。每个标签和对象资源管理器都是一个连接;您只能打开一个到数据库的连接(因此,“单用户模式”)。单用户应该是“单连接” :) 祝你好运。 - tommy_o

19

我尝试了,它有效。

ALTER DATABASE dbName SET MULTI_USER WITH ROLLBACK IMMEDIATE

11

我曾经遇到过同样的问题,使用以下查询语句可以找到需要终止的 session_id:

Select request_session_id From sys.dm_tran_locks Where resource_database_id=DB_ID('BI_DB_Rep');

这太完美了。找到了那个讨厌的SPID,把数据库恢复了在线状态。非常感谢! - Russell Speight

10

如果有人偶然进入了这个讨论串,这里有一个确保有效的解决方案可以解决 SQL Server 卡在 SINGLE USER MODE 的问题:

-- 获取需要终止的连接的进程 ID (spid)
-- 将 'DBName' 替换为实际数据库名称

SELECT sd.[name], sp.spid, sp.login_time, sp.loginame 
FROM sysprocesses sp 
INNER JOIN sysdatabases sd on sp.dbid = sd.dbid  
WHERE sd.[name] = 'DBName'
作为替代方案,您也可以使用命令“sp_who”来获取打开连接的“spid”:

-- 或者使用这个存储过程


exec sp_who

-- 然后执行以下步骤,并用正确的值替换[spid]和[DBName]


KILL SpidToKillGoesHere
GO

SET DEADLOCK_PRIORITY HIGH
GO

ALTER DATABASE [DBName] SET MULTI_USER WITH ROLLBACK IMMEDIATE
GO

9

按下CTRL + 1

查找锁定数据库的进程。在dbname列中查找你的数据库,并记录spid。现在你需要执行该语句:

kill <your spid>
ALTER DATABASE <your db> SET MULTI_USER;

CTRL + 1是一个非常方便的快捷键,我之前不知道! - Tyler Forsythe

8
以下方法对我有效:
USE [master]
SET DEADLOCK_PRIORITY HIGH
exec sp_dboption '[StuckDB]', 'single user', 'FALSE';
ALTER DATABASE [StuckDB] SET MULTI_USER WITH NO_WAIT
ALTER DATABASE [StuckDB] SET MULTI_USER WITH ROLLBACK IMMEDIATE

8

另一种选择是:

  • 将数据库下线;在SMSS中,右键点击数据库并选择"Take Offline",勾选 "Drop all connections"
  • 运行ALTER DATABASE [Your_Db] SET MULTI_USER

我的数据库不让我离线,它一直说它处于单用户模式并且有用户连接!(是的,我勾选了“断开所有连接”)。最后我只好将数据库分离! - TabbyCool
我不得不使用这个选项,因为没有用户连接,并且KILL命令无法在sa连接上工作。 - Derek K

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