This question already has answers here:
Exit single-user mode
(18 answers)
Closed 8 years ago.
One of my databases is in single user mode, and i can't seem to switch it to multi user.
USE master
GO
ALTER DATABASE MyDB
SET MULTI_USER WITH ROLLBACK IMMEDIATE
GO
When I run the above query, i get the following result
Changes to the state or options of database 'MyDB' cannot be made at this time. The database is in single-user mode, and a user is currently connected to it.
I've tried to query SQL Server from the master database to find all active connections to MyDB (exec sp_who), but when i do so i get the following error
Database 'MyDB' is already open and can only have one user at a time.
What am i supposed to do to exit single user mode?
Use this:
exec sp_dboption 'db_name_here', 'single user', 'FALSE'
Related
I have a SQL Server 2016 on a Windows Server 2016.
The database is stuck in single user mode.
I try to do this :
ALTER DATABASE MyDatabase
SET MULTI_USER;
But it says that the database is in use.
I tried this to find the spID :
exec sp_who
And I found the spid 57 is using the database,
Tried this to kill the spID
KILL 57
But it says : Process ID 57 is not an active process ID.
I am really stuck!
I can't even rename or delete the database.
I tried all of these but, didn't work :
SQL Server 2008 R2 Stuck in Single User Mode
Any idea please ?
It means that the DB is in use, it's set to single user mode, and you're not that single user. A common cause of that is that Object Explorer in SSMS is connected to the DB. Close everything that's connected to the server (even restart the SQL Server service if you need to), and try again. At worst, don't use SSMS. Just connect with SQLCMD, so you know that nothing else is connected.
I found the solution,
I restarted the sql server service, re-execute the query exec sp_who and found another spID and could kill it this time.
Thanks
From the Official docs you can try changing it a little bit by removing the read-only part
ALTER DATABASE [database_name]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
GO
ALTER DATABASE [database_name]
SET MULTI_USER;
GO
Docs : https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options?view=sql-server-ver15#b-setting-the-database-to-read_only
I have a SQL server database that has been running perfectly fine on my machine for about 6 months, a couple days ago out of nowhere it was inaccessible (Pending Recovery).
I did a bunch of Googling and have tried the following things to fix the issue but thus far restoring it from a previous backup is the only thing that seems to work.
I have tried (From SMS and SQLCMD):
ALTER DATABASE mydatabase SET EMERGENCY
ALTER DATABASE mydatabase set single_user
DBCC CHECKDB (mydatabase, REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;
ALTER DATABASE mydatabase set multi_user
Step #3 errors out with: "cannot open mydatabase is already open and can only have one user at a time"
Second try:
EXEC sp_resetstatus 'mydatabase';
ALTER DATABASE mydatabase SET EMERGENCY
DBCC CHECKDB ('mydatabase')
ALTER DATABASE mydatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CHECKDB ('mydatabase', REPAIR_ALLOW_DATA_LOSS)
ALTER DATABASE mydatabase SET MULTI_USER
Step #5 errors out with the same error.
My question is what could be causing this in the first place and how can I fix it properly without having to do a restore twice a day.
Database is already open and can only have one user at a time, this is error number 924. The complete error message looks like this:
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
Msg 924, Level 14, State 1, Line 1 Database ‘db_name’ is already open and can only have one user at a time.
The level 14 belongs to security level errors like a permission denied. It means that it cannot be open because someone is using it.
Use the sp_who or sp_who2 stored procedures. You can also use the kill command to kill the processes that are active in the database.
I also found this thread useful: How to fix Recovery Pending State in SQL Server Database?
what could be causing this in the first place and how can I fix it properly without having to do a restore
The most likely cause is a a hardware or driver problem with your hard disk.
In my case, I had databases set up on my local machine but on an external drive mapped to my hard drive. I have the external drive connected to my docking station all the time but I had to disconnect the hard drive and after I connected it again - the databases that are restored on the external drive went into Recover Pending mode.
In my case what helped me was to set the database offline in Microsoft SQL Server Management Studio by right clicking on the database - Tasks - Take Offline. The status of the database changes to Offline. After that bring the database online again by right clicking on the database - Tasks - Bring online.
The database was successfully recovered without any issues. But if the cause is different these steps may not help.
Take the database offline
Bring the database back online
I need to perform a database restore from my application. Before doing this, I want to kill all processes as follows:
private void KillAllProcessesOnSMARTDatabases(Server targetServer)
{
targetServer.KillAllProcesses(SMART_DB);
targetServer.KillAllProcesses(SMART_HISTORY_DB);
targetServer.KillAllProcesses(SMART_METADATA_DB);
SqlConnection.ClearAllPools();
}
However, when the first KillAllProcesses is run, I get the following exception:
Microsoft.SqlServer.Management.Smo.FailedOperationException: Drop all active database connections failed for Server 'MYServer'. ---> Microsoft.SqlServer.Management.Common.ExecutionFailureException: An exception occurred while executing a Transact-SQL statement or batch. ---> System.Data.SqlClient.SqlException: Only user processes can be killed.
The connection string used to create the server has sa credentials, however, the processes that need to be terminated are started under a different user. I tested the similar scenario and the test succeeded.
This started happening only recently. To me it appears there are some processes running that are not started by the user?
It would appear that your code is attempting to terminate all SQL Server Processes, which is not a good idea.
If you want to perform a database restore, you should set the database in question into either single_user mode or RESTRICTED_USER mode, the later being the most suitable.
Take a look at the following example of switching a database to RESTRICTED_USER mode and how to close any open user connections in the process.
How to: Set a Database to Single-User mode
You can use SMO to "kill" a particular database.
This will force a drop of all client connections to that database only and then drop the database itself.
Microsoft.SqlServer.Management.Smo.Server oServer = this.GetSmoServer();
oServer.KillDatabase(this.DatabaseName);
This question already has answers here:
What does sp_reset_connection do?
(2 answers)
Closed 4 years ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
Trying to understand what Sql Profiler means by emitting "sp_reset_connection".
I have the following, "exec sp_reset_connection" line followed by BatchStarting and Completed,
RPC:Completed exec sp_reset_connection
SQL:BatchStarting SELECT [c].[TestID] AS [TestID], [c].[Description] AS [Description] FROM [dbo].[Test] AS [c]
SQL:BatchCompleted SELECT [c].[TestID] AS [TestID], [c].[Description] AS [Description] FROM [dbo].[Test] AS [c]
Basically does first line "exec sp_reset_connection" mean the whole process (my connection was opened, the select stmt is run, then the connection is closed and released back to pool) just take place? Or my connection is still in open stage.
And, why does the sp_reset_connection executed before my own select statement, shouldn't it the reset come after user's sql?
I'm trying to know is there a way to know in more detail when a connection is opened and closed?
By seeing "exec sp_reset_connection", does that mean my connection is closed?
Like the other answers said, sp_reset_connection indicates that connection pool is being reused. Be aware of one particular consequence!
Jimmy Mays' MSDN Blog said:
sp_reset_connection does NOT reset the
transaction isolation level to the
server default from the previous
connection's setting.
UPDATE: Starting with SQL 2014, for client drivers with TDS version 7.3 or higher, the transaction isolation levels will be reset back to the default.
ref: SQL Server: Isolation level leaks across pooled connections
Here is some additional information:
What does sp_reset_connection do?
Data access API's layers like ODBC,
OLE-DB and System.Data.SqlClient all
call the (internal) stored procedure
sp_reset_connection when re-using a
connection from a connection pool. It
does this to reset the state of the
connection before it gets re-used,
however nowhere is documented what
things get reset. This article tries
to document the parts of the
connection that get reset.
sp_reset_connection resets the
following aspects of a connection:
All error states and numbers
(like ##error)
Stops all EC's (execution contexts)
that are child threads of a parent EC
executing a parallel query
Waits for any outstanding I/O
operations that is outstanding
Frees any held buffers on the
server by the connection
Unlocks any buffer resources
that are used by the connection
Releases all allocated memory
owned by the connection
Clears any work or temporary
tables that are created by the
connection
Kills all global cursors owned by the
connection
Closes any open SQL-XML handles that are open
Deletes any open SQL-XML related work tables
Closes all system tables
Closes all user tables
Drops all temporary objects
Aborts open transactions
Defects from a distributed transaction when enlisted
Decrements the reference count
for users in current database which
releases shared database locks
Frees acquired locks
Releases any acquired handles
Resets all SET options to the default values
Resets the ##rowcount value
Resets the ##identity value
Resets any session level trace
options using dbcc traceon()
Resets CONTEXT_INFO to NULL in SQL Server 2005 and newer [ not part of the original article ]
sp_reset_connection will NOT reset:
Security context, which is why
connection pooling matches connections
based on the exact connection string
Application roles entered using sp_setapprole, since application roles could not be reverted at all prior to SQL Server 2005. Starting in SQL Server 2005, app roles can be reverted, but only with additional information that is not part of the session. Before closing the connection, application roles need to be manually reverted via sp_unsetapprole using a "cookie" value that is captured when sp_setapprole is executed.
Note: I am including the list here as I do not want it to be lost in the ever transient web.
It's an indication that connection pooling is being used (which is a good thing).
Note however:
If you issue SET TRANSACTION ISOLATION LEVEL in a stored procedure or trigger, when the object returns control the isolation level is reset to the level in effect when the object was invoked. For example, if you set REPEATABLE READ in a batch, and the batch then calls a stored procedure that sets the isolation level to SERIALIZABLE, the isolation level setting reverts to REPEATABLE READ when the stored procedure returns control to the batch.
http://msdn.microsoft.com/en-us/library/ms173763.aspx
I am trying to delete an existing database in SQL Server 2005. My first attempt produced the following error:
5030: The database could not be exclusively
locked to perform the operation.
I have since killed all processes that are accessing the database. I have also removed the replication subscription that it had previously been involved in.
Any thoughts on what else that could be holding the lock on it besides SQL Server processes and replication?
Update: I restarted the server, and that fixed it. I was trying to avoid that, since this is a production server, but hey what can you do?
A production server in which so many connections use the database yet you want to drop it? :)
None the less, how to kick out everybody from the database:
USE [dbname];
ALTER DATABASE [dbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
Then drop the database:
USE [master];
DROP DATABASE [dbname];
There is still a very small window of opportunity between the USE [master]; and DROP DATABASE ... where some other connection can grab the 1 single allowed lock on the database, but it usually not worth working around that.
I hate to say it, but a quick solution is to restart the system, make sure the sql server server service is not started, then you should be able to delete.
Also, is IIS stopped if you db is connected to a web ap?
You don't happen to know if anyone left a transaction in an uncompleted rollback state (or otherwise uncompleted)? Might as well check the locks list, too.
In the management studio, goto Management->Activity Monitor (right click) -> View Processes. That will give you a full list of everything running, you can sort the list by Database to see what is still attached, and you can also kill any connections. It's easy to end up with orphaned connections that will prevent you from getting the exclusive access that you need.
No One else should be using the DB, including yourself.
Why would we make a deleted DB to multi user mode.
ALTER DATABASE dbName SET MULTI_USER WITH ROLLBACK IMMEDIATE
To avoid this error, use the T-SQL script below in the master database. Make sure to run this (and modify the #dbname) for each database you are running the ALTER DATABASE command in.
"The database could not be exclusively locked to perform the
operation"
This "connection killer" script will work if Windows has established JDBC connections to the database. But this script is unable to kill off JDBC connections for Linux services (e.g. JBoss). So you'll still get that error if you don't stop JBoss manually. I haven't tried other protocols, but please comment if you find out more information as you build new systems.
USE master;
DECLARE #dbname sysname
Set #dbname = 'DATABASE_NAME_HERE-PROD'
Declare #spid int
Select #spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(#dbname)
While #spid Is Not Null
Begin
Execute ('Kill ' + #spid)
Select #spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(#dbname) and spid > #spid
End
This error normally occurs when your database is in Multi User mode where users are accessing your database or some objects are referring to your database.
First you should set the database to single user mode:
ALTER DATABASE dbName
SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Now we will try to delete the database
delete DATABASE ...
Finally set the database to Multiuser mode
ALTER DATABASE dbName
SET MULTI_USER WITH ROLLBACK IMMEDIATE