ในอดีตนิยมใช้ SQL Profiler ในการตรวจสอบการทำงานของ Database แต่เนื่องจากข้อจำกัดด้าน Performance (High Overhead) และความยืดหยุ่น ปัจจุบัน Microsoft แนะนำให้ใช้งาน Extended Events (XEvents) ซึ่งเป็นสถาปัตยกรรม Lightweight Tracing System ที่ฝังอยู่ใน SQLOS โดยตรง
บทเรียนนี้จะอธิบายโครงสร้างพื้นฐานของ Extended Events และเปรียบเทียบกับเครื่องมือรุ่นเก่า
- ระดับ 1 – เข้าใจ Architecture ของ XEvents
- อธิบายความแตกต่าง Profiler vs XEvents, Components หลัก (Event/Action/Predicate/Target/Session) ได้
- ระดับ 2 – สร้าง Session พื้นฐานได้
- สร้าง XEvent Session เพื่อจับ Long-running Queries, Errors, Deadlocks, Wait Info ลง Ring Buffer หรือ File ตาม Scenario
- ระดับ 3 – ใช้ XEvents ในการแก้ปัญหาจริง
- อ่าน/แปลไฟล์
.xel, ใช้ XEvent Profiler/SSMS UI และ DMV (sys.dm_xe_sessions,sys.dm_xe_session_targets) เพื่อติดตามเหตุการณ์ในระบบได้อย่างปลอดภัย
- อ่าน/แปลไฟล์
- ระดับ 4 – ออกแบบ Tracing Strategy ตามแนวทาง Microsoft
- วางแผน Session ระยะยาว/เฉพาะกิจให้สอดคล้องกับ Best Practices ด้าน Monitoring & Tracing ที่อ้างถึงใน Performance Center และ Monitoring Guides (ลด Overhead, เน้น Early Filtering)
Extended Events (XEvents) คือ Framework สำหรับ Tracing และ Debugging ใน SQL Server ที่ออกแบบมาให้มี Overhead ต่ำกว่า SQL Trace/Profiler แบบเดิม
ทำไมต้องเปลี่ยนจาก Profiler? Profiler เป็น Synchronous และมี Overhead สูง (อาจถึง 30%) ในขณะที่ XEvents เป็น Asynchronous และมี Overhead ต่ำมาก (<1%)
เปรียบเทียบสถาปัตยกรรม:
| Feature | SQL Trace/Profiler | Extended Events |
|---|---|---|
| Overhead | สูง (Synchronous) | ต่ำ (Asynchronous) |
| Filtering | หลังเก็บข้อมูล | ก่อนเก็บ (Early Filtering) |
| Target Types | Trace File เท่านั้น | หลากหลาย (Ring Buffer, File, Histogram) |
| Status | Deprecated | Recommended |
XE Engine ประกอบด้วยองค์ประกอบหลักดังนี้:
- Packages: คอนเทนเนอร์สำหรับเก็บ Metadata ของ Events (เช่น
package0สำหรับ System Objects,sqlserverสำหรับ Database Engine) - Events: จุดตรวจสอบ (Instrumentation Points) ที่น่าสนใจภายใน Code ของ SQL Server (เช่น
lock_acquired,sql_statement_completed) - Predicates: เงื่อนไขการกรอง (Filters) ที่ทำงานในระดับ Engine ก่อน การเก็บข้อมูล (Early Filtering) -> ช่วยลด Overhead ได้อย่างมหาศาล
- Actions: ข้อมูลเสริม (Global Fields) ที่ต้องการเก็บเพิ่มเติม (เช่น
sql_text,plan_handle) Note: มี Cost ในการประมวลผลเพิ่ม - Targets: ปลายทางสำหรับการจัดเก็บข้อมูล (Consumers)
- Sessions: การกำหนดค่า (Configuration) เพื่อเชื่อมโยง Events, Predicates, และ Targets เข้าด้วยกัน
| Package | Description | Common Events |
|---|---|---|
package0 |
Core system objects | Types, Maps, Actions |
sqlserver |
Database Engine events | sql_statement_completed, rpc_completed, error_reported |
sqlos |
SQL OS / Scheduling | wait_info, scheduler_monitor_* |
sqlclr |
CLR Integration | CLR-related events |
SecAudit |
Security Audit | Audit events |
XtpCompile |
In-Memory OLTP | Hekaton compilation events |
QueryExecution |
Query Processing | Plan-related events |
| Event | Purpose | Use Case |
|---|---|---|
sql_statement_completed |
Query execution finished | Query performance analysis |
rpc_completed |
Stored procedure call finished | SP performance analysis |
lock_acquired / lock_deadlock |
Locking events | Blocking/Deadlock analysis |
sql_statement_recompile |
Plan recompilation | Recompile troubleshooting |
wait_info |
Wait statistics | Real-time wait analysis |
error_reported |
Error occurred | Error monitoring |
query_post_execution_showplan |
Actual execution plan | Plan capture (High overhead!) |
Warning
High-Overhead Events:
query_post_execution_showplan- ดึง Actual Plan ทุก Query (ใช้กับ Production อย่างระวัง!)- ใช้
query_plan_profile(SQL 2019+) ที่มี Lightweight Query Profiling แทน
- Types: ประเภทข้อมูลของ Field (เช่น int32, unicode_string)
- Maps: การแปลงค่ารหัสตัวเลขภายใน (Internal ID) ให้เป็นข้อความที่มนุษย์อ่านเข้าใจ (Description) เช่น แปลง
WaitType=120เป็นชื่อ Wait Type
-
The Dispatcher:
- หัวใจสำคัญของความ Lightweight คือ Dispatcher
- Mechanism: เมื่อ Event เกิดขึ้น Thread ที่รัน Query จะแค่ "เขียนข้อมูลลง Memory Buffer" (เร็วมาก) แล้วกลับไปทำงานต่อทันที
- Background Thread: จะมี Dispatcher Thread ภายใน Engine คอยตื่นมาดึงข้อมูลจาก Buffer ไปเขียนลง Target (File/Ring Buffer) ในภายหลัง
- Result: User Transaction ไม่ต้องรอ I/O (Asynchronous)
-
Event Loss Policy:
- เนื่องจาก XEvent ทำงานแบบ Async จึงมีโอกาสที่ Buffer เต็มแล้วเขียนไม่ทัน เราต้องเลือก Policy:
- Single Event Loss: Buffer เต็มให้ทิ้ง Event (Default, ปลอดภัยสุด)
- Multiple Event Loss: ทิ้งทั้ง Buffer
- No Event Loss: บังคับให้ User Thread รอ (Blocking) จนกว่า Buffer จะว่าง -> อันตราย! อาจทำให้ระบบช้าลงเหมือน SQL Trace
- เนื่องจาก XEvent ทำงานแบบ Async จึงมีโอกาสที่ Buffer เต็มแล้วเขียนไม่ทัน เราต้องเลือก Policy:
-
Global State Data:
- Actions (เช่น
sql_text,username) เป็นการดึงข้อมูล Global State ซึ่งอาจมี Cost สูงกว่าการเก็บ Payload ปกติ ควรเลือกใช้เท่าที่จำเป็น
- Actions (เช่น
stateDiagram-v2
CodePoint --> Event: Trigger Event
Event --> Predicate: Filter? (Early Filtering)
Predicate --> Action: Collect Payload (If True)
Action --> Buffer: Buffer in Memory
Buffer --> Target: Dispatch Asynchronously
Target --> File: .xel
Target --> RingBuffer: Memory
- Event File (.xel): บันทึกลง Disk (Asynchronous) เหมาะสำหรับการเก็บข้อมูลระยะยาว (Long-term retention) หรือปริมาณมาก
- Ring Buffer: บันทึกลง Memory แบบ FIFO (First-In, First-Out) เหมาะสำหรับการตรวจสอบเบื้องต้น (Ad-hoc monitoring) ข้อควรระวัง: ข้อมูลอาจสูญหายได้ง่าย
- Histogram (Bucketing): การจัดกลุ่มและนับจำนวนเหตุการณ์ใน Memory (Aggregation) เช่น การนับจำนวน Deadlock แยกตาม Database
- Event Pairing: การจับคู่ Event เริ่มต้นและสิ้นสุดเพื่อค้นหา Incomplete Transactions
Default Session ที่รันอยู่ตลอดเวลา (Always-on) เพื่อบันทึกข้อมูลสุขภาพของระบบที่สำคัญ:
- Deadlocks: บันทึก Deadlock Graph output
- Severe Errors: บันทึก Error ที่มีความรุนแรง (Severity >= 20)
- Long Waits: การรอทรัพยากรที่นานผิดปกติ (> 15s/30s)
- Memory: ปัญหา Memory Allocation Failures
- Execution Time-outs: ตรวจสอบโดยจับคู่
sql_statement_startingและcompletedหรือใช้rpc_completedที่มีresult = 2(Abort) - Errors: จับ Event
error_reportedเพื่อตรวจสอบ Error ที่อาจถูกละเลยโดย Application (Swallowed Errors) - Recompilations: จับ
sql_statement_recompileร่วมกับ Histogram เพื่อระบุ Object ที่เกิด Recompile บ่อยที่สุด
เครื่องมือและฟีเจอร์ใหม่ที่เพิ่มความสะดวกในการใช้งาน
เครื่องมือที่ผสานประสบการณ์ผู้ใช้ (UX) ของ SQL Profiler เข้ากับประสิทธิภาพของ Extended Events
- Usage: SSMS -> Object Explorer -> XE Profiler -> Standard
- Benefit: สามารถดูข้อมูลแบบ Live Stream (Live Watch) ได้โดยมี Overhead ต่ำ
โครงสร้างพื้นฐานใหม่สำหรับการติดตาม Query Execution
- Legacy: Event
query_post_execution_showplanมีผลกระทบต่อประสิทธิภาพสูง (High Performance Overhead) - Modern: Event
query_thread_profileใช้งาน Infrastructure ใหม่ที่มีความเบา (Lightweight) - Live Query Stats: ช่วยให้สามารถดูความคืบหน้าของ Query ได้แบบ Real-time (เป็น Default ใน SQL Server 2019+)
บน Cloud เราไม่มี Local Drive ให้เขียนไฟล์ .xel
- Target: ต้องเขียนลง Azure Blob Storage แทน
- Analysis: โหลดไฟล์ .xel จาก Blob มาเปิดใน SSMS เครื่องเราได้เลย
ในแล็บนี้ คุณจะกำหนดค่า XEvent session เพื่อจับ Wait Stats และ Deadlocks จากนั้นวิเคราะห์ผลลัพธ์