แก้ไขปัญหาการบล็อกคิวรีใน Fabric คลังข้อมูล

นําไปใช้กับ:✅ Warehouse ใน Microsoft Fabric

หากคิวรีของคุณในคลังสินค้าใช้เวลานานผิดปกติหรือดูเหมือนจะค้าง การล็อกเกิดขึ้นเมื่อเซสชันระงับการล็อกที่ป้องกันไม่ให้คิวรีอื่น ๆ ดําเนินการต่อ

บทความนี้แสดงวิธีตรวจสอบว่าการล็อกส่งผลต่อปริมาณงานของคุณหรือไม่ และการดําเนินการที่คุณสามารถทําได้

Tip

คลังสินค้าใช้การล็อกระดับตาราง การดําเนินการ DML ใด ๆ จะได้รับล็อคบนตารางทั้งหมดโดยไม่คํานึงถึงจํานวนแถวที่ได้รับผลกระทบ ลักษณะการทํางานนี้แตกต่างจาก SQL Server ซึ่งสนับสนุนการล็อกระดับแถวและระดับหน้า

ข้อกำหนดเบื้องต้น

  • คลังสินค้าที่มีปริมาณงานที่ใช้งานอยู่
  • การเป็นสมาชิกในบทบาทพื้นที่ทํางาน ผู้ชม คือสิทธิ์ขั้นต่ําในการสืบค้นมุมมองการจัดการแบบไดนามิก (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;

การตรวจสอบธุรกรรมที่เปิดอยู่อย่างสม่ําเสมอและการแทรกแซงตามความเหมาะสมจะช่วยลดโอกาสในการก่อตัวของเชนการบล็อก