ALTER DATABASE ist fehlgeschlagen, da die Datenbank nicht gesperrt werden konnte


124

Ich muss eine Datenbank neu starten, da einige Prozesse nicht funktionieren. Mein Plan ist es, es offline und wieder online zu schalten.

Ich versuche dies in SQL Server Management Studio 2008 zu tun:

use master;
go
alter database qcvalues
set single_user
with rollback immediate;
alter database qcvalues
set multi_user;
go

Ich erhalte folgende Fehler:

Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'qcvalues'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
Msg 5061, Level 16, State 1, Line 4
ALTER DATABASE failed because a lock could not be placed on database 'qcvalues'. Try again later.
Msg 5069, Level 16, State 1, Line 4
ALTER DATABASE statement failed.

Was mache ich falsch?


Was ist das Problem, das diesen Bedarf überhaupt verursacht hat? Haben Sie im Moment einige Rollback-Transaktionen? Haben Sie diesen Befehl auch bereits in einem anderen SSMS-Fenster ausgeführt, das möglicherweise noch geöffnet ist? Ich frage mich (reine Spekulation), ob dies eine Sperre erfordert, die andere Versuche blockiert, aber es wartet noch, bis die Datenbank tatsächlich in den single_user-Modus versetzt werden kann.
Martin Smith

1
@ Martin - fair genug. Ich muss an etwas anderes denken oder meinen Verstand verlieren.
beides

@ Vielen Dank an alle, ich habe SSMS neu gestartet und konnte alle töten
JOE SKEET

Könnte intelligent sein. Ich habe eine unvollständige Abfrage gelöscht, bei der beim Versuch, auf die Datenbank zuzugreifen, verschnörkelte Zeilen angezeigt wurden, und dann hat es funktioniert.
Faahmed

Antworten:


293

Nachdem Sie den Fehler erhalten haben, führen Sie

EXEC sp_who2

Suchen Sie nach der Datenbank in der Liste. Möglicherweise wurde eine Verbindung nicht beendet. Wenn Sie Verbindungen zur Datenbank finden, führen Sie aus

KILL <SPID>

Wo <SPID>ist die SPID für die Sitzungen, die mit der Datenbank verbunden sind?

Probieren Sie Ihr Skript aus, nachdem alle Verbindungen zur Datenbank entfernt wurden.

Leider habe ich keinen Grund, warum Sie das Problem sehen, aber hier ist ein Link, der zeigt, dass das Problem an anderer Stelle aufgetreten ist.

http://www.geakeit.co.uk/2010/12/11/sql-take-offline-fails-alter-database-failed-because-a-lock-could-not-error-5061/


Können Sie erklären, warum eine Verbindung durch den Befehl nicht beendet wird? Der einzige Grund, den ich mir vorstellen kann, ist, dass es sich noch im Rollback befindet oder dass ein set single_userVersuch noch aussteht.
Martin Smith

@ Martin, ich fürchte, ich habe keinen Grund dafür. Aber ich werde einen Link hinzufügen, der darauf hinweist, dass andere das Problem gesehen haben. Ich bin damit einverstanden, dass ein Transaktions-Rollback das Problem sein könnte, aber das KILLwürde es auch nicht lösen.
Bobs

Seien Sie nett zu verstehen, warum dies passiert, aber die Kommentare auf Ihrem Link scheinen darauf hinzudeuten, dass es funktionieren würde! (+1)
Martin Smith

KILL (87) Ergebnisse in Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '('.erm ....
Tim Abell

2
@MartinSmith Ich glaube, ich weiß warum: Ich hatte gerade das gleiche Problem, eine anhaltende Verbindung, die unter sp_who2 angezeigt wurde und dazu führte, dass ein Offline-Vorgang zum Stillstand kam. Es stellte sich heraus, dass es sich bei ssms um ein offenes Fenster für Bearbeitungszeilen handelt. Ich glaube, was hier passiert, ist, dass das Fenster zum Bearbeiten von Zeilen eine Abfrage ist, die mit einer bearbeitbaren Ergebnismenge geöffnet bleibt. SQL Server verfügt über eine solche Funktion als Alternative zu Aktualisierungsanweisungen. Beim Schließen dieses speziellen ssms-Fensters wurde das Hängen, das offline geschaltet wurde, sofort abgeschlossen.
John

5

Ich habe diesen Fehler wie folgt reproduziert.

Verbindung 1 (einige Minuten laufen lassen)

CREATE DATABASE TESTING123
GO

USE TESTING123;

SELECT NEWID() AS X INTO FOO
FROM sys.objects s1,sys.objects s2,sys.objects s3,sys.objects s4 ,sys.objects s5 ,sys.objects s6

Anschlüsse 2 und 3

set lock_timeout 5;

ALTER DATABASE TESTING123 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;

2

Versuchen Sie dies, wenn es "im Übergang" ist ...

http://learnmysql.blogspot.com/2012/05/database-is-in-transition-try-statement.html

USE master
GO

ALTER DATABASE <db_name>

