Lors de la restauration d'une sauvegarde, comment déconnecter toutes les connexions actives?

166

Mon SQL Server 2005 ne restaure pas une sauvegarde en raison de connexions actives. Comment puis-je le forcer?

Jader Dias
la source
Voulez-vous toujours supprimer toutes les connexions à la base de données que vous souhaitez «restaurer»? Ou y aura-t-il des moments où vous ne voudrez pas supprimer les connexions existantes? De plus, devez-vous vous soucier du pool de connexions?
Philip Kelley

Réponses:

177

SQL Server Management Studio 2005

Lorsque vous cliquez avec le bouton droit de la souris sur une base de données et que vous cliquez Taskspuis cliquez sur Detach Database, une boîte de dialogue avec les connexions actives apparaît.

Détacher l'écran

En cliquant sur le lien hypertexte sous "Messages", vous pouvez supprimer les connexions actives.

Vous pouvez ensuite supprimer ces connexions sans détacher la base de données.

Plus d'informations ici .

SQL Server Management Studio 2008

L'interface a changé pour SQL Server Management studio 2008, voici les étapes (via: Tim Leung )

  1. Cliquez avec le bouton droit sur le serveur dans l'Explorateur d'objets et sélectionnez «Moniteur d'activité».
  2. Lorsque cela s'ouvre, développez le groupe Processus.
  3. Utilisez maintenant la liste déroulante pour filtrer les résultats par nom de base de données.
  4. Coupez les connexions au serveur en sélectionnant l'option du clic droit «Kill Process».
George Stocker
la source
21
Si vous rencontrez le même problème que @Ryan, c'est probablement parce que vous utilisez Management Studio 2008 (ou version ultérieure), plutôt que Management Studio 2005. Pour faire la même chose dans Management Studio 2008, cliquez avec le bouton droit sur votre serveur dans Object Explorer et sélectionnez «Moniteur d'activité». Lorsque cela s'ouvre, développez le groupe Processus. Utilisez maintenant la liste déroulante pour filtrer les résultats par nom de base de données. Vous pouvez maintenant interrompre vos connexions en sélectionnant l'option du clic droit 'Kill Process'.
Tim Leung
195

Vous souhaitez définir votre base de données en mode mono-utilisateur, effectuer la restauration, puis la remettre en mode multi-utilisateur:

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

