ข้อผิดพลาด“ ฐานข้อมูลกำลังอยู่ในช่วงเปลี่ยนผ่าน”


12

วันนี้ฉันพยายามกู้คืนฐานข้อมูลผ่านฐานข้อมูลที่มีอยู่แล้วฉันเพียงคลิกขวาที่ฐานข้อมูลใน SSMS -> ภารกิจ -> ใช้ออฟไลน์เพื่อที่ฉันจะคืนค่าฐานข้อมูล

หน้าต่างป๊อปอัปขนาดเล็กปรากฏขึ้นและปรากฏขึ้นQuery Executing.....เป็นครั้งคราวแล้วเกิดข้อผิดพลาดDatabase is in use cannot take it offlineขึ้น จากที่ฉันรวบรวมมีการเชื่อมต่อที่ใช้งานกับฐานข้อมูลนั้นดังนั้นฉันพยายามที่จะดำเนินการค้นหาต่อไปนี้

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

อีกครั้งที่จุดนี้ SSMS พบQuery Executing.....บางครั้งแล้วโยนข้อผิดพลาดต่อไปนี้:

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.

หลังจากนี้ฉันไม่สามารถเชื่อมต่อกับฐานข้อมูลผ่าน SSMS ได้ และเมื่อฉันพยายามที่จะออฟไลน์โดยใช้ SSMS ข้อผิดพลาดขว้างว่า:

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

ณ จุดนี้ผมก็ could'nt Database is in Transitionสัมผัสอะไรฐานข้อมูลฉันพยายามมันกลับข้อผิดพลาดเดียวกัน

ฉันได้ google อ่านคำถามที่ผู้คนต้องเผชิญกับปัญหาที่คล้ายกันและพวกเขาแนะนำให้ปิด SSMS และเปิดอีกครั้งดังนั้นฉันและเพราะมันเป็นเพียงเซิร์ฟเวอร์ dev ฉันเพิ่งลบฐานข้อมูลโดยใช้ SSMS และเรียกคืนบนฐานข้อมูลใหม่

คำถามของฉันคือสิ่งที่อาจทำให้เกิดปัญหานี้? และฉันจะหลีกเลี่ยงสิ่งนี้ให้เกิดขึ้นได้ในอนาคตและหากฉันเคยอยู่ในสถานการณ์เดียวกันในอนาคตมีวิธีอื่นในการแก้ไขปัญหาอื่น ๆ แล้วลบฐานข้อมูลทั้งหมดหรือไม่

ขอขอบคุณ

คำตอบ:


24

Repro

  1. เปิด SSMS
  2. พิมพ์ข้อความต่อไปนี้ลงในหน้าต่างแบบสอบถามใหม่

    use <YourDatabase>;
    go
    
  3. ไปที่ Object Explorer (SSMS) แล้วคลิกขวาที่<YourDatabase>-> Tasks->Take Offline
  4. เปิดหน้าต่างแบบสอบถามใหม่ที่สองและพิมพ์ข้อความต่อไปนี้:

    use <YourDatabase>;
    go
    

คุณจะได้รับแจ้งพร้อมข้อความต่อไปนี้:

เกี่ยวกับข่าวสาร 952 ระดับ 16 สถานะ 1
ฐานข้อมูลบรรทัด 1 'TestDb1' อยู่ในช่วงการเปลี่ยนภาพ ลองคำสั่งในภายหลัง

สาเหตุที่เกิดขึ้นสามารถพบได้จากแบบสอบถามการวินิจฉัยที่คล้ายกันไปยังหนึ่งด้านล่าง:

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;

สำหรับสิ่งที่คุ้มค่าคุณไม่ต้องใช้ Object Explorer เพื่อทำซ้ำข้อผิดพลาดนี้ คุณเพียงแค่ต้องการคำขอที่ถูกบล็อกที่พยายามดำเนินการเดียวกัน (ในกรณีนี้ให้ใช้ฐานข้อมูลออฟไลน์) ดูภาพหน้าจอด้านล่างสำหรับสามขั้นตอนใน T-SQL:

ป้อนคำอธิบายรูปภาพที่นี่

สิ่งที่คุณจะเห็นได้มากที่สุดคือเซสชัน Object Explorer ของคุณถูกบล็อกโดยเซสชันอื่น (แสดงโดยblocking_session_id) เซสชัน Object Explorer นั้นจะพยายามล็อกแบบเอกสิทธิ์ ( X) บนฐานข้อมูล ในกรณีของ repro ดังกล่าวเซสชัน Object Explorer ได้รับการล็อกการปรับปรุง ( U) และพยายามแปลงเป็นล็อคแบบเอกสิทธิ์ ( X) มี wait_type ของLCK_M_Xถูกบล็อกโดยเซสชันของเราที่แสดงโดยหน้าต่างแบบสอบถามแรก ( use <YourDatabase>คว้าล็อคที่ใช้ร่วมกัน ( S) บนฐานข้อมูล)

จากนั้นข้อผิดพลาดนี้มาจากอีกเซสชันหนึ่งพยายามรับการล็อกและข้อความแสดงข้อผิดพลาดนี้ส่งผลให้การปฏิเสธเซสชันเพื่อเข้าถึงฐานข้อมูลที่พยายามเปลี่ยนเป็นสถานะอื่น (ในกรณีนี้สถานะออนไลน์ เป็นการเปลี่ยนแบบออฟไลน์)

คุณควรทำอย่างไรในครั้งต่อไป

ปิดแรกไม่ต้องตกใจและไม่ได้เริ่มต้นลดลงฐานข้อมูล คุณต้องใช้วิธีการแก้ไขปัญหา (พร้อมแบบสอบถามการวินิจฉัยที่คล้ายกันเช่นด้านบน) เพื่อค้นหาสาเหตุที่คุณเห็นสิ่งที่คุณเห็น ด้วยข้อความเช่นนั้นหรือเมื่อสิ่งที่ปรากฏว่า "หยุด" คุณควรถือว่าไม่มีการทำงานพร้อมกันโดยอัตโนมัติและเริ่มขุดลงในการบล็อก ( sys.dm_tran_locksเป็นการเริ่มต้นที่ดี)

ในฐานะที่เป็นหมายเหตุด้านข้างฉันเชื่ออย่างแท้จริงว่าคุณเป็นผู้ที่ดีที่สุดในการค้นหาสาเหตุของปัญหาก่อนที่จะดำเนินการใด ๆ แบบสุ่ม ไม่เพียงแค่ใช้การดำเนินการนี้เท่านั้น แต่ยังรวมถึงพฤติกรรมทุกอย่างที่คุณไม่คาดคิด รู้ว่าสิ่งที่ได้รับจริงๆสาเหตุของปัญหาของคุณก็เห็นได้ชัดจริงๆมันไม่ใช่เรื่องใหญ่ โดยพื้นฐานแล้วคุณมีสายการบล็อกและตัวบล็อกหลักเป็นสิ่งที่คุณน่าจะเพิ่งเปิดตัวKILLหรือเป็นคำขอของเซสชันที่คุณไม่ต้องการให้KILLรอจนกว่ามันจะเสร็จสิ้น ไม่ว่าจะด้วยวิธีใดคุณจะมีความรู้ในการตัดสินใจที่ถูกต้องและรอบคอบในสถานการณ์เฉพาะของคุณ (ย้อนกลับหรือรอการคอมมิชชัน)

อีกสิ่งหนึ่งที่ควรค่าแก่การสังเกตนี่เป็นหนึ่งในเหตุผลที่ฉันเลือกใช้ T-SQL ทางเลือกแทน GUI คุณรู้แน่ชัดว่าคุณกำลังทำอะไรกับ T-SQL และ SQL Server กำลังทำอะไรอยู่ ท้ายที่สุดคุณออกคำสั่งอย่างชัดเจน เมื่อคุณใช้ GUI T-SQL จริงจะเป็นนามธรรม ในกรณีนี้ผมมองไปที่วัตถุที่ถูกปิดกั้นความพยายาม Explorer ALTER DATABASE <YourDatabase> SET OFFLINEเพื่อใช้ฐานข้อมูลแบบออฟไลน์และมันก็เป็น ไม่มีความพยายามที่จะย้อนกลับซึ่งเป็นเหตุผลที่มันรออย่างไม่มีกำหนด ในกรณีของคุณถ้าคุณต้องการย้อนกลับเซสชันที่มีการล็อกในฐานข้อมูลนั้นคุณALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATEน่าจะพอเพียงถ้าคุณได้กำหนดเริ่มต้นว่าการย้อนกลับไม่เป็นไร


4

เพียงปิด Studio จัดการเซิร์ฟเวอร์ SQL (SSMS) และเปิดใหม่อีกครั้งแก้ไขปัญหาให้ฉัน


0

ไม่จำเป็นต้องทำอะไรเพียงแค่ฆ่ากระบวนการSqLWB.exeจาก Task Manager เปิด SQL Server คลิกขวาที่ฐานข้อมูลและออฟไลน์ หากไม่ได้ผลหลังจากเซสชันถูกฆ่าให้พิมพ์คำสั่ง

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

และจากนั้นออฟไลน์ มันจะทำงานได้ดีเหมือนกันกับฉันเช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.