2009-08-18 9 views
2

Ich bin gerade dabei, eine Entwicklungsdatenbank auf dem Produktionsserver abzutrennen. Da dies ein Produktionsserver ist, möchte ich den SQL-Dienst nicht neu starten. Das ist das Worst-Case-Szenario.Datenbank trennen/offline nehmen fehlgeschlagen

Offensichtlich habe ich versucht, es durch SSMS zu lösen. Sagte mir, es gab eine aktive Verbindung und ich habe es getrennt. Als ich das zweite Mal losließ, sagte es mir, dass das unmöglich sei, seit es benutzt wurde.

Ich versuchte EXEC sp_detach_db 'DB' ohne Glück.

Ich habe versucht, die Datenbank offline zu bekommen. Das lief für ungefähr 15 Minuten, als mir langweilig wurde und ich es abstellte.

Wie auch immer, ich habe alles versucht ... Ich habe sichergestellt, dass alle Verbindungen mit dem Verbindungsindikator in detach Datenbank mit SSMS getötet wurden.

Die folgende ergab 0 Treffer:

USE master SELECT * FROM sys.sysprocesses WHERE dbid = DB_ID ('DB')

und Folgendes wird nun für 18 Minuten ausgeführt wird:

ALTER DATABASE DB SET OFFLINE MIT ROLLBACK SOFORT

Ich habe SMSS während dieser ganzen Zeit regelmäßig neu gestartet, um sicherzustellen, dass SSMS nicht der Übeltäter ist, indem ich etwas unsichtbar sperrte.

Gibt es nicht einen Weg, es brutal zu erzwingen? Das Datenbankschema ist etwas, das mir ziemlich am Herzen liegt, aber die Daten sind entbehrlich.

Hoffentlich gibt es eine Art schnelle Lösung? :)

Der DBA wird versuchen, den Prozess heute Nacht zurückzusetzen, aber ich würde gerne den Fix für diese nur für den Fall wissen.

Thx!

ps: Ich benutze DTC ... vielleicht könnte dies erklären, warum meine Datenbank plötzlich gesperrt wurde?

edit:

ich jetzt mache die folgende, die in einer unendlichen Ausführung des letzten Teils führt. Die erste Abfrage gibt sogar 0 zurück, also nehme ich an, dass das Töten der Benutzer nicht einmal von Bedeutung ist.

USE [master] GO

SELECT * FROM sys.sysprocesses WHERE dbid = DB_ID ('Datenbank')

DECLARE GO @return_value int

EXEC @return_value = [dbo].[Usp_KillUsers] @p_DBName = 'Datenbank'

SELECT 'Rückgabewert' = @return_value

ALTER DATABASE Datenbank SET OFFLINE MIT ROLLBACK IMMEDIATE

Antwort

1

DISTINCT req_transactionUOW SELECT FROM syslockinfo

KILL 'number_returned' (diejenige (n) mit process_id -2)

die Ursache war DTC etwas lästig sein und die Datenbank vollständig mit einer gescheiterten Transaktion aufzuhängen. Jetzt würde ich gerne wissen, warum das passiert ist. Aber zumindest gibt es mir die Möglichkeit, die fehlerhaften Transaktionen zurückzusetzen, wenn das Problem erneut auftritt.

Ich poste es hier, weil ich sicher bin, dass es einigen Leuten helfen wird, die die gleichen Probleme erfahren.

1

GO GO Wie sind Sie eine Verbindung zu SQL Server herstellen? Ist es möglich, dass Sie versuchen, die Datenbank zu trennen, während Sie selbst damit verbunden sind? Dies kann abhängig von der Version von SQL Server ein Trennen blockieren.

Sie können die DAC für solche Sachen versuchen.

+1

Auch für solche Aufgaben möchte ich am Anfang einen expliziten "Master verwenden", um sicherzustellen, dass ich nicht die DB verwende, die ich lösen möchte. –

+0

Ich bin 100% sicher, dass ich die Datenbank nicht benutze. Ich habe jeden Ort überprüft, den Sie überprüfen können, um sicherzustellen, dass keine Verbindungen in dieser Datenbank aktiv sind. – SpoBo

1

Versuchen Sie, alle Verbindungen zu töten, bevor die Datenbank Abnehmen IE:

USE [master] 
GO 
/****** Object: StoredProcedure [dbo].[usp_KillUsers] Script Date: 08/18/2009 10:42:48 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[usp_KillUsers] 
    @p_DBName SYSNAME = NULL 
AS 

/* Check Paramaters     */ 
/* Check for a DB name     */ 
IF (@p_DBName IS NULL) 
BEGIN 
    PRINT 'You must supply a DB Name' 
    RETURN 
END -- DB is NULL 
IF (@p_DBName = 'master') 
BEGIN 
    PRINT 'You cannot run this process against the master database!' 
    RETURN 
END -- Master supplied 
IF (@p_DBName = DB_NAME()) 
BEGIN 
    PRINT 'You cannot run this process against your connections database!' 
    RETURN 
END -- your database supplied 

SET NOCOUNT ON 

/* Declare Variables     */ 
DECLARE @v_spid INT, 
     @v_SQL NVARCHAR(255) 

/* Declare the Table Cursor (Identity) */ 
DECLARE c_Users CURSOR 
    FAST_FORWARD FOR 
SELECT spid 
    FROM master..sysprocesses (NOLOCK) 
    WHERE db_name(dbid) LIKE @p_DBName 

OPEN c_Users 

FETCH NEXT FROM c_Users INTO @v_spid 
WHILE (@@FETCH_STATUS <> -1) 
BEGIN 
    IF (@@FETCH_STATUS <> -2) 
    BEGIN 
    SELECT @v_SQL = 'KILL ' + CONVERT(NVARCHAR, @v_spid) 
-- PRINT @v_SQL 
    EXEC (@v_SQL) 
    END -- -2 
    FETCH NEXT FROM c_Users INTO @v_spid 
END -- While 

CLOSE c_Users 
DEALLOCATE c_Users 

Dies ist ein Skript alle Benutzer Verbindungen zu einer Datenbank zu töten, nur den Namen der Datenbank übergeben, und es wird sich schließen. Dann können Sie versuchen, die Datenbank zu trennen. Dieses Skript ist eines, das ich vor einiger Zeit gefunden habe und ich kann es nicht als mein eigenes beanspruchen. Ich meine das nicht als irgendeine Art von Plagiat, ich habe einfach nicht die Quelle.

+0

Getestet es, gab 0 zurück, also denke ich, dass alle Verbindungen geschlossen waren. Danach ist es immer noch fehlgeschlagen, es offline zu bringen. Sagte mir, es konnte die Datenbank nicht sperren. – SpoBo