Fehler - Es konnte kein exklusiver Zugriff erhalten werden, da die Datenbank verwendet wird

117

Ich versuche tatsächlich, ein Skript (in SQL Server 2008) zu erstellen, um eine Datenbank aus einer Sicherungsdatei wiederherzustellen. Ich habe den folgenden Code erstellt und erhalte eine Fehlermeldung:

Msg 3101, Level 16, State 1, Line 3
Exclusive access could not be obtained because 
the database is in use.
Msg 3013, Level 16, State 1, Line 3
RESTORE DATABASE is terminating abnormally.

Wie behebe ich dieses Problem?

IF DB_ID('AdventureWorksDW') IS NOT NULL 
BEGIN 
RESTORE DATABASE [AdventureWorksDW] 
FILE = N'AdventureWorksDW_Data' 
FROM  
DISK = N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\Backup\AdventureWorksDW.bak' 
WITH  FILE = 1, 
MOVE N'AdventureWorksDW_Data' 
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW.mdf', 
MOVE N'AdventureWorksDW_Log'  
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW_0.LDF', 
NOUNLOAD,  STATS = 10 
END
Dampf
quelle
Wenn dies funktioniert, kann ich möglicherweise ein zuverlässiges Skript erstellen, um mehrere Datenbanken aus einem Ordner wiederherzustellen. Ich konnte keinen zuverlässigen Code im Netz finden. Mein Code ist möglicherweise zuverlässig, da er von SS selbst generiert wird.
Steam

Antworten:

104

Ich gehe davon aus, dass Sie sich beim Wiederherstellen einer Datenbank nicht um vorhandene Transaktionen auf dieser Datenbank kümmern. Richtig? Wenn ja, sollte dies für Sie funktionieren:

USE master
GO

ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
--This rolls back all uncommitted transactions in the db.
WITH ROLLBACK IMMEDIATE
GO

RESTORE DATABASE AdventureWorksDW
FROM ...
...
GO

Nun ein weiterer Punkt zu beachten. Nachdem Sie die Datenbank in den Einzelbenutzermodus versetzt haben, versucht möglicherweise eine andere Person, eine Verbindung zur Datenbank herzustellen. Wenn sie erfolgreich sind, können Sie mit der Wiederherstellung nicht fortfahren. Es ist ein Rennen! Mein Vorschlag ist, alle drei Anweisungen gleichzeitig auszuführen.

Dave Mason
quelle
alle drei Anweisungen in einer Transaktion.
Steam
1
Mein SSMS reagiert nicht, wenn ich versuche, auf diese Adventureworks-Datenbank zuzugreifen.
Steam
2
Er meint eigentlich USE masternicht USER master.
Async
7
Fügen Sie einfach ALTER DATABASE [AdventureWorksDW] SET MULTI_USERam Ende hinzu, um sicherzustellen, dass sich die Datenbank wieder im normalen Mehrbenutzermodus befindet.
Gnaanaa
1
@gnaanaa: Wenn sich die gesicherte Datenbank zum SINGLE_USERZeitpunkt SINGLE_USERder Sicherung im Modus befand , befindet sie sich bei der Wiederherstellung der Sicherung im Modus. Wenn es sich MULTI_USERzur Sicherungszeit im MULTI_USERModus befand, befindet es sich bei der Wiederherstellung im Modus. Sie machen einen großen Punkt: Es lohnt sich auf jeden Fall, nach Abschluss der Wiederherstellung zu überprüfen. Sie können RESTORE HEADERONLY auch auf dem Sicherungsmedium ausführen und IsSingleUserdie FlagsSpalte überprüfen oder bitweise berechnen .
Dave Mason
234
  1. Legen Sie den Pfad zum Wiederherstellen der Datei fest.
  2. Klicken Sie links auf "Optionen".
  3. Deaktivieren Sie "Tail-Log-Backup vor dem Wiederherstellen erstellen".
  4. Aktivieren Sie das Kontrollkästchen "Vorhandene Verbindungen zur Zieldatenbank schließen". Geben Sie hier die Bildbeschreibung ein
  5. OK klicken.
Vinu M Shankar
quelle
16
In meinem Fall war dieses Kontrollkästchen ausgegraut. Ich habe jedoch von vorne begonnen und konnte das Kontrollkästchen aktivieren, bevor ich die Quelle für die Wiederherstellung auswählte. Nach Auswahl der Sicherungsdatei wurde die Option erneut ausgegraut, das Kontrollkästchen wurde jedoch weiterhin aktiviert und die Wiederherstellung funktionierte.
Phansen
3
Ein großes Lob dafür, dass ich mich vor der Eingabe von SQL bewahrt habe. Die einzige GUI-Methode unter allen Antworten.
Lionet Chen
Ich hoffe, das hätte bei mir wie bei anderen funktioniert. Aber für mich blieb das Kontrollkästchen immer ausgegraut. Die Antwort von Andrei Karchueuski unten hat für mich funktioniert.
Devraj Gadhavi
11
Ich musste auch das Kontrollkästchen "Sicherung des Endprotokolls vor der Wiederherstellung erstellen" deaktivieren, bevor ich die Wiederherstellung durchführen konnte.
Hylle
3
"Vor dem Wiederherstellen eine Sicherung des Endprotokolls erstellen" muss ebenfalls deaktiviert sein. Danke
jedu
50

Führen Sie diese Abfrage aus, bevor Sie die Datenbank wiederherstellen:

alter database [YourDBName] 
set offline with rollback immediate

und dieser nach der Wiederherstellung:

  alter database [YourDBName] 
  set online