SET OFFLINE WITH ROLLBACK IMMEDIATE
...
...
ALTER DATABASE <db_name> SET ONLINE

Funktioniert nicht, wenn sich die Datenbank im Übergang befindet, es wird der gleiche Fehler mit der SET OFFLINEvom OP erwähnten Anweisung angezeigt (möglicherweise gibt es Szenarien, in denen dies funktioniert, aber für mich nicht)
Abel

1

Ich werde dies hier hinzufügen, falls jemand so viel Glück hat wie ich.

Beachten Sie beim Überprüfen der Liste der Prozesse sp_who2 die Prozesse, die nicht nur für die betroffene Datenbank, sondern auch für den Master ausgeführt werden . In meinem Fall bezog sich das Problem, das die Datenbank blockierte, auf eine gespeicherte Prozedur, die eine xp_cmdshell startete.

Überprüfen Sie, ob Sie alle Prozesse in haben KILL / Rollback Zustand für Master - Datenbank

SELECT *
FROM sys.sysprocesses
WHERE cmd = 'KILLED/ROLLBACK'

Wenn Sie das gleiche Problem haben, hilft wahrscheinlich nur der Befehl KILL nicht. Sie können den SQL Server neu starten. Besser ist es, die cmd.exe unter Windows-Prozessen unter dem SQL Server-Betriebssystem zu finden und zu beenden.


0

Gehen Sie in SQL Management Studio zu Sicherheit -> Anmeldungen und doppelklicken Sie auf Ihre Anmeldung. Wählen Sie in der linken Spalte Serverrollen aus, und überprüfen Sie, ob sysadmin aktiviert ist.

In meinem Fall war ich in einem Konto ohne dieses Privileg angemeldet.

HTH!


1
Der Fehler in der ursprünglichen Frage tritt auch auf, wenn Sie SA sind. Er hat nichts mit Ihren Rechten zu tun. Wenn Sie nicht über genügend Rechte verfügen, können Sie den Offline-Befehl nicht ausführen.
Abel

0

Das Töten der Prozess-ID hat bei mir gut funktioniert. Wenn Sie den Befehl "EXEC sp_who2" über ein neues Abfragefenster ausführen ... und die Ergebnisse für die Datenbank "beschäftigt" filtern, hat es das Beenden der Prozesse mit dem Befehl "KILL" geschafft, den Trick auszuführen. Danach hat alles wieder funktioniert.


0

Nur um meine zwei Cent hinzuzufügen. Ich habe mich in die gleiche Situation gebracht, während ich nach den minimal erforderlichen Berechtigungen eines Datenbank-Logins gesucht habe, um die Anweisung erfolgreich auszuführen:

ALTER DATABASE ... SET SINGLE_USER WITH ROLLBACK IMMEDIATE

Es scheint, dass die ALTER-Anweisung erfolgreich ausgeführt wird , wenn sie mit einem Sysadmin- Login ausgeführt wird, aber sie erfordert den Teil zur Bereinigung von Verbindungen, wenn sie unter einem Login ausgeführt wird, der "nur" eingeschränkte Berechtigungen hat, wie:

ALTER ANY DATABASE

PS Ich habe stundenlang versucht herauszufinden, warum "ALTER DATABASE .." nicht funktioniert, wenn es unter einem Login ausgeführt wird, das die dbcreator-Rolle + ALTER ANY DATABASE- Berechtigungen hat. Hier ist mein MSDN-Thread !


0

Ich weiß, dass dies ein alter Beitrag ist, aber ich bin kürzlich auf ein sehr ähnliches Problem gestoßen. Leider konnte ich keinen der Befehle zum Ändern der Datenbank verwenden, da keine exklusive Sperre gesetzt werden konnte. Aber ich konnte nie eine offene Verbindung zur Datenbank finden. Ich musste schließlich den Integritätsstatus der Datenbank zwangsweise löschen, um sie in einen Wiederherstellungsstatus zu zwingen, anstatt sie wiederherzustellen.


0

In seltenen Fällen (z. B. nachdem eine schwere Transaktion festgeschrieben wurde) verhindert ein laufender CHECKPOINT-Systemprozess, der eine DATEISperre für die Datenbankdatei hält, den Übergang in den MULTI_USER-Modus.


0

In meinem Szenario hat kein Prozess die Datenbank unter sp_who2 blockiert. Wir haben jedoch festgestellt, dass ausstehende Prozesse noch ausgeführt werden, da die Datenbank viel größer als unsere anderen Datenbanken ist. Aus diesem Grund wird die Datenbank unter der Verfügbarkeitsgruppe immer noch als rot / offline angezeigt, nachdem wir versucht haben, die Daten durch Klicken mit der rechten Maustaste auf die angehaltene Datenbank wieder aufzunehmen.

Um zu überprüfen, ob noch Prozesse ausgeführt werden, führen Sie einfach diesen Befehl aus: Wählen Sie Prozent abgeschlossen aus sys.dm_exec_requests aus, wobei Prozent_Komplett> 0 ist

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.