J'essaie d'exécuter ce script SQL sur une instance SQL Server pour restaurer une base de données de test sur une copie plus récente de la base de données active.
RESTORE FILELISTONLY
FROM disk = '\\staging_server\path\to\db_backup.bak'
-- Restore the files for
RESTORE DATABASE Test_DB
FROM disk = '\\staging_server\path\to\db_backup.bak'
WITH replace,
MOVE 'Test_DB' TO 'D:\R2_BIN\Test_DB.mdf',
MOVE 'Test_DB_log' TO 'D:\R2_BIN\Test_DB_log.ldf',
stats = 5
GO
Cependant, lors de l'exécution du script, je reçois l'erreur suivante.
Msg 3101, niveau 16, état 1, ligne 5
L'accès exclusif n'a pas pu être obtenu car la base de données est en cours d'utilisation.
Msg 3013, niveau 16, état 1, ligne 5
RESTORE DATABASE se termine anormalement.
Existe-t-il un moyen de forcer l'exécution de cette opération et de supprimer toutes les connexions dont elle a besoin pour le faire? J'ai essayé de fermer toutes les applications susceptibles de se connecter à la base de données, mais je ne peux tout simplement pas identifier certaines des connexions. Il y en a plusieurs de mon nom d'utilisateur et pourtant je n'ai qu'une seule instance de SQL Server Management Studio ouverte.
Quoi qu'il en soit, existe-t-il un moyen de supprimer toutes les connexions à une base de données spécifique? Il y a pas mal de bases de données en cours d'exécution sur cette instance, donc je ne veux pas simplement arrêter et redémarrer l'instance ensemble si je peux l'aider.
Vous devez passer en mode mono-utilisateur:
-- Close all connections and rollback all transaction
ALTER DATABASE Test_DB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
RESTORE FILELISTONLY
FROM disk = '\\staging_server\path\to\db_backup.bak'
-- Restore the files for
RESTORE DATABASE Test_DB
FROM disk = '\\staging_server\path\to\db_backup.bak'
WITH replace,
MOVE 'Test_DB' TO 'D:\R2_BIN\Test_DB.mdf',
MOVE 'Test_DB_log' TO 'D:\R2_BIN\Test_DB_log.ldf',
stats = 5
GO
ALTER DATABASE Test_DB SET MULTI_USER;
GO
Msg 3101, niveau 16, état 1, ligne 5 L'accès exclusif n'a pas pu être obtenu car la base de données est en cours d'utilisation.
Le message d'erreur dit tout. L'opération de restauration nécessite un accès exclusif à la base de données lorsque vous essayez de la restaurer à partir de la sauvegarde. Puisqu'il n'est pas en mesure d'obtenir, vous obtenez un message d'erreur.
Puisque vous restaurez sur une base de données déjà présente, vous n'avez pas besoin d'utiliser WITH MOVE
commande. Ci-dessous devrait fonctionner
use master
go
alter database Test_DB set single_user with rollback immediate
go
RESTORE DATABASE Test_DB
FROM disk = '\\staging_server\path\to\db_backup.bak'
WITH replace
go
Tuer les sessions est quelque chose qui ne devrait pas être fait en premier lieu:
L'approche que j'utilise lors d'une restauration pendant une telle activité de rafraîchissement serait:
Approche 1:
Mettez la base de données en mode mono-utilisateur, effectuez la restauration et réinitialisez-la sur multi_user
use master
go
alter database <database_name_here>
set single_user with rollback immediate
Faites la restauration et revenez à multi_user
alter database <database_name>
set multi_user
go
Approche 2:
Si ci-dessus ne fonctionne pas: mettez la base de données hors ligne et reconnectez-la ci-dessous:
- Mettre la base de données hors ligne
ALTER DATABASE [database name] SET OFFLINE WITH
ROLLBACK IMMEDIATE
GO
-- Take the Database Online
ALTER DATABASE [myDB] SET ONLINE
GO
Approche 3: Pas la meilleure façon mais faites selon vos besoins
Affichez les sessions ouvertes de la base de données à l'aide de SP_who2 ou SP_whoisactive et supprimez les sessions que vous analysez devraient être sans aucun impact.
ou utilisez le script ci-dessous pour tuer toutes les sessions ouvertes pour cette base de données:
declare @sql as varchar(20), @spid as int
select @spid = min(spid) from master..sysprocesses where dbid = db_id('<database_name>')
and spid != @@spid
while (@spid is not null)
begin
print 'Killing process ' + cast(@spid as varchar) + ' ...'
set @sql = 'kill ' + cast(@spid as varchar)
exec (@sql)
select
@spid = min(spid)
from
master..sysprocesses
where
dbid = db_id('<database_name>')
and spid != @@spid
end
print 'Process completed...'