Andrei Karcheuski
quelle
Am Ende wechselte ich über SINGLE_USER zu dieser Methode, nachdem die Verbindung der Pilotanwendung die Wiederherstellung meiner Abfrage und den anschließenden Aufruf von MULTI_USER beendet hatte. Die Wiederherstellung konnte keinen exklusiven Zugriff erhalten und die alte Datenbank wurde im SINGLE_USER-Modus belassen.
Smörgåsbord
3
das hat bei mir funktioniert. und es wird automatisch online geschaltet, sobald Sie es wiederherstellen.
Dileep
3
Dies funktioniert und vermeidet die Rennbedingung in der akzeptierten Antwort.
Scott Whitlock
1
Danke Andrei.
Erdogan
11

Für mich ist die Lösung:

  1. Aktivieren Sie das Kontrollkästchen Vorhandene Datenbank überschreiben (MIT ERSETZEN) auf der Registerkarte optoins auf der linken Seite.

  2. Deaktivieren Sie alle anderen Optionen.

  3. Wählen Sie die Quell- und Zieldatenbank aus.

  4. OK klicken.

Das ist es.

Aayush Verma
quelle
1
Hat auch für mich gearbeitet. Ich musste auch "Tail-Log-Backup vor Wiederherstellung wiederherstellen" deaktivieren.
Yuva
7

Verwenden Sie das folgende Skript, um alle geöffneten Verbindungen zur Datenbank zu finden und zu beenden, bevor Sie die Datenbank wiederherstellen.

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

Hoffe das wird helfen ...

Aqeel Haider
quelle
3

Ich denke, Sie müssen nur die Datenbank auf den Einzelbenutzermodus einstellen, bevor Sie versuchen, wie unten beschrieben wiederherzustellen. Stellen Sie einfach sicher, dass Sie verwenden master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
Jason
quelle
2

Ich habe gerade den sqlexpress-Dienst neu gestartet und dann die Wiederherstellung ordnungsgemäß abgeschlossen

BabaNew
quelle
Was kann ich über die Ablehnung sagen ... für mich hat es funktioniert!
BabaNew
1
OP hatte ein Problem mit seinem Wiederherstellungsskript, da er die Tatsache nicht berücksichtigte, dass seine Datenbank möglicherweise bereits verwendet wird. Die Lösung bestand darin, sein Skript mit den richtigen Befehlen zu aktualisieren, die ihm exklusiven Zugriff auf die Datenbank ermöglichen. Während der Neustart des Dienstes möglicherweise für Sie funktioniert hat, war dies nicht die geeignete Lösung für sein Problem.
PL
1
Use Master
alter database databasename set offline with rollback immediate;

--Do Actual Restore
RESTORE DATABASE databasename
FROM DISK = 'path of bak file'
WITH MOVE 'datafile_data' TO 'D:\newDATA\data.mdf',
MOVE 'logfile_Log' TO 'D:\newDATA\DATA_log.ldf',replace

alter database databasename set online with rollback immediate;
GO
Puneeth
quelle
1

Lösung 1: Starten Sie die SQL-Dienste neu und versuchen Sie, die Datenbank wiederherzustellen. Lösung 2: Starten Sie das System / den Server neu und versuchen Sie, die Datenbank wiederherzustellen. Lösung 3: Nehmen Sie die aktuelle Datenbank zurück, löschen Sie die aktuelle / Ziel-Datenbank und versuchen Sie, die Datenbank wiederherzustellen.

Joseph Joy
quelle
1

Das Einstellen der Datenbank in den Einzelbenutzermodus hat bei mir nicht funktioniert, aber es hat funktioniert, sie offline zu schalten und dann wieder online zu schalten. Es befindet sich im Kontextmenü der Datenbank unter Aufgaben.

Stellen Sie sicher, dass im Dialogfeld die Option "Alle aktiven Verbindungen löschen" aktiviert ist.

Jeffrey Harmon
quelle
0

Hier ist eine Möglichkeit, wie ich die Datenbank von der Produktion bis zur Entwicklung wiederherstellen kann:

HINWEIS: Ich mache es über einen SSAS-Job, um die Produktionsdatenbank täglich zur Entwicklung zu bringen:

Schritt 1: Löschen Sie die Sicherung des Vortages in der Entwicklung:

declare @sql varchar(1024);

set @sql = 'DEL C:\ProdAEandAEXdataBACKUP\AE11.bak'
exec master..xp_cmdshell @sql

Schritt 2: Kopieren Sie die Produktionsdatenbank in die Entwicklung:

declare @cmdstring varchar(1000)
set @cmdstring = 'copy \\Share\SQLDBBackup\AE11.bak C:\ProdAEandAEXdataBACKUP'
exec master..xp_cmdshell @cmdstring 

Schritt 3: Wiederherstellung durch Ausführen eines SQL-Skripts

SQLCMD -E -S dev-erpdata1 -b -i "C:\ProdAEandAEXdataBACKUP\AE11_Restore.sql"

Code in der Datei AE11_Restore.sql:

RESTORE DATABASE AE11
FROM DISK = N'C:\ProdAEandAEXdataBACKUP\AE11.bak'
WITH MOVE 'AE11' TO 'E:\SQL_DATA\AE11.mdf',
MOVE 'AE11_log' TO 'D:\SQL_LOGS\AE11.ldf',
RECOVERY;
Nicht-Programmierer
quelle
0

Ich habe diesen Fehler erhalten, als nicht genügend Speicherplatz vorhanden war, um Db wiederherzustellen. Das Reinigen von etwas Platz löste es.

user3790083
quelle
0

Es hat bei mir funktioniert, die ursprüngliche Datenbank offline zu schalten

offline schalten

Ali Karaca
quelle