คู่มือเกมแลค › L12 ฐานข้อมูล
ล็อกจากการเปลี่ยนสคีมา (DDL) ระหว่างให้บริการ Schema change lock (DDL / metadata lock)
ID สาเหตุ db-ddl-lock · ผู้รับผิดชอบหลัก อินฟรา DB (ทีมอินฟรา) · ร่วมกับ พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าเพิ่มคอลัมน์หรืออินเด็กซ์ให้ตารางระหว่างให้บริการ ล็อกที่ต้องใช้เพียงชั่วครู่ตัวเดียวอาจทำให้ทุกคำขอที่ใช้ตารางนั้นต้องรอ
ทำไม เพิ่มคอลัมน์หรืออินเด็กซ์ให้ตารางที่ใช้งานอยู่ผ่าน hotfix → ผลคือ การเปลี่ยนสคีมารอทรานแซกชันยาวที่เปิดอยู่ก่อน และทุกคำขอที่ตามมาต้องรอการเปลี่ยนสคีมานั้น → บนหน้าจอ ฟีเจอร์ที่ใช้ตารางนั้น (กระเป๋า, จดหมาย ฯลฯ) ค้างทั้งหมดแล้วไทม์เอาต์
- อาการ
- อินพุตดีเลย์, กดไม่ติด/โรลแบ็ค, เข้าเกมไม่ได้/โหลดไม่จบ
- ปัจจัย
- การหยุดชะงัก
- ใครเจอ
- เฉพาะบางฟีเจอร์, ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- สุ่มเป็นครั้งคราว, หลังล็อกอิน/หลังปิดปรับปรุง
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก อินฟรา DB (ทีมอินฟรา) · ร่วมกับ พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
- งานฝั่งทีมพัฒนาเกม
- hotfix ที่มีการเปลี่ยนสคีมาให้นัดเวลากับอินฟรา DB, deploy โค้ดที่ทำงานได้แม้ยังไม่มีคอลัมน์ใหม่ก่อน
- งานฝั่งทีมอินฟรา
- ตั้งขีดจำกัดการรอล็อกให้สั้นแล้วลองใหม่เมื่อล้มเหลว, รันตอนที่ไม่มีทรานแซกชันยาว, ใช้เครื่องมือ online schema change, ตารางใหญ่ให้ทำช่วงปิดปรับปรุง
- บนกราฟ
- ขึ้นเป็นขั้นบันไดจากจุดหนึ่ง · จำนวนเซสชันที่รอล็อก, ดีเลย์ของคิวรีบนตารางนั้น
- จุดที่ต้องดู
- MySQL นับเซสชันที่ State เป็น Waiting for table metadata lock ใน SHOW PROCESSLIST และหาเซสชันที่ขวางอยู่ (blocking_pid) ด้วย sys.schema_table_lock_waits ส่วน PostgreSQL ดูคำขอที่ granted เป็น false และ AccessExclusiveLock ใน pg_locks และหาเซสชันที่ขวางอยู่ด้วย pg_blocking_pids()
- สัญญาณว่าใช่
- ตั้งแต่เวลาที่เริ่มเปลี่ยนสคีมา ทุกคิวรีที่ใช้ตารางนั้นกองรอล็อก และหัวแถวคือทรานแซกชันที่ยังไม่จบหรือคำสั่งเปลี่ยนสคีมา
- สัญญาณว่าไม่ใช่
- การรอกระจุกเฉพาะบางแถว และแถวอื่นในตารางเดียวกันยังประมวลผลได้ดี: น่าจะเป็น hot row (db-hot-row)
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- ตอนเปลี่ยนสคีมา MySQL ถือ metadata lock ส่วน PostgreSQL ถือล็อกตารางที่แรงที่สุดชั่วครู่ แม้ตัวการเปลี่ยนจะเสร็จในพริบตา แต่ถ้ามีทรานแซกชันที่ยังไม่จบอยู่ข้างหน้าแม้แต่ตัวเดียว ทุกคำขอที่ตามมาจะต้องรอ
แหล่งอ้างอิง
- Online DDL Performance and Concurrency MySQL
แม้เป็น online DDL ตอนจบก็ต้องใช้ exclusive metadata lock ชั่วครู่ ถ้ามีทรานแซกชันยาวจะต้องรอ และคำขอล็อกที่รออยู่จะขวางทุกทรานแซกชันที่ตามมา - Server System Variables MySQL
lock_wait_timeout: ขีดจำกัดการรอ metadata lock, ค่าเริ่มต้น 31,536,000 วินาที (1 ปี) - ALTER TABLE (PostgreSQL Documentation) PostgreSQL
ALTER TABLE ที่ไม่ได้ระบุอะไรเพิ่มจะถือล็อก ACCESS EXCLUSIVE ซึ่งแรงที่สุด - Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
lock_timeout: ถ้ารอล็อกนานเกินเวลานี้จะยกเลิกคำสั่ง - General Thread States MySQL
Waiting for table metadata lock: สถานะของเธรดที่กำลังรอ metadata lock - The schema_table_lock_waits and x$schema_table_lock_waits Views MySQL
เซสชันที่รอ metadata lock (waiting_query) และเซสชันที่ขวางอยู่ (blocking_pid) - pg_locks (PostgreSQL Documentation) PostgreSQL
ถ้า granted เป็น false แปลว่ากำลังรอล็อก, mode แสดงประเภทล็อก เช่น AccessExclusiveLock - System Information Functions and Operators (PostgreSQL Documentation) PostgreSQL
pg_blocking_pids(): รายการเซสชันที่ขวางไม่ให้เซสชันที่ระบุได้ล็อก
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L12 ฐานข้อมูล
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (อินพุตดีเลย์)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง