When restoring a backup, how do I disconnect all active connections? - sql-server

My SQL Server 2005 doesn't restore a backup because of active connections. How can I force it?

You want to set your db to single user mode, do the restore, then set it back to multiuser:
ALTER DATABASE YourDB
SET SINGLE_USER WITH
ROLLBACK AFTER 60 --this will give your current connections 60 seconds to complete
--Do Actual Restore
RESTORE DATABASE YourDB
FROM DISK = 'D:\BackUp\YourBaackUpFile.bak'
WITH MOVE 'YourMDFLogicalName' TO 'D:\Data\YourMDFFile.mdf',
MOVE 'YourLDFLogicalName' TO 'D:\Data\YourLDFFile.ldf'
/*If there is no error in statement before database will be in multiuser
mode. If error occurs please execute following command it will convert
database in multi user.*/
ALTER DATABASE YourDB SET MULTI_USER
GO
Reference : Pinal Dave (http://blog.SQLAuthority.com)
Official reference: https://msdn.microsoft.com/en-us/library/ms345598.aspx

SQL Server Management Studio 2005
When you right click on a database and click Tasks and then click Detach Database, it brings up a dialog with the active connections.
By clicking on the hyperlink under "Messages" you can kill the active connections.
You can then kill those connections without detaching the database.
More information here.
SQL Server Management Studio 2008
The interface has changed for SQL Server Management studio 2008, here are the steps (via: Tim Leung)
Right-click the server in Object Explorer and select 'Activity Monitor'.
When this opens, expand the Processes group.
Now use the drop-down to filter the results by database name.
Kill off the server connections by selecting the right-click 'Kill Process' option.

This code worked for me, it kills all existing connections of a database.
All you have to do is change the line Set #dbname = 'databaseName' so it has your database name.
Use Master
Go
Declare #dbname sysname
Set #dbname = 'databaseName'
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
after this I was able to restore it

Try this:
DECLARE UserCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT
spid
FROM
master.dbo.sysprocesses
WHERE DB_NAME(dbid) = 'dbname'--replace the dbname with your database
DECLARE #spid SMALLINT
DECLARE #SQLCommand VARCHAR(300)
OPEN UserCursor
FETCH NEXT FROM UserCursor INTO
#spid
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQLCommand = 'KILL ' + CAST(#spid AS VARCHAR)
EXECUTE(#SQLCommand)
FETCH NEXT FROM UserCursor INTO
#spid
END
CLOSE UserCursor
DEALLOCATE UserCursor
GO

Restarting SQL server will disconnect users. Easiest way I've found - good also if you want to take the server offline.
But for some very wierd reason the 'Take Offline' option doesn't do this reliably and can hang or confuse the management console. Restarting then taking offline works
Sometimes this is an option - if for instance you've stopped a webserver that is the source of the connections.

I ran across this problem while automating a restore proccess in SQL Server 2008.
My (successfull) approach was a mix of two of the answers provided.
First, I run across all the connections of said database, and kill them.
DECLARE #SPID int = (SELECT TOP 1 SPID FROM sys.sysprocess WHERE dbid = db_id('dbName'))
While #spid Is Not Null
Begin
Execute ('Kill ' + #spid)
Select #spid = top 1 spid from master.dbo.sysprocesses
where dbid = db_id('dbName')
End
Then, I set the database to a single_user mode
ALTER DATABASE dbName SET SINGLE_USER
Then, I run the restore...
RESTORE DATABASE and whatnot
Kill the connections again
(same query as above)
And set the database back to multi_user.
ALTER DATABASE dbName SET MULTI_USER
This way, I ensure that there are no connections holding up the database before setting to single mode, since the former will freeze if there are.

None of these were working for me, couldn't delete or disconnect current users. Also couldn't see any active connections to the DB. Restarting SQL Server (Right click and select Restart) allowed me to do it.

To add to advice already given, if you have a web app running through IIS that uses the DB, you may also need to stop (not recycle) the app pool for the app while you restore, then re-start. Stopping the app pool kills off active http connections and doesn't allow any more, which could otherwise end up allowing processes to be triggered that connect to and thereby lock the database. This is a known issue for example with the Umbraco Content Management System when restoring its database

None of the above worked for me. My database didn't show any active connections using Activity Monitor or sp_who. I ultimately had to:
Right click the database node
Select "Detach..."
Check the "Drop Connections" box
Reattach
Not the most elegant solution but it works and it doesn't require restarting SQL Server (not an option for me, since the DB server hosted a bunch of other databases)

I prefer to do like this,
alter database set offline with rollback immediate
and then restore your database.
after that,
alter database set online with rollback immediate

Related

MSSQL RESTORE DATABASE Taking 10 times longer on AWS EC2 than On-Prem VM after Lift and Shift Migration

Scenario:
My company's IT departments are in the middle of a major migration from on-prem VM Ware server hosting to AWS based server hosting.
An on-prem server running Windows 2016 DataCenter and SQL Server 2016 was replicated and migrated from on-premise to an AWS EC2. The server is 1:1, Lift & Shift from the on-premise instance.
This server is a "test/simulation" box that is used by our account management team to preform "what-if" analysis prior to hitting production with account configuration changes, for this reason the databases on this box need to be regularly refreshed at the account managers discretion.
The Data teams step a simple backup and restore jobs within the SQL Agent that restores the given database from a network available share location that hosts the most recent .bak file. Runs a few scripts to make the system non-production and brings the database online.
USE TestSIM1
BEGIN TRY
IF EXISTS (SELECT EnvironmentLockedThru
FROM [dbo].[GlobalSettings] gs
WHERE EnvironmentLockedThru IS NOT NULL
AND EnvironmentLockedThru >= GETDATE())
BEGIN
PRINT 'Environment is locked'
RAISERROR ('Environment is locked', -- Message text.
16, -- Severity.
1 -- State.
);
END
ELSE
BEGIN
--PRINT 'Environment is unlocked or Lock has expired.'
USE Master
ALTER DATABASE [TestSIM1] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [TestSIM1] FROM DISK = N'\\Storage22\SQL\Sim\ProdSvr.DBName.Mirror.bak' WITH FILE = 1, MOVE N'DBName' TO N'D:\Data\TestSIM1.mdf', MOVE N'DBName_log' TO N'E:\Logs\TestSIM1_log.ldf', NOUNLOAD, REPLACE, STATS = 5
ALTER DATABASE [TestSIM1] SET MULTI_USER
END
END TRY
BEGIN CATCH
DECLARE #ErrorMessage NVARCHAR(4000);
DECLARE #ErrorSeverity INT;
DECLARE #ErrorState INT;
SELECT
#ErrorMessage = ERROR_MESSAGE(),
#ErrorSeverity = ERROR_SEVERITY(),
#ErrorState = ERROR_STATE();
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (#ErrorMessage, -- Message text.
#ErrorSeverity, -- Severity.
#ErrorState -- State.
);
END CATCH;
This takes anywhere from 45-60 minutes to restore the FULL backup to the Test server on a given day on premise.
After completing the migration of the server from on-prem to the AWS EC2 version of the server, it is now taking upwards of 10 hours to complete the restore.
I am hoping someone might have an explanation for this behavior and a possible resolution for this.
EC2 Specs:
8 Core
32 GB RAM
<Will update the exact EC2, class when my team provides it back to me.>
SQL Server:
Processes: Set to Automatic Affinity for all Processers
Memory: 24 GB allocated

SQL Server Database Stuck Single User

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

How to detect that a SQL Server database was created by attaching a data file or by restore from Enterprise Manager

Ours is a SQL Server (2008-R2) - Windows Forms based application. We have a backup/restore utility provided with our software which performs some logical checks before restoring a backup to ensure that the backup is functionally valid.
However, our clients often use the SQL Server Enterprise Manager utility to:
Restore backups or
Attach data files (kept aside before formatting) directly.
This type of action bypasses all our functional checks and allows the user to restore an invalid backup.
We want to detect that a database was restored/attached and may be we will stop the software from loading if such a thing happened. We think that this information (attach/restore) should be available within some table of SQL Server itself but don't know the right location/query.
If any change is required in our software to achieve the above, we are ready to do the same too, e.g. may be we need to store some data at some point of time to make the detection happen, please advise.
So, how can we detect that
A database backup was restored using SQL Server Management Utility
(Note: MSDB.Restorehistory may not be a good option as we have often found this table blank for unknown reasons even after backup was restored and just in case user restores the MSDB from MSDB backup or MSDB template due to a data corruption, may be due to abnormal shutdown of system, then the RestoreHistory table data is gone)
A database was created by attaching a data/log file using SQL Server Management Utility
Any help in this regard is highly appreciated.
Rajarshi
Method 1:
You can use SQL Server Audit (Security\Server Audit Specification), and add Backup-Restore_Group option to it in order to log all backup and restore in your server.
You can also read audited data with following query:
SELECT *
FROM sys.fn_get_audit_file('Your Audit File Path',DEFAULT, DEFAULT)
this feature is in SQL Server 20088 R2 and above version and not exists in SQL Server 2008.
Method 2:
You can use SQL server error log in order to get backup and restore history:
In order to get backup log of your database:
EXEC sys.sp_readerrorlog #p1 = 0, -- int
#p2 = 1, -- int
#p3 = N'Database backed up. Database: Attach', -- nvarchar(4000)
#p4 = N'' -- nvarchar(4000)
In order to get restore log of your database:
EXEC sys.sp_readerrorlog #p1 = 0, -- int
#p2 = 1, -- int
#p3 = N'Database was restored: Database: Attach, -- nvarchar(4000)
#p4 = N'' -- nvarchar(4000)
you can use this method on SQL Server Express 2008-R2 edition.

SQL Server tells me database is in use but it isn't

SQL Server keeps telling me a database is in use when I try to drop it or restore it, but when I run this metadata query:
select * from sys.sysprocesses
where dbid
in (select database_id from sys.databases where name = 'NameOfDb')
It returns nothing.
Sometimes it will return 1 process which is a CHECKPOINT_QUEUE waittype. If I try to kill that process, it won't let me (cannot kill a non-user process).
Anyone have any idea what's wrong?
i like this script. Do not struggle with killing..
use master
alter database xyz set single_user with rollback immediate
restore database xyz ...
alter database xyz set multi_user
I was having the same issue when trying to restore a database from a backup. The solution for me was to ensure that I checked "Overrite the existing database(WITH REPLACE)" and "Close existing connections to destination database" in the Options page BEFORE doing the restore. Here is a screenshot below.
There could be lots of things blocking your database. For example, if you have a query window opened on that database, it would be locked by you. Not counting external accesses, like a web application on IIS.
If you really wanna force the drop on it, check the close existing connections option or try to manually stop SQL Server's service.

How to delete database, error 5030 database can't be locked

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

Resources