"Veritabanı geçişte" Hatası


12

Bugün zaten var olan bir veritabanı üzerinden bir veritabanını geri yüklemeye çalışıyordum, sadece veritabanını geri yükleyebilmem için SSMS -> Görevler -> Çevrimdışı Ol'a veritabanını sağ tıklattım.

Küçük bir açılır pencere belirdi ve bir süre için gösterildi Query Executing.....ve ardından bir hata attı Database is in use cannot take it offline. Topladığım bu veritabanına bazı aktif bağlantılar var, bu yüzden aşağıdaki sorguyu yürütmeye çalıştım

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

Yine bu noktada SSMS Query Executing.....bir süre için gösterdi ve sonra aşağıdaki hatayı attı:

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.

Bundan sonra veri tabanına SSMS üzerinden bağlanamadım. ve SSMS kullanarak çevrimdışına almaya çalıştığımda şöyle bir hata verdi:

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

Bu noktada ben sadece aynı hata mesajı döndürdü denedim bir şey veritabanına dokunmak couldn't Database is in Transition.

Google'da insanların benzer sorunla karşılaştığı bazı soruları okudum ve SSMS'yi kapatıp tekrar açmayı önerdiler, Ben de yaptım ve sadece bir dev sunucusu olduğu için sadece SSMS kullanarak veritabanını sildim ve yeni bir veritabanına geri yükledim.

Benim sorum buna neden olmuş olabilir ?? ve nasıl gelecekte olmasını önlemek için nasıl ve şimdiye kadar aynı durumda sonunda ben bunu başka tüm yolu silme sonra sabitleme başka bir yolu var ???

teşekkür ederim

Yanıtlar:


24

reprodüksiyon

  1. SSMS'yi açma
  2. Aşağıdakileri yeni bir sorgu penceresine yazın

    use <YourDatabase>;
    go
  3. Nesne Gezgini'ne (SSMS) gidin ve sağ tıklayın <YourDatabase>-> Tasks->Take Offline
  4. İkinci bir yeni sorgu penceresi açın ve aşağıdakileri yazın:

    use <YourDatabase>;
    go

Aşağıdaki mesajla karşılaşırsınız:

Msg 952, Seviye 16, Durum 1, Satır 1
Veritabanı 'TestDb1' geçiş aşamasında. İfadeyi daha sonra deneyin.

Bunun olmasının nedeni, aşağıdakine benzer bir teşhis sorgusundan bulunabilir:

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;

Değeri ne olursa olsun, bu hatayı yeniden oluşturmak için Nesne Gezgini'ne ihtiyacınız yoktur. Yalnızca aynı işlemi deneyen engellenen bir istek gerekir (bu durumda veritabanını çevrimdışı duruma getirin). T-SQL'deki üç adım için aşağıdaki ekran görüntüsüne bakın:

resim açıklamasını buraya girin

Büyük olasılıkla göreceğiniz şey, Object Explorer oturumunuzun başka bir oturum tarafından engellenmesidir (ile gösterilir blocking_session_id). Bu Nesne Gezgini oturumu Xveritabanında özel bir kilit ( ) almaya çalışacaktır . Yukarıdaki repro'nun durumunda, Object Explorer oturumuna bir güncelleme kilidi ( U) verildi ve özel bir kilide ( X) dönüştürülmeye çalışıldı . LCK_M_Xİlk sorgu penceresi ( veritabanında use <YourDatabase>paylaşılan bir kilit ( S) kapar) tarafından temsil edilen oturumumuz tarafından engellenen bir wait_type vardı .

Ve sonra bu hata , kilit almaya çalışan başka bir oturumdan kaynaklandı ve bu hata mesajı, farklı bir duruma (bu durumda çevrimiçi durum çevrimdışı geçiş).

Bir dahaki sefere ne yapmalısın?

Öncelikle panik yapmayın ve veritabanlarını düşürmeye başlamayın . Gördüklerinizi neden gördüğünüzü öğrenmek için bir sorun giderme yaklaşımı (yukarıdaki gibi benzer bir teşhis sorgusuyla) almanız gerekir. Böyle bir mesajla veya bir şey "asılı" göründüğünde, otomatik olarak eşzamanlılık eksikliğini üstlenmeli ve engellemeye kazmaya başlamalısınız ( sys.dm_tran_locksiyi bir başlangıçtır).

Bir yan not olarak, herhangi bir rastgele işlem yapmadan önce bir sorunun kökenini bulmak için en iyisi olduğuna inanıyorum. Sadece bu işlemle değil, beklemediğiniz tüm davranışlar için de geçerlidir. Soruna gerçekten neyin sebep olduğunu bilmek , bunun gerçekten önemli olmadığı açıktır. Temelde bir engelleme zinciriniz vardı ve üst engelleyici, büyük olasılıkla bir KILLaçık bırakmış olabileceğiniz bir şeydi veya bir oturumun isteği istemiyorsanız, KILLtamamlanana kadar bekleyebilirdiniz. Her iki durumda da, senaryonuzun (geri alma veya kesinti için bekleme) verildiğinde doğru ve ihtiyatlı bir karar verme bilginiz olurdu.

Dikkate değer başka bir şey, bu her zaman bir GUI yerine T-SQL alternatif tercih nedenlerinden biridir. T-SQL ile ne yürüttüğünüzü ve SQL Server'ın ne yaptığını tam olarak biliyorsunuz. Sonuçta, açık komutu verdiniz. Bir GUI kullandığınızda, gerçek T-SQL bir soyutlama olacaktır. Bu durumda, engellenen Object Explorer'ın veritabanını çevrimdışına alma girişimine baktım ve öyleydi ALTER DATABASE <YourDatabase> SET OFFLINE. Geri alma girişimi olmadı, bu yüzden süresiz olarak bekliyordu. Sizin durumunuzda, bu veritabanında kilitleri olan oturumları geri almak isterseniz, geri dönmenin iyi olduğuna dair ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATEilk belirlemeyi yapmış olsaydınız büyük olasılıkla yeterli olurdu.



0

Hiçbir şey yapmanıza gerek yok, sadece SqLWB.exeGörev Yöneticisi'nden işlemi öldürün, SQL Server'ı açın, veritabanına sağ tıklayın ve çevrimdışı yapın. Çalışmazsa, oturum öldürüldükten sonra komutu yazın

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

ve ardından çevrimdışı. Benim için de çalıştığı gibi çalışacak.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.