Référence: Pinal Dave ( http://blog.SQLAuthority.com )

Référence officielle: https://msdn.microsoft.com/en-us/library/ms345598.aspx

Brendan
la source
11
Plutôt que d'émettre un ROLLBACK IMMÉDIAT, il peut être pertinent de n'effectuer que ROLLBACK après un DELAY spécifique, donnant ainsi aux requêtes des utilisateurs la possibilité de se terminer naturellement.
John Sansom
2
Bon point, mis à jour pour revenir en arrière pour inclure la commande
AFTER
Salut @brendan, et si la restauration prend plus de 60 secondes? merci
user3583912
11
Si vous restaurez une base de données, les transactions ouvertes seront perdues que vous ROLLBACK IMMEDIATEou ROLLBACK AFTER 60. La seule façon d'enregistrer ces données est d'effectuer une autre sauvegarde après la restauration. Mais vous restaurez à partir d'une sauvegarde différente. Alors, quel est l'intérêt d'attendre? Est-ce que je manque quelque chose?
Dave Mason
@DMason, je suis également curieux de connaître cette question. L'utilisation de single_user avec le mode de restauration empêche-t-elle de nouvelles connexions pendant le temps d'attente? Si tel est le cas, je me demande si c'est un moyen plus propre / plus agréable de laisser au moins les actions en lecture seule se terminer plutôt que de les terminer brusquement?
Jason
43

Ce code a fonctionné pour moi, il tue toutes les connexions existantes d'une base de données. Tout ce que vous avez à faire est de changer la ligne Set @dbname = 'databaseName' pour qu'elle ait le nom de votre base de données.

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

après cela, j'ai pu le restaurer

RagnaRock
la source
1
C'était l'approche la plus rapide (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson
Cela n'a pas fonctionné pour moi. La base de données est toujours utilisée. J'utilise SQL Server 2008.
Marek Bar
J'ai trouvé que l'exécution de ce code plusieurs fois, l'une après l'autre, fera EVENTUELLEMENT l'affaire. Parfois, quelque chose se faufile entre votre KILL et votre restauration. Et parfois, vous devez exécuter le kill PUIS la restauration l'un après l'autre.
John Waclawski
Dépend entièrement de l'agressivité de l'application essayant de se reconnecter. Quelques utilisateurs paresseux? Fonctionne très bien. Serveur d'applications à volume élevé qui se reconnecte en moins d'une seconde? Pas tellement.
BradC
5

Essaye ça:

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
user2276214
la source
4

Le redémarrage du serveur SQL déconnectera les utilisateurs. Le moyen le plus simple que j'ai trouvé - bon aussi si vous voulez mettre le serveur hors ligne.

Mais pour une raison très étrange, l'option 'Take Offline' ne le fait pas de manière fiable et peut bloquer ou perturber la console de gestion. Redémarrage puis mise hors ligne des travaux

Parfois, c'est une option - si, par exemple, vous avez arrêté un serveur Web qui est la source des connexions.

Simon_Weaver
la source
+1. La réponse acceptée ne fonctionnera pas pour SQL Express (par exemple dans un environnement de développement) car SQL Express n'a pas de moniteur d'activité
Matt Frear
1
@MattFrear: Ce n'est pas vrai! Au moins en 2008 R2 Express, je vois un bouton de barre d'outils et une entrée de menu contextuel sur le nœud du serveur.
Stephan
4
Le redémarrage d'un serveur SQL entier supprimera les connexions à toutes les bases de données. Un serveur peut prendre en charge de nombreuses bases de données, mais une seule doit être restaurée maintenant.
Ross Presser
3
C'est absolument la pire façon de supprimer les connexions à une base de données. Surtout si vous avez de nombreuses autres bases de données encore utilisées par d'autres utilisateurs. Je déconseille vivement d'utiliser cette méthode. C'est 100%, exagération totale !!
John Waclawski
@JohnWaclawski Je ne sais pas pour le pire mais certainement le plus paresseux - c'est pourquoi je l'ai dit parfois. De toute façon, cela ne permet pas vraiment de gagner du temps par rapport aux autres méthodes
Simon_Weaver
3

J'ai rencontré ce problème en automatisant un processus de restauration dans SQL Server 2008. Mon approche (réussie) était un mélange de deux des réponses fournies.

Tout d'abord, je traverse toutes les connexions de ladite base de données et les tue.

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

Ensuite, j'ai défini la base de données sur un mode single_user

ALTER DATABASE dbName SET SINGLE_USER

Ensuite, je lance la restauration ...

RESTORE DATABASE and whatnot

Tuez à nouveau les connexions

(same query as above)

Et redéfinissez la base de données sur multi_user.

ALTER DATABASE dbName SET MULTI_USER

De cette façon, je m'assure qu'aucune connexion ne bloque la base de données avant de passer en mode unique, car le premier se fige s'il y en a.

Eric Wu
la source
2

Aucun de ceux-ci ne fonctionnait pour moi, ne pouvait pas supprimer ou déconnecter les utilisateurs actuels. Impossible de voir également les connexions actives à la base de données. Le redémarrage de SQL Server (clic droit et sélectionnez Redémarrer) m'a permis de le faire.

Le codeur
la source
2

Pour ajouter aux conseils déjà donnés, si vous disposez d'une application Web exécutée via IIS qui utilise la base de données, vous devrez peut-être également arrêter (et non recycler) le pool d'applications de l'application pendant la restauration, puis redémarrer. L'arrêt du pool d'applications tue les connexions http actives et n'en permet plus, ce qui pourrait autrement permettre de déclencher des processus qui se connectent et verrouillent ainsi la base de données. Il s'agit d'un problème connu, par exemple avec le système de gestion de contenu Umbraco lors de la restauration de sa base de données

Chris Halcrow
la source
1

Aucune de ces réponses n'a fonctionné pour moi. Ma base de données n'a montré aucune connexion active utilisant Activity Monitor ou sp_who. J'ai finalement dû:

  • Cliquez avec le bouton droit sur le nœud de la base de données
  • Sélectionnez "Détacher ..."
  • Cochez la case "Supprimer les connexions"
  • Rattacher

Ce n'est pas la solution la plus élégante mais cela fonctionne et cela ne nécessite pas de redémarrer SQL Server (ce n'est pas une option pour moi, car le serveur DB hébergeait un tas d'autres bases de données)

Brent Wagoner
la source
C'est une exagération totale. Utilisez le code KILL ci-dessus. Fonctionne sur des centaines de travaux de restauration pour moi.
John Waclawski
La base de données avec laquelle je travaillais ne tue pas tout - cependant, cela peut avoir été un problème avec leur configuration. Je suis d'accord que c'est beaucoup plus facile en général.
Brent Wagoner
0

Je préfère faire comme ça,

modifier la base de données définie hors ligne avec restauration immédiate

puis restaurez votre base de données. après ça,

modifier l'ensemble de la base de données en ligne avec restauration immédiate

Aniyan Kolathur
la source