Repro
- เปิด SSMS
พิมพ์ข้อความต่อไปนี้ลงในหน้าต่างแบบสอบถามใหม่
use <YourDatabase>;
go
- ไปที่ Object Explorer (SSMS) แล้วคลิกขวาที่
<YourDatabase>
-> Tasks
->Take Offline
เปิดหน้าต่างแบบสอบถามใหม่ที่สองและพิมพ์ข้อความต่อไปนี้:
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
น่าจะพอเพียงถ้าคุณได้กำหนดเริ่มต้นว่าการย้อนกลับไม่เป็นไร