คู่มือเกมแลค › L12 ฐานข้อมูล
งาน batch ขนาดใหญ่ Batch jobs during service
ID สาเหตุ db-batch · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้ารันการสรุปอันดับ, การส่งจดหมายในเกมแบบรวดเดียว หรือการล้างข้อมูลเก่าระหว่างให้บริการ งานเหล่านี้จะยึดล็อกและดิสก์ไว้
ทำไม รันงานขนาดใหญ่ในช่วงเวลาให้บริการ → ผลคือ ล็อกเป็นช่วงกว้าง, ถือครองดิสก์และ CPU → บนหน้าจอ เทรดและเซฟล้มเหลวในบางช่วงเวลา, โหลดช้า
- อาการ
- อินพุตดีเลย์, กดไม่ติด/โรลแบ็ค
- ปัจจัย
- ความหน่วง, การหยุดชะงัก
- ใครเจอ
- เฉพาะบางฟีเจอร์, ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- เป็นรอบสม่ำเสมอ
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)
- งานฝั่งทีมพัฒนาเกม
- แบ่งเป็นชุดเล็ก ๆ ทำทีละน้อย, สรุปผลบน replica
- งานฝั่งทีมอินฟรา
- จัด replica สำหรับงานสรุปผล, ตั้งเวลา batch ไว้ช่วงที่ว่าง, เฝ้าดู lock escalation และการรอ gap lock
- บนกราฟ
- พุ่งเป็นรอบ · ดีเลย์ของคิวรี DB, การรอล็อก
- จุดที่ต้องดู
- หาคิวรียาวที่รันอยู่ในช่วงที่แลค MySQL ดู slow query log ส่วน PostgreSQL ดู query_start และ query ใน pg_stat_activity แล้วเทียบกับเมตริกการรอล็อกในช่วงเดียวกันและตารางเวลา batch (cron, event scheduler ของ DB) SQL Server บันทึก lock escalation ด้วย extended event lock_escalation
- สัญญาณว่าใช่
- คิวรี UPDATE, DELETE หรือสรุปผลขนาดใหญ่รันเวลาเดิมทุกครั้ง และระหว่างนั้นการรอล็อกกับอัตราการใช้งานดิสก์สูงขึ้นพร้อมกัน
- สัญญาณว่าไม่ใช่
- ช่วงนั้นไม่มีคิวรียาว: น่าจะเป็น checkpoint (db-checkpoint) หรือการสำรองข้อมูลของเซิร์ฟเวอร์ (dk-backup)
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- SQL Server จะเปลี่ยนเป็นล็อกทั้งตารางเมื่อคำสั่งเดียวถือ row lock เกินประมาณ 5,000 ตัว (lock escalation) ทันทีนั้นทุกคำขอที่ใช้ตารางเดียวกันจะหยุด MySQL ก็เช่นกัน ด้วยการตั้งค่าเริ่มต้น ถ้าแก้ข้อมูลด้วยเงื่อนไขแบบช่วง จะล็อกไปถึงช่องว่างระหว่างแถว (gap lock) ทำให้เพิ่มแถวใหม่ไม่ได้
แหล่งอ้างอิง
- Transaction Locking and Row Versioning Guide Microsoft SQL Server
ถ้าคำสั่งเดียวถือล็อกบนตาราง (หรืออินเด็กซ์) เดียวตั้งแต่ 5,000 ตัวขึ้นไปจะเกิด lock escalation, บันทึกได้ด้วย extended event lock_escalation - InnoDB Locking MySQL
ที่ระดับ isolation เริ่มต้นของ InnoDB คือ REPEATABLE READ การค้นและการสแกนใช้ next-key lock ทำให้ gap lock ขวางการเพิ่มแถวใหม่ในช่องว่างนั้น - The Slow Query Log MySQL
บันทึกคิวรีที่เกิน long_query_time พร้อมเวลารัน (Query_time), เวลาล็อก (Lock_time) และจำนวนแถวที่อ่าน - The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
pg_stat_activity: คิวรีที่กำลังรันอยู่ (query) และเวลาที่เริ่ม (query_start) ของแต่ละเซสชัน
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L12 ฐานข้อมูล
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (อินพุตดีเลย์)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง