PlusMagi's Blog By Pitt Phunsanit Database SQL Server: สคริปต์ตรวจสอบการ Lock

SQL Server: สคริปต์ตรวจสอบการ Lock

ในฐานะ System Architect การจัดการ Transaction และการทำความเข้าใจเรื่อง Lock เป็นหัวใจสำคัญของการออกแบบระบบฐานข้อมูลที่เสถียร เมื่อระบบเกิดปัญหาความล่าช้า (Slowness) หรือการหยุดชะงัก (Deadlock) สาเหตุหลักมักมาจาก ‘การจองทรัพยากร’ (Locking) ที่ไม่เหมาะสม บทความนี้จะนำเสนอแนวทางและสคริปต์ที่ทรงประสิทธิภาพสำหรับ PostgreSQL เพื่อตรวจสอบว่ามี Session ใดกำลังถือ Lock อยู่ และ Lock นั้นส่งผลกระทบต่อการทำงานของระบบอย่างไร

💡 Lock คืออะไร และทำไมต้องตรวจสอบ?

Lock คือกลไกที่ฐานข้อมูลใช้เพื่อรับประกันความสมบูรณ์ของข้อมูล (Data Integrity) เมื่อ Transaction หนึ่งกำลังอ่านหรือแก้ไขข้อมูล ระบบจะทำการ ‘จอง’ ส่วนของข้อมูลนั้นไว้ชั่วคราว เพื่อป้องกันไม่ให้ Transaction อื่นเข้ามาแก้ไขข้อมูลพร้อมกัน ซึ่งหากการจองนี้ถูกปล่อยทิ้งไว้เป็นเวลานาน หรือเกิดการจองแบบวงจร (Deadlock) ก็จะทำให้ระบบทั้งหมดหยุดชะงักได้

ใน PostgreSQL เราสามารถใช้ View และ Function เฉพาะทางเพื่อดึงข้อมูลสถานะการล็อกทั้งหมดได้ โดยเฉพาะการตรวจสอบว่ามี Session ใดกำลัง ‘บล็อก’ (Blocking) Session อื่นอยู่หรือไม่

💻 PostgreSQL Script: ตรวจสอบสถานะการ Lock และ Deadlock

สคริปต์นี้จะดึงข้อมูลสำคัญ 3 ส่วน คือ 1) Session ที่กำลังทำงาน 2) Lock ที่ถูกจอง และ 3) Session ที่กำลังถูกบล็อก

SQL

SELECT
    a.pid AS Session_PID, -- Process ID ของ Session ที่กำลังทำงาน
    a.query AS Current_Query, -- คำสั่ง SQL ที่กำลังรัน
    l.mode AS Lock_Mode, -- ระดับการล็อก (เช่น Share, Exclusive)
    l.granted AS Is_Granted, -- สถานะ: t=ได้ Lock แล้ว, f=กำลังรอ Lock
    c.relname AS Table_Name, -- ชื่อตารางที่ถูกล็อก
    pg_blocking_paddr(l.relation) AS Blocking_PID -- PID ของ Session ที่เป็นผู้บล็อก
FROM pg_locks l
JOIN pg_stat_activity a ON l.pid = a.pid
JOIN pg_class c ON l.relation = c.oid
WHERE l.granted = FALSE AND l.relation IS NOT NULL
ORDER BY Blocking_PID, a.pid;

🔍 วิธีการวิเคราะห์ผลลัพธ์ (Analysis)

เมื่อรันสคริปต์นี้แล้ว ให้สังเกตคอลัมน์หลัก ๆ ดังนี้:

  • Session_PID: คือ Process ID ของ Session ที่กำลังมีปัญหา (โดยเฉพาะ Session ที่มี Is_Granted = 'f')
  • Lock_Mode: บอกระดับการจอง เช่น 'ExclusiveLock' (X) หมายถึงมีการจองแบบแก้ไขอย่างเบ็ดเสร็จ
  • Is_Granted: หากค่าเป็น 'f' (False) หมายความว่า Session นี้กำลัง ‘รอ’ Lock จาก Session อื่นอยู่ ซึ่งเป็นจุดที่เกิดปัญหาคอขวด
  • Blocking_PID: นี่คือหัวใจสำคัญ! หากคอลัมน์นี้มีค่า PID แสดงว่า Session นั้นกำลังถูก Session ID นี้บล็อกอยู่

✅ สรุปและแนวทางแก้ไขปัญหา (Conclusion)

การพบว่ามี Session ใดกำลังรอ Lock (Is_Granted = 'f') และถูกบล็อกโดย Session อื่น (Blocking_PID มีค่า) คือการยืนยันปัญหาคอขวดอย่างชัดเจน ในฐานะ Senior Architect แนวทางแก้ไขที่ดีที่สุดไม่ใช่การฆ่า Session ทันที แต่คือการปรับปรุง Transaction:

  1. ลดระยะเวลา Transaction: ทำให้ Transaction สั้นที่สุดเท่าที่จะทำได้
  2. จัดลำดับ Lock: กำหนดให้ทุก Transaction เข้าถึงและล็อกทรัพยากร (Table) ตามลำดับที่กำหนดไว้เสมอ เพื่อป้องกัน Deadlock วงจร
  3. ใช้ Isolation Level ที่เหมาะสม: พิจารณาการใช้ระดับ Isolation ที่จำเป็นเท่านั้น (เช่น ไม่จำเป็นต้องใช้ Serializable หาก Read Committed ก็เพียงพอ)

การทำความเข้าใจกลไกการล็อกอย่างลึกซึ้งจะช่วยให้คุณสามารถออกแบบโค้ดและกระบวนการทางธุรกิจให้ทำงานร่วมกับฐานข้อมูลได้อย่างราบรื่นและเสถียรที่สุด

Exit mobile version