Wie trenne ich beim Wiederherstellen eines Backups alle aktiven Verbindungen?

166

Mein SQL Server 2005 stellt aufgrund aktiver Verbindungen keine Sicherung wieder her. Wie kann ich es erzwingen?

Jader Dias
quelle
Möchten Sie immer alle Verbindungen zur Datenbank beenden, über die Sie "wiederherstellen" möchten? Oder wird es Zeiten geben, in denen Sie vorhandene Verbindungen nicht beenden möchten? Müssen Sie sich auch um das Zusammenlegen von Verbindungen kümmern?
Philip Kelley

Antworten:

177

SQL Server Management Studio 2005

Wenn Sie mit der rechten Maustaste auf eine Datenbank klicken Tasksund dann klicken und dann klicken Detach Database, wird ein Dialogfeld mit den aktiven Verbindungen angezeigt.

Bildschirm abnehmen

Durch Klicken auf den Hyperlink unter "Nachrichten" können Sie die aktiven Verbindungen beenden.

Sie können diese Verbindungen dann beenden, ohne die Datenbank zu trennen.

Weitere Informationen hier .

SQL Server Management Studio 2008

Die Benutzeroberfläche wurde für SQL Server Management Studio 2008 geändert. Hier sind die Schritte (über: Tim Leung ).

  1. Klicken Sie im Objekt-Explorer mit der rechten Maustaste auf den Server und wählen Sie "Aktivitätsmonitor".
  2. Wenn dies geöffnet wird, erweitern Sie die Gruppe Prozesse.
  3. Verwenden Sie nun das Dropdown-Menü, um die Ergebnisse nach dem Datenbanknamen zu filtern.
  4. Beenden Sie die Serververbindungen, indem Sie mit der rechten Maustaste auf die Option "Prozess beenden" klicken.
George Stocker
quelle
21
Wenn Sie dasselbe Problem wie @Ryan haben, liegt dies wahrscheinlich daran, dass Sie Management Studio 2008 (oder höher) anstelle von Management Studio 2005 verwenden. Um dasselbe in Management Studio 2008 zu tun, klicken Sie mit der rechten Maustaste auf Ihren Server in Object Explorer und wählen Sie 'Aktivitätsmonitor'. Wenn dies geöffnet wird, erweitern Sie die Gruppe Prozesse. Verwenden Sie nun das Dropdown-Menü, um die Ergebnisse nach dem Datenbanknamen zu filtern. Sie können Ihre Verbindungen jetzt beenden, indem Sie mit der rechten Maustaste auf die Option "Prozess beenden" klicken.
Tim Leung
195

Sie möchten Ihre Datenbank in den Einzelbenutzermodus versetzen, die Wiederherstellung durchführen und dann wieder auf Mehrbenutzer einstellen:

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

