"Database sedang dalam transisi" Kesalahan

12

Hari ini saya mencoba mengembalikan database ke database yang sudah ada, saya cukup mengklik kanan database di SSMS -> Tugas -> Ambil Offline sehingga saya bisa mengembalikan database.

Sebuah jendela sembulan kecil muncul dan muncul Query Executing.....untuk beberapa saat dan kemudian melemparkan pesan kesalahan Database is in use cannot take it offline. Dari yang saya kumpulkan ada beberapa koneksi aktif ke database itu jadi saya mencoba untuk mengeksekusi query berikut

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

Sekali lagi pada titik ini SSMS menunjukkan Query Executing.....kapan dan kemudian melemparkan kesalahan berikut:

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.

Setelah ini saya tidak bisa terhubung ke database melalui SSMS. dan ketika saya mencoba untuk membuatnya offline menggunakan SSMS itu melemparkan kesalahan yang mengatakan:

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

Pada titik ini saya tidak bisa menyentuh database apa pun yang saya coba mengembalikan pesan kesalahan yang sama Database is in Transition.

Saya mendapat di google membaca beberapa pertanyaan di mana orang-orang menghadapi masalah yang sama dan mereka merekomendasikan untuk menutup SSMS dan membukanya lagi, begitu juga saya dan Karena itu hanya server dev saya hanya menghapus database menggunakan SSMS dan dipulihkan pada database baru.

Pertanyaan saya adalah apa yang mungkin menyebabkan ini ?? dan bagaimana saya bisa Menghindari hal ini terjadi di masa depan dan jika saya pernah berakhir dalam situasi yang sama di masa depan apakah ada cara lain untuk memperbaikinya selain menghapus seluruh database ???

Terima kasih

M.Ali
sumber

Jawaban:

23

Repro

  1. Buka SSMS
  2. Ketik yang berikut ke dalam jendela permintaan baru

    use <YourDatabase>;
    go
  3. Pergi ke Object Explorer (SSMS) dan klik kanan pada <YourDatabase>-> Tasks->Take Offline
  4. Buka jendela permintaan baru kedua dan ketikkan yang berikut:

    use <YourDatabase>;
    go

Anda akan diminta dengan pesan berikut:

Msg 952, Level 16,
Status 1, Baris 1, Basis Data 'TestDb1' sedang dalam transisi. Coba pernyataannya nanti.

Alasan ini terjadi dapat ditemukan dari permintaan diagnostik yang mirip dengan yang di bawah ini:

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;

Untuk apa nilainya, Anda tidak perlu Object Explorer untuk mereproduksi kesalahan ini. Anda hanya perlu permintaan yang diblokir yang mencoba operasi yang sama (dalam hal ini, buat database menjadi offline). Lihat screenshot di bawah ini untuk tiga langkah dalam T-SQL:

masukkan deskripsi gambar di sini

Apa yang kemungkinan besar akan Anda lihat adalah sesi Object Explorer Anda diblokir oleh sesi lain (ditunjukkan oleh blocking_session_id). Sesi Object Explorer itu akan mencoba untuk mendapatkan kunci eksklusif ( X) pada database. Dalam kasus repro di atas, sesi Object Explorer diberikan kunci pembaruan ( U) dan mencoba untuk mengkonversi ke kunci eksklusif ( X). Itu memiliki wait_type LCK_M_X, diblokir oleh sesi kami yang diwakili oleh jendela kueri pertama ( use <YourDatabase>ambil kunci bersama ( S) pada database).

Dan kemudian kesalahan ini muncul dari sesi lain mencoba untuk mendapatkan kunci, dan pesan kesalahan ini menghasilkan penolakan sesi untuk mendapatkan akses ke database yang mencoba untuk transisi ke keadaan yang berbeda (dalam hal ini, keadaan online ke transisi offline).

Apa yang harus Anda lakukan lain kali?

Pertama, jangan panik dan jangan mulai menjatuhkan basis data . Anda perlu mengambil pendekatan pemecahan masalah (dengan permintaan diagnostik serupa seperti yang di atas) untuk mencari tahu mengapa Anda melihat apa yang Anda lihat. Dengan pesan seperti itu, atau ketika sesuatu muncul "hang", Anda harus secara otomatis menganggap kurangnya konkurensi dan mulai menggali untuk memblokir ( sys.dm_tran_locksadalah awal yang baik).

Sebagai catatan tambahan, saya benar-benar yakin bahwa Anda yang terbaik untuk mengetahui akar masalah sebelum mengambil tindakan acak apa pun. Tidak hanya dengan operasi ini, tetapi itu berlaku untuk semua perilaku yang tidak Anda harapkan. Mengetahui apa yang sebenarnya menyebabkan masalah Anda, sudah jelas itu bukan masalah besar. Pada dasarnya Anda memiliki rantai pemblokiran, dan pemblokir induk adalah sesuatu yang kemungkinan besar baru saja Anda keluarkan KILL, atau jika itu adalah permintaan sesi yang tidak Anda inginkan KILLmaka Anda bisa menunggu sampai selesai. Either way, Anda akan memiliki pengetahuan untuk membuat keputusan yang tepat dan bijaksana mengingat skenario khusus Anda (kembalikan atau tunggu komitmen).

Hal lain yang patut dicatat, ini adalah salah satu alasan mengapa saya selalu memilih alternatif T-SQL daripada GUI. Anda tahu persis apa yang Anda jalankan dengan T-SQL dan apa yang dilakukan SQL Server. Bagaimanapun, Anda mengeluarkan perintah eksplisit. Ketika Anda menggunakan GUI, T-SQL yang sebenarnya akan menjadi abstraksi. Dalam hal ini, saya melihat upaya Object Explorer yang diblokir untuk membuat database offline dan itu ALTER DATABASE <YourDatabase> SET OFFLINE. Tidak ada upaya untuk mengembalikan, itulah sebabnya ia menunggu tanpa batas. Dalam kasus Anda, jika Anda ingin mengembalikan sesi yang memiliki kunci pada basis data itu, ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATEkemungkinan besar Anda sudah mencukupi jika Anda telah membuat keputusan awal bahwa rollback baik-baik saja.

Thomas Stringer
sumber
3

Cukup menutup SQL Server Management Studio (SSMS) dan membuka kembali masalah untuk saya.

Michael Bollhoefer
sumber
0

Tidak perlu melakukan apa pun, cukup matikan proses SqLWB.exedari Task Manager, buka SQL Server, klik kanan pada database dan bawa offline. Jika tidak berhasil, maka setelah sesi terbunuh, ketikkan perintah

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

dan kemudian offline. Ini akan berhasil karena itu bekerja untuk saya juga.

garima
sumber