หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
นําไปใช้กับ:✅ Warehouse ใน Microsoft Fabric
หากคิวรีของคุณในคลังสินค้าใช้เวลานานผิดปกติหรือดูเหมือนจะค้าง การล็อกเกิดขึ้นเมื่อเซสชันระงับการล็อกที่ป้องกันไม่ให้คิวรีอื่น ๆ ดําเนินการต่อ
บทความนี้แสดงวิธีตรวจสอบว่าการล็อกส่งผลต่อปริมาณงานของคุณหรือไม่ และการดําเนินการที่คุณสามารถทําได้
Tip
คลังสินค้าใช้การล็อกระดับตาราง การดําเนินการ DML ใด ๆ จะได้รับล็อคบนตารางทั้งหมดโดยไม่คํานึงถึงจํานวนแถวที่ได้รับผลกระทบ ลักษณะการทํางานนี้แตกต่างจาก SQL Server ซึ่งสนับสนุนการล็อกระดับแถวและระดับหน้า
ข้อกำหนดเบื้องต้น
- คลังสินค้าที่มีปริมาณงานที่ใช้งานอยู่
- การเป็นสมาชิกในบทบาทพื้นที่ทํางาน ผู้ชม คือสิทธิ์ขั้นต่ําในการสืบค้นมุมมองการจัดการแบบไดนามิก (DMV) ในบทความนี้
- สําหรับข้อมูลเพิ่มเติมเกี่ยวกับการแก้ไขปัญหาด้วย DMV โปรดดู ตรวจสอบการเชื่อมต่อ เซสชัน และคําขอโดยใช้ DMV
ขั้นตอนที่ 1: ตรวจสอบว่าคิวรีกําลังรอการล็อกอยู่หรือไม่
เริ่มต้นด้วยการตรวจสอบว่ามีคิวรีใดที่กําลังรอการล็อกอยู่หรือไม่
เรียกใช้คิวรีต่อไปนี้:
SELECT
request_session_id,
resource_type,
resource_description,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE request_status = 'WAIT';
ถ้าคิวรีส่งคืนแถว บางเซสชันกําลังรอทรัพยากรที่เซสชันอื่นถือครอง แต่ละแถวระบุคําขอล็อกที่ไม่สามารถให้ได้ในขณะนี้
Tip
มุมมองสามารถ sys.dm_tran_locks ส่งคืนแถวจํานวนมากสําหรับการล็อกที่ได้รับ การกรองตาม request_status = 'WAIT' จะมุ่งเน้นไปที่เซสชันที่ถูกบล็อก
ขั้นตอนที่ 2: ระบุคิวรีที่ถูกบล็อก
ถัดไป ให้ตรวจสอบว่าคิวรีใดถูกบล็อกและเซสชันใดที่บล็อก
SELECT
session_id,
status,
blocking_session_id,
wait_type,
total_elapsed_time,
open_transaction_count
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;
คิวรีนี้ส่งกลับ:
- เซสชันที่เรียกใช้แบบสอบถามที่ถูกบล็อก (
session_id) - เซสชันที่บล็อกอยู่ในขณะนี้ (
blocking_session_id) - รอนานแค่ไหน (
total_elapsed_timeเป็นมิลลิวินาที) - เซสชันการบล็อกมีธุรกรรมที่เปิดอยู่หรือไม่ (
open_transaction_count)
ถ้าคิวรีแสดง blocking_session_id ว่าไม่ใช่ศูนย์ และ open_transaction_count > 0กําลังรอเซสชันอื่นที่ล็อกไว้
ขั้นตอนที่ 3: ค้นหาเซสชันการบล็อก
หากต้องการทําความเข้าใจว่าทรัพยากรใดถูกล็อก ให้ตรวจสอบการล็อกที่เซสชันการบล็อกถือครองอยู่ในปัจจุบัน แทนที่ a session_id ที่คุณระบุไว้ก่อนหน้านี้สําหรับ <blocking_session_id> คิวรีตัวอย่างต่อไปนี้:
SELECT
request_session_id,
resource_type,
resource_associated_entity_id,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE
request_status = 'GRANT'
AND request_session_id = <blocking_session_id>;
ใช้คิวรีนี้เพื่อกําหนด:
- ทรัพยากรใดที่เซสชันการบล็อกเก็บไว้ล็อกอยู่ในปัจจุบัน ตัวอย่างเช่น คุณสามารถใช้
sys.objectsเพื่อระบุresource_associated_entity_idตําแหน่งที่ไฟล์resource_type = OBJECT. - โหมดล็อค (เช่น ample, Exclusive (
X), Schema-Modification (Sch-M)) - ไม่ว่าการล็อกจะเกี่ยวข้องกับการดําเนินการ DDL หรือการอัพเดตสถิติ (
UPDSTATS)
Note
การล็อกที่เกี่ยวข้องกับสถิติ (เช่น จาก UPDSTATS) ยังปรากฏใน sys.dm_tran_locks. ล็อค Schema-Modification (Sch-M) และ Exclusive (X) เป็นตัวบล็อกที่พบบ่อยที่สุด แต่การล็อกประเภทใดก็ตามสามารถบล็อกคําขอที่ขัดแย้งกันได้ (เช่น บล็อก Sch-MSch-S )
ขั้นตอนที่ 4: ค้นหาเจ้าของธุรกรรมที่บล็อก
ในหลายกรณี คุณอาจต้องการขอให้เจ้าของธุรกรรม COMMIT การบล็อกหรือ ROLLBACK งานของพวกเขาแทนที่จะยุติเซสชัน พิจารณาใช้TRYCATCHโครงสร้างสําหรับการจัดการข้อผิดพลาดกับ หรือROLLBACKCOMMIT สําหรับข้อมูลเพิ่มเติม โปรดดู ลอง... จับ.
คุณสามารถระบุเจ้าของและคําค้นหาที่เกี่ยวข้องกับเซสชันการบล็อกได้ แทนที่ a session_id ที่คุณระบุไว้ก่อนหน้านี้สําหรับ <blocking_session_id> คิวรีตัวอย่างต่อไปนี้:
SELECT
r.session_id,
s.login_name,
s.program_name,
r.status,
r.blocking_session_id,
r.command,
r.total_elapsed_time,
s.last_request_start_time,
s.last_request_end_time
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s
ON r.session_id = s.session_id
WHERE r.session_id = <blocking_session_id>;
-
login_nameเป็นเจ้าของเซสชันการบล็อก -
program_nameคือแอปพลิเคชันที่เริ่มต้นเซสชัน ค่าระบุDMS_userตัวแก้ไขคิวรีพอร์ทัล Fabric -
commandคือคําสั่งที่กําลังรันอยู่
จากนั้นคุณสามารถติดต่อเจ้าของธุรกรรมเพื่อยอมรับหรือย้อนกลับได้ตามความเหมาะสม
ขั้นตอนที่ 5: ตรวจสอบว่าเซสชันการบล็อกไม่ได้ใช้งานหรือไม่คืบหน้าหรือไม่
เซสชันการบล็อกอาจดูเหมือนใช้งานอยู่ แต่ไม่มีความคืบหน้าจริง
ตัวบ่งชี้ของเซสชันที่ไม่ได้ใช้งานหรือหยุดชะงัก ได้แก่ :
-
status = 'sleeping'บ่งชี้ว่าไม่มีคิวรีที่ใช้งานอยู่ - มองหาคําขอ
last_request_start_timeที่เร็วกว่าเวลาปัจจุบันอย่างมีนัยสําคัญ ซึ่งบ่งชี้ว่าคําขอที่เปิดอยู่มีอายุการใช้งานยาวนาน - มองหาค่า
total_elapsed_timeที่ไม่เพิ่มขึ้นระหว่างการตรวจสอบ ซึ่งบ่งชี้ว่าเซสชันหยุดชะงัก
SELECT
session_id,
status,
last_request_start_time,
last_request_end_time,
open_transaction_count
FROM sys.dm_exec_sessions
WHERE session_id = <blocking_session_id>;
- ถ้าสถานะเซสชันเป็น
sleepingและopen_transaction_count > 0เซสชันมีธุรกรรมที่เปิดอยู่โดยไม่มีคิวรีที่ใช้งานอยู่ - เซสชันจะล็อกไว้โดยไม่ต้องทํางาน - หากเซสชันปรากฏและ
sys.dm_exec_requeststotal_elapsed_timeยังคงเพิ่มขึ้นระหว่างการตรวจสอบ แสดงว่าเซสชันกําลังดําเนินไปอย่างแข็งขัน อาจเป็นการดีกว่าที่จะรอให้ธุรกรรมเสร็จสมบูรณ์แทนที่จะยุติและบังคับให้ย้อนกลับ
ขั้นตอนที่ 6: ดําเนินการเพื่อแก้ไขการบล็อก
Note
สถานการณ์การบล็อกมักจะแก้ไขได้เองเมื่อเซสชันการบล็อกเสร็จสิ้นการทําธุรกรรม หากปริมาณงานของคุณสามารถทนต่อความล่าช้าได้
ถ้าคุณต้องการยกเลิกการบล็อกคิวรีดาวน์สตรีม ให้พิจารณาว่าเซสชันการบล็อกมีลักษณะดังต่อไปนี้หรือไม่:
- มีธุรกรรมที่เปิดอยู่
- ดูเหมือนไม่ได้ใช้งานหรือไม่คืบหน้า
- กําลังล็อคการปิดกั้น (เช่น Exclusive (
X) หรือSch-M)
ถ้าเป็นเช่นนั้น สมาชิกของบทบาทพื้นที่ทํางานผู้ดูแลระบบสามารถยุติเซสชันได้โดยใช้:
KILL <session_id>;
KILLคําสั่งจะ:
- จบเซสชัน
- ย้อนกลับงานทั้งหมดที่ทําในธุรกรรมที่ใช้งานอยู่ของเซสชันนั้น
- ปลดล็อค
- อนุญาตให้คิวรีดาวน์สตรีมดําเนินการต่อ
ความระมัดระวัง
การฆ่าเซสชันจะย้อนกลับงานที่ไม่ได้ผูกมัดทั้งหมดที่ดําเนินการโดยเซสชันนั้น การดําเนินการนี้อาจเลิกทําการเปลี่ยนแปลงข้อมูลที่ทําโดยผู้ใช้หรือแอปพลิเคชัน ใช้ตัวเลือกนี้เฉพาะเมื่อคุณแน่ใจว่าการยกเลิกธุรกรรมจะไม่ส่งผลเสียต่อปริมาณงานของคุณ
ขั้นตอนที่ 7: ป้องกันปัญหาการล็อกในอนาคต
เพื่อช่วยป้องกันปัญหาที่คล้ายกัน:
- หลีกเลี่ยงการเปิดธุรกรรมที่ชัดเจน (
BEGIN TRANSACTIONโดยไม่มี หรือROLLBACK) ที่สอดคล้องกันCOMMIT - ทําให้ธุรกรรมมีอายุสั้น ดําเนินการเฉพาะการดําเนินการที่จําเป็นภายในธุรกรรม
- เสมอ
COMMITหรือROLLBACKธุรกรรมเมื่อเสร็จสมบูรณ์ - กําหนดเวลาการดําเนินการ DDL (เช่น
ALTER TABLE) ในช่วงที่มีการจราจรน้อย
ตรวจสอบธุรกรรมที่เปิดอยู่ในเชิงรุกโดยใช้:
SELECT
session_id,
login_name,
open_transaction_count,
program_name,
status,
blocking_session_id,
last_request_start_time
FROM sys.dm_exec_sessions
WHERE open_transaction_count > 0;
การตรวจสอบธุรกรรมที่เปิดอยู่อย่างสม่ําเสมอและการแทรกแซงตามความเหมาะสมจะช่วยลดโอกาสในการก่อตัวของเชนการบล็อก