Referenz: Pinal Dave ( http://blog.SQLAuthority.com )

Offizielle Referenz: https://msdn.microsoft.com/en-us/library/ms345598.aspx

brendan
quelle
11
Anstatt ein SOFORTIGES ROLLBACK auszugeben, kann es relevant sein, nur ROLLBACK nach einer bestimmten VERZÖGERUNG auszuführen, wodurch Benutzeranfragen die Möglichkeit erhalten, diese auf natürliche Weise abzuschließen.
John Sansom
2
Guter Punkt, aktualisiert auf Rollback, um den Befehl AFTER 60
einzuschließen
Hallo @brendan, was ist, wenn der Rollback länger als 60 Sekunden dauert? danke
user3583912
11
Wenn Sie eine Datenbank wiederherstellen, gehen die offenen Transaktionen verloren, unabhängig davon, ob Sie ROLLBACK IMMEDIATEoder ROLLBACK AFTER 60. Die einzige Möglichkeit, diese Daten zu speichern, besteht darin, nach dem Rollback eine weitere Sicherung durchzuführen. Sie stellen jedoch aus einem anderen Backup wieder her. Also, wozu warten? Vermisse ich etwas
Dave Mason
@DMason, ich bin auch neugierig auf diese Frage. Verhindert die Verwendung des single_user mit Rollback-Modus neue Verbindungen während der Wartezeit? Wenn ja, frage ich mich, ob es eine sauberere / schönere Möglichkeit ist, schreibgeschützte Aktionen zumindest abzuschließen, anstatt sie abrupt zu beenden?
Jason
43

Dieser Code hat bei mir funktioniert, er beendet alle vorhandenen Verbindungen einer Datenbank. Sie müssen lediglich die Zeile Set @dbname = 'databaseName' so ändern, dass sie Ihren Datenbanknamen enthält.

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

danach konnte ich es wiederherstellen

RagnaRock
quelle
1
Dies war der schnellste Ansatz (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson
Bei mir hat es nicht funktioniert. Die Datenbank wird noch verwendet. Ich benutze SQL Server 2008.
Marek Bar
Ich habe festgestellt, dass das mehrmalige Ausführen dieses Codes direkt hintereinander den Trick EVENTUELL macht. Manchmal schleicht sich etwas zwischen KILL und Restore. Und manchmal muss man den Kill ausführen, DANN die Wiederherstellung direkt nacheinander.
John Waclawski
Hängt vollständig von der Aggressivität der Anwendung ab, die versucht, die Verbindung wiederherzustellen. Ein paar faule Benutzer? Funktioniert super. Hochvolumiger App-Server, der in weniger als einer Sekunde wieder eine Verbindung herstellt? Nicht so viel.
BradC
5

Versuche dies:

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
quelle
4

Durch einen Neustart von SQL Server werden Benutzer getrennt. Der einfachste Weg, den ich gefunden habe - gut auch, wenn Sie den Server offline schalten möchten.

Aber aus irgendeinem sehr seltsamen Grund macht die Option "Offline nehmen" dies nicht zuverlässig und kann die Verwaltungskonsole hängen oder verwirren. Neustart und Offline-Arbeiten

Manchmal ist dies eine Option - wenn Sie beispielsweise einen Webserver gestoppt haben, der die Quelle der Verbindungen ist.

Simon_Weaver
quelle
+1. Die akzeptierte Antwort funktioniert nicht für SQL Express (z. B. in einer Entwicklungsumgebung), da SQL Express keinen Aktivitätsmonitor hat
Matt Frear
1
@ MattFrear: Das ist nicht wahr! Zumindest in 2008 R2 Express sehe ich eine Symbolleistenschaltfläche und einen Kontextmenüeintrag auf dem Serverknoten.
Stephan
4
Durch einen Neustart eines gesamten SQL Servers werden Verbindungen zu allen Datenbanken unterbrochen. Ein Server unterstützt möglicherweise viele Datenbanken, aber nur eine muss jetzt wiederhergestellt werden.
Ross Presser
3
Dies ist absolut der schlechteste Weg, um Verbindungen zu einer Datenbank zu beenden. Vor allem, wenn viele andere Datenbanken noch von anderen Benutzern verwendet werden. Ich rate GEGEN diese Methode. Es ist 100%, totaler Overkill !!
John Waclawski
@ JohnWaclawski Ich weiß nichts über das Schlimmste, aber sicherlich das Faulste - deshalb habe ich manchmal gesagt. Es spart sowieso keine Zeit gegenüber anderen Methoden
Simon_Weaver
3

Ich bin auf dieses Problem gestoßen, als ich einen Wiederherstellungsprozess in SQL Server 2008 automatisiert habe. Mein (erfolgreicher) Ansatz war eine Mischung aus zwei der bereitgestellten Antworten.

Zuerst laufe ich über alle Verbindungen dieser Datenbank und töte sie.

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

Dann habe ich die Datenbank auf einen single_user-Modus gesetzt

ALTER DATABASE dbName SET SINGLE_USER

Dann führe ich die Wiederherstellung aus ...

RESTORE DATABASE and whatnot

Beenden Sie die Verbindungen erneut

(same query as above)

Und setzen Sie die Datenbank wieder auf multi_user.

ALTER DATABASE dbName SET MULTI_USER

Auf diese Weise stelle ich sicher, dass keine Verbindungen vorhanden sind, die die Datenbank halten, bevor der Einzelmodus aktiviert wird, da der erstere einfriert, wenn dies der Fall ist.

Eric Wu
quelle
2

Keines davon funktionierte für mich, konnte aktuelle Benutzer nicht löschen oder trennen. Es konnten auch keine aktiven Verbindungen zur Datenbank angezeigt werden. Durch einen Neustart von SQL Server (Rechtsklick und Auswahl von Neustart) konnte ich dies tun.

Der Codierer
quelle
2

Wenn Sie eine Web-App über IIS ausführen, die die Datenbank verwendet, müssen Sie möglicherweise auch den App-Pool für die App stoppen (nicht recyceln), während Sie sie wiederherstellen, und dann neu starten. Durch das Stoppen des App-Pools werden aktive http-Verbindungen beendet und keine weiteren Verbindungen mehr zugelassen. Andernfalls können Prozesse ausgelöst werden, die eine Verbindung zur Datenbank herstellen und diese dadurch sperren. Dies ist ein bekanntes Problem, beispielsweise beim Umbraco Content Management System beim Wiederherstellen seiner Datenbank

Chris Halcrow
quelle
1

Keines der oben genannten hat bei mir funktioniert. In meiner Datenbank wurden keine aktiven Verbindungen mit Activity Monitor oder sp_who angezeigt. Ich musste letztendlich:

  • Klicken Sie mit der rechten Maustaste auf den Datenbankknoten
  • Wählen Sie "Trennen ..."
  • Aktivieren Sie das Kontrollkästchen "Verbindungen trennen"
  • Wieder anbringen

Nicht die eleganteste Lösung, aber sie funktioniert und erfordert keinen Neustart von SQL Server (für mich keine Option, da der DB-Server eine Reihe anderer Datenbanken gehostet hat).

Brent Waggoner
quelle
Das ist totaler Overkill. Verwenden Sie den obigen KILL-Code. Arbeitet an Hunderten von Wiederherstellungsjobs für mich.
John Waclawski
Die Datenbank, mit der ich gearbeitet habe, würde nicht alles töten - es könnte jedoch ein Problem mit ihrer Einrichtung gewesen sein. Ich bin damit einverstanden, dass das im Allgemeinen viel einfacher ist.
Brent Waggoner
0

Ich mache das lieber so,

Ändern Sie den Datenbanksatz offline mit sofortigem Rollback

und stellen Sie dann Ihre Datenbank wieder her. nachdem,

Datenbank online ändern mit sofortigem Rollback

Aniyan Kolathur
quelle