มนตร์วิเศษของ WAL: ทำไม Database ไม่เซฟข้อมูลลงตารางตรงๆ แต่เลือกจดไดอารีก่อนเสมอ?
⏱️ ใช้เวลาอ่านประมาณ: 4 นาที 20 วินาที
เมื่อคุณสั่ง INSERT INTO users VALUES ('Somchai') แล้วฐานข้อมูลตอบกลับมาว่า "Success (Commit OK)" ภายในเวลา 1 มิลลิวินาที
คุณอาจคิดว่าชื่อ 'Somchai' ถูกเขียนลงไปในตารางบนฮาร์ดดิสก์เรียบร้อยแล้วใช่ไหมครับ?
ความจริงที่ชวนช็อกคือ ข้อมูลยังไม่ได้ถูกเขียนลงไฟล์ตารางจริงเลยแม้แต่นิดเดียว! มันแค่ลอยค้างอยู่บน RAM ด้วยซ้ำ... แล้วถ้าไฟดับทันทีตอนนั้น ทำไมเปิดเครื่องใหม่ข้อมูลถึงไม่เคยหายแม้แต่ตัวเดียว?
🐌 ทำไมการเขียนลงตารางจริงถึง "ช้าชวนหงุดหงิด"?
ตารางในฐานข้อมูล (PostgreSQL, MySQL InnoDB) มีโครงสร้างซับซ้อนมหาศาล มีทั้งหน้าข้อมูล (Data Pages), ดัชนี (B-Tree Indexes), Foreign Keys และข้อจำกัดต่างๆ
ถ้าทุกครั้งที่มีคนกดซื้อของ Database ต้องวิ่งไปหาหน้ากระดาษที่ถูกต้องบนดิสก์ ปรับแต่งกิ่งก้านของ B-Tree 4-5 ตัว แล้วสั่งเขียนลงดิสก์ทันที (Random Disk I/O):
- หัวอ่านดิสก์ต้องวิ่งกระโดดไปมาสลับตำแหน่งหลายจุด
- Throughput ของระบบจะตกฮวบเหลือแค่ไม่กี่ร้อย Transaction ต่อวินาที
- และถ้าไฟดับกลางคันตอนกำลังแก้โครงสร้าง B-Tree ค้างอยู่... ฐานข้อมูลจะพังทั้งก้อนจนกู้ไม่ได้!
📓 สมุดพกของนายช่าง: Write-Ahead Logging (WAL)
เพื่อแก้ปัญหานี้ วิศวกรคอมพิวเตอร์จึงสร้างกฎเหล็กที่ชื่อว่า Write-Ahead Logging (WAL) (ฝั่ง MySQL เรียก Redo Log):
"ก่อนที่แกจะไปจัดเรียงเอกสารเข้าแฟ้มใหญ่ (Table Space) ให้เสียเวลา... จงหยิบสมุดโน้ตเล็กๆ ขึ้นมาจดบรรทัดเดียวสั้นๆ ต่อท้ายแถว (Append-only) ให้เสร็จก่อนเสมอ!"
กระบวนการทำงานที่แท้จริงเบื้องหลังคำว่า COMMIT จึงเปลี่ยนเป็น:
- แก้ข้อมูลใน RAM (Buffer Pool) ทันที (ยังไม่แตะไฟล์ตารางบนดิสก์)
- เขียนบันทึกการกระทำสั้นๆ เช่น "คำสั่งที่ 101: เปลี่ยนยอดเงินแถวที่ 5 เป็น 500" ลงในไฟล์ WAL แบบต่อท้ายแถวตรงๆ (Sequential I/O ซึ่งเร็วทะลุนรก)
- สั่ง
fsync()ให้แน่ใจว่าข้อความในสมุดโน้ต WAL ตกถึงแผ่นดิสก์จริงๆ - ตอบกลับ Client ทันทีว่า: "บันทึกสำเร็จแล้ว!"
🧹 แล้วเมื่อไหร่ข้อมูลถึงจะไปโผล่ในตารางจริง?
หน้าข้อมูลที่ถูกแก้ค้างไว้บน RAM จะถูกเรียกว่า Dirty Pages
Database จะมีพนักงานเบื้องหลังที่ชื่อว่า Checkpointer / Background Writer คอยทำงานแบบชิลๆ: ทยอยกวาด Dirty Pages จากบน RAM ไปจัดเรียงแล้วบันทึกลงไฟล์ตารางจริงทีละชุดใหญ่ๆ (Batching) ในช่วงที่ระบบว่าง
RAM ดับ ข้อมูล Dirty Pages หายเกลี้ยง...
➔ แต่ตอนบูตเครื่องใหม่ Database จะเปิดอ่านสมุดบันทึก WAL
➔ เล่นซ้ำคำสั่งทั้งหมด (Replay / REDO) ตั้งแต่จุด Checkpoint ล่าสุด
➔ ทุกอย่างกลับมาถูกต้องสมบูรณ์ 100% ไม่มีอะไรสูญหาย!
💡 5-Min Takeaway
"ความเร็วและความปลอดภัย ไม่จำเป็นต้องเป็นศัตรูกันเสมอไป" แทนที่จะเสียเวลาไปกับการจัดระเบียบตารางจริงทันทีในทุก Request กลไก WAL ฉลาดพอที่จะเปลี่ยนงานสุ่มเขียนดิสก์ที่เชื่องช้า ให้กลายเป็นการจดบันทึกต่อท้ายแถวด้วยความเร็วสูงสุด การันตีทั้งความทนทาน (Durability ใน ACID) และเปิดทางให้ Database รับโหลดได้หลายหมื่น Transaction ต่อวินาที