it-swarm.com.de

SQL Server-Wiederherstellungsdatenbank mit aktiven Verbindungen

Ich versuche, dieses SQL-Skript auf einer SQL Server-Instanz auszuführen, um eine Testdatenbank auf einer neueren Kopie der Live-Datenbank wiederherzustellen.

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

Beim Ausführen des Skripts wird jedoch die folgende Fehlermeldung angezeigt.

Nachricht 3101, Ebene 16, Status 1, Zeile 5
Es konnte kein exklusiver Zugriff erhalten werden, da die Datenbank verwendet wird.
Nachricht 3013, Ebene 16, Status 1, Zeile 5
RESTORE DATABASE wird abnormal beendet.

Gibt es eine Möglichkeit, diese Operation zu erzwingen und alle Verbindungen zu beenden, die erforderlich sind, um sie auszuführen? Ich habe versucht, alle Anwendungen zu schließen, die möglicherweise Verbindungen zur Datenbank herstellen, aber einige der Verbindungen kann ich einfach nicht identifizieren. Es gibt mehrere von meinem Benutzernamen und dennoch habe ich nur eine Instanz von SQL Server Management Studio geöffnet.

Gibt es eine Möglichkeit, alle Verbindungen zu einer bestimmten Datenbank zu beenden? Auf dieser Instanz werden einige Datenbanken ausgeführt, daher möchte ich die Instanz nicht einfach alle herunterfahren und neu starten, wenn ich helfen kann.

8
Luke

Sie müssen in den Einzelbenutzermodus wechseln:

-- 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
11

Meldung 3101, Ebene 16, Status 1, Zeile 5 Es konnte kein exklusiver Zugriff erhalten werden, da die Datenbank verwendet wird.

Die Fehlermeldung sagt alles. Der Wiederherstellungsvorgang erfordert exklusiven Zugriff auf die Datenbank, wenn Sie versuchen, sie aus der Sicherung wiederherzustellen. Da es nicht möglich ist, erhalten Sie eine Fehlermeldung.

Da Sie eine bereits vorhandene Datenbank wiederherstellen, müssen Sie den Befehl WITH MOVE Nicht verwenden. Unten sollte funktionieren

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
1
Shanky

Das Beenden der Sitzungen sollte nicht an erster Stelle erfolgen:

Der Ansatz, den ich während einer Wiederherstellung während einer solchen Aktualisierungsaktivität verwende, wäre:

Ansatz 1:

Bringen Sie die Datenbank in den Einzelbenutzermodus, führen Sie die Wiederherstellung durch und setzen Sie sie auf multi_user zurück

use master
go
alter database <database_name_here>
set single_user with rollback immediate

Führen Sie die Wiederherstellung durch und setzen Sie sie wieder auf multi_user

alter database <database_name>
set multi_user
go

Ansatz 2:

Wenn oben nicht funktioniert: Schalten Sie die Datenbank offline und wieder online mit:

- Nehmen Sie die Datenbank offline

ALTER DATABASE [database name] SET OFFLINE WITH
ROLLBACK IMMEDIATE
GO
-- Take the Database Online
ALTER DATABASE [myDB] SET ONLINE
GO

Ansatz 3: Nicht der beste Weg, aber tun Sie, was Sie brauchen

Zeigen Sie die geöffneten Sitzungen der Datenbank mit SP_who2 oder SP_whoisactive an und beenden Sie die Sitzungen, die Sie analysieren, ohne Auswirkungen.

oder verwenden Sie das folgende Skript, um alle offenen Sitzungen für diese Datenbank zu beenden:

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...'
1
KASQLDBA