Errore "Database in transizione"


12

Oggi stavo cercando di ripristinare un database su un database già esistente, ho semplicemente fatto clic con il pulsante destro del mouse sul database in SSMS -> Attività -> Take Offline per poter ripristinare il database.

Una piccola finestra pop-up è apparso e mostrato Query Executing.....per qualche tempo e poi ha lanciato un errore dicendo Database is in use cannot take it offline. Da cui ho raccolto ci sono alcune connessioni attive a quel database, quindi ho cercato di eseguire la seguente query

USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO

Ancora una volta a questo punto il SSMS ha mostrato Query Executing.....per un po 'di tempo e quindi ha gettato il seguente errore:

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

Dopo questo non sono riuscito a collegarmi al database tramite SSMS. e quando ho provato a metterlo offline usando SSMS ha lanciato un errore che diceva:

Database is in Transition. Try later .....

A questo punto semplicemente non sono riuscito a toccare il database, qualunque cosa ho provato ha restituito lo stesso messaggio di errore Database is in Transition.

Ho ottenuto su Google leggere alcune domande in cui le persone avevano riscontrato problemi simili e mi hanno consigliato di chiudere SSMS e aprirlo di nuovo, così ho fatto io e poiché era solo un server di sviluppo ho appena eliminato il database utilizzando SSMS e ripristinato su un nuovo database.

La mia domanda è: cosa avrebbe potuto causare questo ?? e come posso evitare che ciò accada in futuro e se mai dovessi finire nella stessa situazione in futuro, c'è un altro modo di aggiustarlo se non l'eliminazione dell'intero database ???

Grazie

Risposte:


23

Repro

  1. Apri SSMS
  2. Digitare quanto segue in una nuova finestra di query

    use <YourDatabase>;
    go
  3. Passare a Esplora oggetti (SSMS) e fare clic con il tasto destro su <YourDatabase>-> Tasks->Take Offline
  4. Aprire una seconda nuova finestra di query e digitare quanto segue:

    use <YourDatabase>;
    go

Ti verrà richiesto con il seguente messaggio:

Messaggio 952, livello 16, stato 1, riga 1
Database "TestDb1" è in transizione. Prova la dichiarazione più tardi.

Il motivo per cui ciò accade può essere trovato da una query diagnostica simile a quella seguente:

select
    l.resource_type,
    l.request_mode,
    l.request_status,
    l.request_session_id,
    r.command,
    r.status,
    r.blocking_session_id,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    request_sql_text = st.text,
    s.program_name,
    most_recent_sql_text = stc.text
from sys.dm_tran_locks l
left join sys.dm_exec_requests r
on l.request_session_id = r.session_id
left join sys.dm_exec_sessions s
on l.request_session_id = s.session_id
left join sys.dm_exec_connections c
on s.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc
where l.resource_database_id = db_id('<YourDatabase>')
order by request_session_id;

Per quello che vale, non è necessario Esplora oggetti per riprodurre questo errore. Hai solo bisogno di una richiesta bloccata che sta tentando la stessa operazione (in questo caso, porta il database offline). Vedi lo screenshot seguente per i tre passaggi in T-SQL:

inserisci qui la descrizione dell'immagine

Ciò che molto probabilmente vedrai è che la sessione di Esplora oggetti viene bloccata da un'altra sessione (indicata da blocking_session_id). La sessione Esplora oggetti tenterà di ottenere un blocco esclusivo ( X) sul database. Nel caso della replica precedente, alla sessione Esplora oggetti è stato concesso un blocco degli aggiornamenti ( U) e tentando di convertirlo in un blocco esclusivo ( X). Aveva un wait_type di LCK_M_X, bloccato dalla nostra sessione che era rappresentata dalla prima finestra della query ( use <YourDatabase>prende un lock condiviso ( S) sul database).

E quindi questo errore è nato da un'altra sessione che ha cercato di ottenere un blocco e questo messaggio di errore comporta la negazione di una sessione per ottenere l'accesso a un database che sta tentando di passare a uno stato diverso (in questo caso, lo stato online alla transizione offline).

Cosa dovresti fare la prossima volta?

Prima di tutto, non farti prendere dal panico e non iniziare a eliminare i database . È necessario adottare un approccio di risoluzione dei problemi (con una query diagnostica simile a quella sopra) per scoprire perché stai vedendo quello che stai vedendo. Con un messaggio del genere o quando qualcosa appare "bloccato", dovresti assumere automaticamente una mancanza di concorrenza e iniziare a scavare nel blocco ( sys.dm_tran_locksè un buon inizio).

Come nota a margine, credo davvero che tu sia meglio scoprire la radice di un problema prima di intraprendere qualsiasi azione casuale. Non solo con questa operazione, ma vale per tutti i comportamenti che non ti aspetti. Sapendo cosa stava davvero causando il tuo problema, è ovvio che non era un grosso problema. Fondamentalmente avevi una catena di blocco e il blocco dei genitori era qualcosa che molto probabilmente avresti potuto emettere KILL, o se era una richiesta di una sessione che non volevi, KILLavresti potuto aspettare fino al completamento. Ad ogni modo, avresti avuto le conoscenze per prendere la decisione giusta e prudente dato il tuo particolare scenario (rollback o attendere il commit).

Un'altra cosa degna di nota, questo è uno dei motivi per cui scelgo sempre l'alternativa T-SQL anziché una GUI. Sai esattamente cosa stai eseguendo con T-SQL e cosa sta facendo SQL Server. Dopo tutto, hai emesso il comando esplicito. Quando si utilizza una GUI, l'attuale T-SQL sarà un'astrazione. In questo caso, ho esaminato il tentativo di Object Explorer bloccato di portare offline il database ed è stato ALTER DATABASE <YourDatabase> SET OFFLINE. Non c'è stato alcun tentativo di rollback, motivo per cui è stato indefinitamente in attesa. Nel tuo caso, se volessi eseguire il rollback delle sessioni con blocchi su quel database, ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATEmolto probabilmente ti basterebbe se avessi preso la decisione iniziale che il rollback andava bene.


3

La semplice chiusura di SQL Server Management Studio (SSMS) e la riapertura hanno risolto il problema per me.


0

Non c'è bisogno di fare nulla, basta uccidere il processo SqLWB.exeda Task Manager, aprire SQL Server, fare clic con il tasto destro sul database e metterlo offline. Se non funziona, dopo che la sessione è stata interrotta, digitare il comando

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

e poi offline. Funzionerà come ha funzionato anche per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.