FiveM MariaDB Lock Wait Timeout คืออะไร? วิธีแก้ Lock wait timeout exceeded และหา Transaction ที่ล็อกค้าง
FiveM MariaDB Lock wait timeout exceeded คือ Error ที่เกิดเมื่อ Transaction ของ InnoDB ต้องรอ Lock จาก Transaction อื่นนานเกินค่าที่ MariaDB กำหนดไว้ใน innodb_lock_wait_timeout จึงไม่สามารถทำ Statement ต่อได้ตามปกติ.
สำหรับ FiveM Server ที่ใช้ oxmysql ปัญหานี้มักเกิดเมื่อ Resources หลายตัวพยายามแก้ข้อมูลเดียวกันพร้อมกัน เช่น Update Row เดียว, Transaction เปิดค้างนาน, Query ช้า หรือมี Lock Contention สูง
สิ่งสำคัญที่สุดคือ:
Lock wait timeout
≠ wait_timeout
เพราะ wait_timeout เกี่ยวกับ Connection ที่ Idle แต่ innodb_lock_wait_timeout เกี่ยวกับ Transaction ที่กำลังรอ InnoDB Lock.
① Lock คืออะไร
เมื่อ Transaction แก้ข้อมูล InnoDB อาจต้อง Lock Record หรือโครงสร้างที่เกี่ยวข้องเพื่อป้องกัน Transaction อื่นเปลี่ยนข้อมูลเดียวกันในเวลาเดียวกันจนเกิดความไม่สอดคล้อง
แนวคิด:
Transaction A
↓
UPDATE Row 100
↓
ถือ Lock
Transaction B
↓
ต้อง UPDATE Row 100 เหมือนกัน
↓
รอ Transaction A
ถ้า Transaction A ปล่อย Lock เร็ว:
B ทำงานต่อ
แต่ถ้ารอนานเกิน Timeout:
Lock wait timeout exceeded
② innodb_lock_wait_timeout คืออะไร
innodb_lock_wait_timeout คือ MariaDB System Variable ที่กำหนดเวลารอ InnoDB Record Lock ก่อนเกิด Lock Wait Timeout โดย MariaDB ยังใช้ตัวแปรนี้เป็นกลไกสำคัญหาก Deadlock Detection ถูกปิด.
ดังนั้น:
innodb_lock_wait_timeout
=
เวลารอ Lock
ไม่ใช่เวลารอ Connection Idle
③ วิธีดูค่า innodb_lock_wait_timeout
ใช้:
SHOW VARIABLES
LIKE 'innodb_lock_wait_timeout';
หรือ:
SELECT @@innodb_lock_wait_timeout;
ค่าจริงควรตรวจจาก MariaDB Server ที่ใช้งาน ไม่ควรเดาจาก Tutorial เพราะ Version และ Configuration อาจแตกต่างกัน
④ Error ที่มักพบเป็นแบบไหน
โดยทั่วไปจะเห็นข้อความลักษณะ:
Lock wait timeout exceeded
หรือ Driver/Resource แสดง Error ที่มีความหมายว่าการรอ InnoDB Lock ใช้เวลานานเกินกำหนด
เมื่อเห็น Error นี้ จุดแรกที่ต้องตรวจไม่ใช่:
mysql_connection_string
เพราะ Database Connection ผ่านแล้ว
ปัญหาอยู่ที่:
Transaction / Lock / Query
⑤ wait_timeout กับ innodb_lock_wait_timeout ต่างกันอย่างไร
wait_timeout
Connection
↓
ไม่มี Activity
↓
Idle นาน
↓
ปิด Connection
innodb_lock_wait_timeout
Transaction
↓
ต้องการ Lock
↓
มี Transaction อื่นถืออยู่
↓
รอ
↓
รอนานเกินไป
ดังนั้นสองตัวนี้แก้คนละปัญหา
⑥ Deadlock กับ Lock Wait Timeout เหมือนกันไหม
ไม่เหมือนกัน
Deadlock คือสถานการณ์ที่ Transactions รอกันเป็นวงจรจนไม่มีฝ่ายใดเดินหน้าต่อได้
MariaDB มี Deadlock Detection เปิดใช้งานโดยปริยายใน InnoDB และหากปิดระบบตรวจ Deadlock MariaDB จะพึ่ง innodb_lock_wait_timeout มากขึ้น.
ส่วน Lock Wait Timeout อาจเกิดได้แม้ไม่มี Deadlock แบบวงจร เพียงแค่ Transaction หนึ่งถือ Lock นานจนอีก Transaction รอไม่ไหว
⑦ ตัวอย่าง Deadlock แบบง่าย
Transaction A
Lock Row 1
↓
รอ Row 2
Transaction B
Lock Row 2
↓
รอ Row 1
กลายเป็น:
A รอ B
B รอ A
นี่คือ Deadlock
⑧ ตัวอย่าง Lock Wait Timeout
Transaction A
Lock Row 1
↓
ทำงานนาน
Transaction B
ต้องการ Row 1
↓
รอ
↓
รอเกิน Timeout
กรณีนี้ไม่จำเป็นต้องมีวงจร Deadlock
เพียง Transaction A ถือ Lock นานเกินไปก็เพียงพอให้ B Timeout
⑨ FiveM ทำไมเจอ Lock Wait Timeout
สาเหตุที่ควรตรวจ:
① Transaction ยาวเกินไป
② Query ช้า
③ UPDATE Row เดียวพร้อมกันจำนวนมาก
④ Resource หลายตัวแก้ข้อมูลชุดเดียวกัน
⑤ Query Order ไม่เหมือนกัน
⑥ Index ไม่เหมาะ
⑦ Transaction เปิดแล้วทำงานอย่างอื่นนาน
⑧ Autosave Player พร้อมกัน
⑨ Batch Update ใหญ่เกินไป
⑩ Database Load สูง
ไม่ได้หมายความว่า oxmysql เสียเสมอไป
⑩ oxmysql Transaction เกี่ยวข้องอย่างไร
oxmysql มี MySQL.transaction สำหรับ Execute หลาย Queries และ Commit เมื่อทั้งหมดสำเร็จ ถ้ามี Query ใดล้มเหลว ชุด Transaction จะไม่ Commit.
ตัวอย่าง:
local success = MySQL.transaction.await({
{
query = 'UPDATE `profiles` SET `status` = ? WHERE `id` = ?',
values = { 'active', profileId }
},
{
query = 'UPDATE `settings` SET `updated_at` = NOW() WHERE `profile_id` = ?',
values = { profileId }
}
})
Transaction มีประโยชน์เรื่อง Consistency แต่ถ้าออกแบบให้ทำงานนานเกินไป ก็สามารถทำให้ Locks ถูกถือไว้นานขึ้นได้
⑪ Transaction ควรสั้น
หลักสำคัญคือ:
เริ่ม Transaction
↓
ทำ Database Operations ที่จำเป็น
↓
Commit
ไม่ควร:
เริ่ม Transaction
↓
ทำงานอื่นยาวๆ
↓
Wait
↓
เรียก External Logic
↓
ค่อย Query ต่อ
↓
Commit
ยิ่ง Transaction อยู่ได้นาน Lock ที่เกี่ยวข้องก็อาจถูกถือได้นานขึ้น
⑫ อย่าใส่ Wait() ใน Transaction Logic โดยไม่จำเป็น
หลีกเลี่ยง Architecture เช่น:
-- แนวคิดที่ไม่ควรทำ
beginTransaction()
updateData()
Wait(5000)
updateMoreData()
commit()
เพราะ Database Transaction ไม่ควรถูกเปิดทิ้งระหว่าง Gameplay Delay โดยไม่มีเหตุผล
⑬ Query ช้าทำให้ Lock ค้างนานขึ้นได้
ถ้า Statement ต้อง Update Rows จำนวนมากและใช้เวลานาน:
UPDATE
↓
ถือ Lock
↓
Query ช้า
↓
Transaction อื่นรอ
ดังนั้น Slow Query และ Lock Contention สามารถเกี่ยวข้องกันได้
oxmysql ระบุว่าความเร็ว Query จริงควรวัดผ่าน Debug UI หรือ Server Console เมื่อเปิด mysql_debug และ Performance แตกต่างตาม Hardware, Database Settings, Version และ Workload.
⑭ mysql_debug ช่วยอะไร
เปิด:
set mysql_debug true
แล้วตรวจ:
Query ไหนช้า
Resource ไหนยิง Query
Query ถูกเรียกบ่อยแค่ไหน
ถ้า Lock Error เกิดทุกครั้งหลัง Resource หนึ่ง Execute UPDATE ช้า นั่นเป็นเบาะแสสำคัญ
⑮ SHOW ENGINE INNODB STATUS คืออะไร
MariaDB มีคำสั่ง:
SHOW ENGINE INNODB STATUS;
เพื่อแสดงข้อมูลสถานะเชิงลึกของ InnoDB รวมถึงข้อมูล Deadlock, Buffer Pool และ I/O.
นี่เป็นหนึ่งในเครื่องมือสำคัญเมื่อวิเคราะห์:
Deadlock
Lock Contention
InnoDB Problem
⑯ ควรใช้ SHOW INNODB STATUS ไหม
ใช้รูปแบบปัจจุบัน:
SHOW ENGINE INNODB STATUS;
MariaDB ระบุว่า SHOW INNODB STATUS แบบเก่าเป็น Deprecated/Removed Synonym และควรใช้ SHOW ENGINE INNODB STATUS แทน.
⑰ INNODB_TRX คืออะไร
MariaDB มี:
information_schema.INNODB_TRX
ซึ่งเก็บข้อมูล Transactions ที่กำลังทำงานอยู่ เช่น Transaction ID, State, เวลาเริ่ม และข้อมูล Lock ที่เกี่ยวข้อง.
ตัวอย่าง:
SELECT *
FROM information_schema.INNODB_TRX;
⑱ Transaction State ที่ควรสังเกต
MariaDB ระบุว่า INNODB_TRX.TRX_STATE สามารถมี State เช่น:
RUNNING
LOCK WAIT
ROLLING BACK
COMMITTING
ได้.
ดังนั้นถ้าเจอ:
LOCK WAIT
ก็เป็นสัญญาณตรงว่ามี Transaction กำลังรอ Lock
⑲ INNODB_LOCK_WAITS คืออะไร
MariaDB มี:
information_schema.INNODB_LOCK_WAITS
สำหรับ Mapping ว่า Transaction ใดกำลังถูก Block และ Transaction ใดเป็นตัว Blocking โดยต้องมี PROCESS Privilege เพื่อดูข้อมูล Table นี้.
นี่เป็นเครื่องมือที่มีประโยชน์มากในการตอบคำถาม:
ใครกำลังรอใคร?
⑳ ตัวอย่างตรวจ Lock Waits
SELECT *
FROM information_schema.INNODB_LOCK_WAITS;
ข้อมูลจะช่วยเชื่อมโยง:
Requesting Transaction
↓
Blocked By
↓
Blocking Transaction
ตามโครงสร้างของ MariaDB.
㉑ INNODB_LOCKS คืออะไร
MariaDB มี:
information_schema.INNODB_LOCKS
ซึ่งเก็บข้อมูล Locks ที่ Transaction ขอแต่ยังไม่ได้ หรือ Locks ที่กำลัง Block Transaction อื่น.
ใช้ร่วมกับ:
INNODB_TRX
INNODB_LOCK_WAITS
จะช่วยเห็นภาพ Lock Contention ชัดขึ้น
㉒ PROCESS Privilege จำเป็นไหม
MariaDB ระบุว่า INNODB_LOCK_WAITS และหลาย Information Schema Tables สำหรับการวิเคราะห์ InnoDB ต้องใช้ PROCESS Privilege เพื่อดูข้อมูลทั้งหมด.
ไม่ควรเพิ่ม PROCESS ให้ FiveM Runtime User เพียงเพื่อ Debug
แนวทางที่ดีกว่าคือใช้ Administrative Database Account สำหรับ Monitoring
㉓ อย่าให้ fivem_app เป็น Admin เพียงเพื่อดู Locks
Runtime Account ควรมีสิทธิ์เฉพาะที่ Resource ต้องใช้
การ Debug InnoDB ควรแยกไปใช้:
DBA / Monitoring User
เพื่อไม่ขยาย Privileges ของ Credential ที่ FiveM ถืออยู่โดยไม่จำเป็น
㉔ วิธีหา Blocking Transaction แบบเป็นขั้นตอน
ใช้:
① ตรวจ Error Time
② SHOW ENGINE INNODB STATUS
③ ดู INNODB_TRX
④ ดู INNODB_LOCK_WAITS
⑤ หา Blocking TRX ID
⑥ หา Query/Resource
⑦ ตรวจว่าทำไม Transaction ไม่ Commit
อย่าเริ่มจากเพิ่ม Timeout
㉕ เพิ่ม innodb_lock_wait_timeout แก้ได้ไหม
อาจทำให้รอนานขึ้น แต่ไม่ได้แก้ต้นเหตุเสมอไป
ถ้า Transaction A ถือ Lock 2 นาทีและ B รอเพราะ Query Design ผิด
การเพิ่ม Timeout จาก:
50
→
300
เพียงทำให้ B รอนานกว่าเดิม
ไม่ได้ทำให้ A ปล่อย Lockเร็วขึ้น
㉖ ลด innodb_lock_wait_timeout ดีไหม
บาง Workload อาจต้องการ Fail Fast แทนการรอนาน แต่ไม่มีค่าที่เหมาะกับทุก Server
MariaDB ระบุว่าเมื่อ Deadlock Detection ถูกปิด ระบบจะพึ่ง innodb_lock_wait_timeout มากขึ้น และ Configuration นี้ต้องสัมพันธ์กับ Concurrency Design.
ดังนั้นอย่า Copy ค่า 1 หรือ 5 จาก Server อื่นแบบสุ่ม
㉗ WAIT และ NOWAIT คืออะไร
MariaDB มี Syntax WAIT และ NOWAIT สำหรับ Statements บางประเภท เพื่อกำหนดว่าควรรอ Lock กี่วินาทีหรือ Fail ทันทีหากไม่ได้ Lock.
นี่เป็นเครื่องมือเฉพาะ Use Case ไม่ใช่สิ่งที่ต้องใส่ทุก Query ใน FiveM
㉘ NOWAIT เหมาะเมื่อไหร่
เหมาะเมื่อ Application Design ต้องการ:
หา Lock ไม่ได้
→ Fail ทันที
แทน:
รอ
แต่ Resource ต้องรองรับ Failure อย่างถูกต้อง
ไม่ใช่ใช้ NOWAIT เพื่อซ่อน Query Design ที่มี Lock Contention สูง
㉙ Query Order มีผลกับ Deadlock
สมมติ Resource A:
UPDATE profiles
↓
UPDATE settings
Resource B:
UPDATE settings
↓
UPDATE profiles
หากทำพร้อมกัน มีโอกาสเกิดการรอกันในลำดับตรงข้าม
แนวทางที่ดีคือให้ Transactions ที่แก้ Resources ชุดเดียวกันใช้ Lock/Update Order ที่สม่ำเสมอ
㉚ ตัวอย่าง Order ที่ควรสม่ำเสมอ
กำหนด:
① profiles
② settings
③ metadata
แล้วทุก Transaction ที่ต้องแก้ทั้งสาม Table ใช้ Order นี้เหมือนกัน
ช่วยลดสถานการณ์ที่แต่ละ Transaction ถือคนละ Lock แล้วมารอกันภายหลัง
㉛ Autosave Player พร้อมกันทำให้ Lock Contention ได้ไหม
ได้ หาก Players หลายคนหรือ Resource หลายตัว Update Records ชุดเดียวกันหรือ Shared Rows พร้อมกัน
ตัวอย่าง:
200 Players
↓
Autosave เวลาเดียวกัน
↓
Resource A Update
Resource B Update
Resource C Update
ถ้าข้อมูลถูกออกแบบให้พึ่ง Shared Row หนึ่งตัวมากเกินไป Lock Contention อาจสูง
㉜ Shared Counter Row ต้องระวัง
ตัวอย่าง:
server_stats
id = 1
แล้วทุก Player Action ทำ:
UPDATE `server_stats`
SET `counter` = `counter` + 1
WHERE `id` = 1;
Row เดียวนี้กลายเป็น Hot Row
เมื่อ Concurrent Writes สูง ทุก Transaction ต้องแย่ง Lock จุดเดียวกัน
㉝ Hot Row คืออะไร
คือ Row ที่มี Writes จำนวนมากพร้อมกัน
ตัวอย่าง:
global_stats
global_sequence
shared_state
ถ้า Architecture ส่ง Writes ทุกอย่างไป Row เดียว Lock Contention จะสูงกว่าการกระจายข้อมูลอย่างเหมาะสม
㉞ Index มีผลกับ Lock Wait ไหม
มีได้
Query ที่ไม่มี Index เหมาะสมอาจต้องตรวจ Rows จำนวนมากและใช้เวลานานขึ้น ทำให้ Transaction อยู่ได้นานขึ้น
แต่ต้องใช้:
EXPLAIN
Query Plan
วิเคราะห์จริง ไม่ใช่เพิ่ม Index ทุก Column
㉟ UPDATE ต้องมี WHERE ที่เจาะจง
หลีกเลี่ยง:
UPDATE `players`
SET `status` = 'active';
หากตั้งใจแก้ Player คนเดียว
ควรเป็น Query ที่ระบุ Record ที่ต้องการอย่างถูกต้อง เช่น:
UPDATE `players`
SET `status` = ?
WHERE `id` = ?;
และ Column ใน WHERE ควรมี Index/Key ที่เหมาะกับ Query Pattern จริง
㊱ SELECT FOR UPDATE เกี่ยวอะไร
Query ที่ขอ Lock เพื่อ Update มีผลต่อ Concurrency มากกว่า SELECT อ่านปกติ
ถ้า Resource ใช้ Locking Reads ต้องออกแบบ Transaction ให้สั้นและชัด
ไม่ควรถือ Row Lock ระหว่างรอ Gameplay Event อื่น
㊲ อย่าเปิด Transaction แล้วรอ Client Response
Pattern ที่ควรหลีกเลี่ยง:
Begin Transaction
↓
Lock Row
↓
ส่ง Event ไป Client
↓
รอ Client ตอบ
↓
ค่อย Commit
เพราะ Network/Client Delay อาจทำให้ Database Lock ถูกถือไว้นานโดยไม่จำเป็น
ควร Validate/Collect Data ก่อนเริ่ม Transaction เมื่อทำได้
㊳ oxmysql Transaction ควรใช้เมื่อจำเป็นจริง
oxmysql ระบุว่า Transaction เหมาะเมื่อหลาย Queries ต้อง Commit ทั้งหมดพร้อมกัน หากหนึ่ง Queryล้มเหลวจะไม่ Commitทั้งชุด.
ดังนั้นอย่าเอา Queries ที่ไม่เกี่ยวกับ Atomic Requirement มารวม Transaction ใหญ่เพียงเพราะ “ปลอดภัยกว่า”
Transaction ใหญ่ขึ้นสามารถเพิ่ม Lock Scope/Duration ได้
㊴ Transaction Isolation Level เกี่ยวไหม
oxmysql รองรับ ConVar:
mysql_transaction_isolation_level
ค่า 1–4 และเอกสารปัจจุบันระบุ Default เป็น 2 ซึ่ง Map เป็น Read Committed.
Isolation Level มีผลต่อ Transaction Semantics และ Lock/Visibility Behavior
จึงไม่ควรเปลี่ยนเพื่อแก้ Lock Timeout แบบเดาสุ่ม
㊵ อย่าเปลี่ยน Isolation Level เป็นวิธีแก้แรก
ถ้า Error เกิดจาก:
Transaction เปิด 30 วินาที
การเปลี่ยน Isolation Level อาจไม่ใช่ต้นเหตุ
เริ่มจาก:
Query
Transaction Duration
Blocking Transaction
ก่อน
㊶ Lock Wait หลัง Resource Update
ถ้าปัญหาเพิ่งเริ่มหลัง Update Script ให้ตรวจ:
Transaction ใหม่
Query ใหม่
UPDATE Order ใหม่
Index Migration
Autosave Logic
เพราะ Resource Update อาจเปลี่ยน Database Access Pattern
㊷ Lock Wait หลังเพิ่มผู้เล่น
Player Count เพิ่มอาจเพิ่ม:
Concurrent Writes
แต่จำนวนผู้เล่นไม่ใช่สาเหตุโดยตรง
Resource ที่เขียน Database อย่างมีประสิทธิภาพสามารถ Scale ดีกว่า Resource ที่ Update Shared Rows ทุก Action
㊸ Lock Wait หลังเปิด Server ใหม่
หลัง Restart Players เข้า Server พร้อมกันจำนวนมากอาจสร้าง:
Login Query Burst
Character Load
Settings Update
Session Update
ถ้า Resource ทำ Writes ซ้ำบน Shared Table/Row อาจเห็น Lock Contention เฉพาะช่วง Startup
㊹ Lock Wait เฉพาะ Autosave
ถ้า Error เกิด:
ทุก 5 นาที
ให้ตรวจ Autosave Schedule ก่อน
ถ้า Players ทุกคน Save พร้อมกัน ให้พิจารณา:
Staggered Save
Dirty Flag
ลด Query
แทนเพิ่ม innodb_lock_wait_timeout
㊺ Dirty Flag ช่วยได้อย่างไร
ถ้าข้อมูลไม่เปลี่ยน:
dirty = false
→ ไม่ Update
ถ้าข้อมูลเปลี่ยน:
dirty = true
→ Save
ช่วยลด Writes และลดโอกาสแย่ง Locks โดยไม่จำเป็น
㊻ Upsert เกี่ยวกับ Lock ไหม
Upsert ยังเป็น Write Operation และยังสามารถเกี่ยวข้องกับ Locks
การลด:
SELECT
+
INSERT/UPDATE
เหลือ SQL Statement เดียวอาจช่วยลด Application Round Trips ใน Use Case ที่เหมาะสม แต่ไม่ได้หมายความว่า Upsert ไม่มี Lock
㊼ Prepare แก้ Lock Wait ไหม
ไม่ได้โดยตรง
MySQL.prepare เหมาะกับ Frequently-called Queries แต่ไม่ได้แก้ Transaction ที่ถือ Lock นาน.
ต้องแยก:
Prepare
→ Execution Pattern
Lock Wait
→ Concurrency / Transaction
㊽ Cache ช่วย Lock Contention ได้ไหม
ช่วยได้หากลด Database Writes/Reads ที่ไม่จำเป็น
แต่ข้อมูลที่ต้อง Persist อย่างถูกต้องยังต้อง Save ตาม Business Requirement
อย่า Cache แล้วไม่บันทึกข้อมูลสำคัญเพียงเพื่อหลีกเลี่ยง Locks
㊾ ควร Kill Blocking Transaction ไหม
ใน Emergency อาจต้องจัดการ Blocking Transaction แต่ไม่ควรทำแบบสุ่ม
ก่อนตัด Transaction ต้องรู้:
มันกำลังทำอะไร
Resource ไหนเป็นเจ้าของ
Data Consistency จะได้รับผลอย่างไร
แล้วแก้ Root Cause หลังเหตุการณ์ผ่าน
㊿ Restart MariaDB แก้ Lock Wait ไหม
Restart จะตัด Transactions/Connections แต่ถือเป็นวิธีรุนแรง
ถ้าปัญหาเกิดจาก Resource เดิม:
Restart
↓
เปิดใหม่
↓
Resource ทำ Pattern เดิม
↓
Lock Wait กลับมา
จึงไม่ใช่การแก้ระยะยาว
51. Restart FiveM แก้ไหม
คล้ายกัน
Restart สามารถตัด Runtime Transactions/Requests ชั่วคราว แต่ Resource Code ที่สร้าง Lock Contention ยังอยู่
ต้องแก้ Query/Transaction Design
52. SHOW PROCESSLIST ใช้ร่วมกันได้ไหม
ได้
ใช้:
SHOW FULL PROCESSLIST;
เพื่อดู Connections/Queries ที่กำลังทำงาน แล้วใช้ข้อมูล InnoDB เพิ่มเพื่อดู Transaction/Lock Relationships
SHOW ENGINE INNODB STATUS และ INNODB_TRX จะให้ข้อมูล InnoDB-specific มากกว่า Processlist อย่างเดียว.
53. Workflow Debug Lock Wait ที่ควรใช้
① เก็บ Error
② จดเวลาเกิด
③ SHOW FULL PROCESSLIST
④ SHOW ENGINE INNODB STATUS
⑤ SELECT INNODB_TRX
⑥ SELECT INNODB_LOCK_WAITS
⑦ หา Blocking Transaction
⑧ หา SQL
⑨ หา Resource
⑩ ตรวจ Transaction Duration
⑪ ตรวจ Query Plan
⑫ แก้ Resource
⑬ ทดสอบ Concurrent Load
นี่มีประโยชน์กว่าการเพิ่ม Timeout อย่างเดียว
54. ตัวอย่างตรวจ Transactions
SELECT
TRX_ID,
TRX_STATE,
TRX_STARTED
FROM information_schema.INNODB_TRX;
MariaDB ระบุว่า INNODB_TRX เก็บ Transactions ที่กำลัง Execute รวมถึง State และ Start Time.
ถ้าเห็น Transaction:
STARTED นานมาก
+
LOCK WAIT
ต้องตรวจทันทีว่าอะไรทำให้ Transaction นั้นอยู่ได้นาน
55. ตัวอย่างตรวจ Blocking Relationship
SELECT *
FROM information_schema.INNODB_LOCK_WAITS;
MariaDB ระบุ Table นี้ใช้ Map Blocked Transaction กับ Blocking Transaction.
นี่ตอบคำถามสำคัญที่สุด:
ใคร Block ใคร
56. Lock Timeout หลัง Migration
Migration อาจ:
เพิ่ม Index
เปลี่ยน Query
เปลี่ยน Constraint
เปลี่ยน Data Model
และทำให้ Resource Access Pattern เปลี่ยน
หลัง Migration ควร Monitor:
Slow Query
Deadlock
Lock Wait
Database CPU
ไม่ใช่ตรวจเพียงว่า SQL Import ผ่าน
57. Lock Timeout กับ Table ใหญ่
Table ใหญ่ไม่ได้หมายความว่าจะ Lock Timeout เสมอ
แต่ Query ที่แตะ Rows มาก, ไม่มี Index เหมาะสม หรือใช้ Transaction ใหญ่สามารถเพิ่มเวลาที่ Database ต้องทำงาน
ดังนั้น Table Size ต้องดูร่วมกับ Query Plan
58. Lock Timeout กับ DELETE
DELETE จำนวนมากภายใน Transaction สามารถเป็น Write-heavy Operation
หากต้องลบข้อมูลจำนวนมาก ควรออกแบบ Maintenance/Batch Strategy ตาม Requirement แทน Execute Huge Transaction ในช่วง Player Load สูงโดยไม่ทดสอบ
59. Lock Timeout กับ UPDATE จำนวนมาก
เช่น:
UPDATE `players`
SET `flag` = 0;
ซึ่งแตะหลาย Rows อาจสร้าง Lock Footprint ใหญ่กว่าการ Update Row เดียว
อย่าให้ Gameplay Event ธรรมดา Trigger Bulk UPDATE โดยไม่จำเป็น
60. Checklist FiveM Lock Wait Timeout
ก่อนปรับ Config ตรวจ:
Error เกิดเวลาไหน
Resource ไหน Error
SQL อะไร Error
Transaction ใช่หรือไม่
Transaction เริ่มเมื่อไร
INNODB_TRXมี LOCK WAIT หรือไม่INNODB_LOCK_WAITSใคร Block ใครSHOW ENGINE INNODB STATUSQuery ช้าหรือไม่
Index เหมาะหรือไม่
UPDATE Row เดียวหรือหลาย Rows
Shared Hot Row หรือไม่
Autosave พร้อมกันหรือไม่
Login Burst หรือไม่
Transaction ใหญ่หรือไม่
มี
Wait()ระหว่าง Logic หรือไม่รอ Client Response ระหว่าง Transaction หรือไม่
Query Order สม่ำเสมอหรือไม่
Isolation Level ถูกเปลี่ยนหรือไม่
มี Resource ใหม่หรือไม่
มี Migration ใหม่หรือไม่
Database CPU สูงหรือไม่
Disk I/O สูงหรือไม่
Slow Query Warning มีหรือไม่
mysql_debug บอกอะไร
Timeout ปัจจุบันเท่าไร
อย่าเพิ่ม Timeout ก่อนหา Root Cause
Test Concurrent Writes
Backup ก่อน Schema Change
Monitor หลังแก้
ตาราง Timeout ที่ควรแยกให้ออก
| ค่า | ใช้กับ |
|---|---|
wait_timeout | Idle Database Connection |
innodb_lock_wait_timeout | รอ InnoDB Lock |
interactive_timeout | Idle Interactive Connection |
| Query Timeout | Query Execution |
| Network Timeout | Network/Driver |
| Transaction Timeout | Transaction Lifecycle ตาม Feature |
MariaDB มีระบบ Lock Wait, Connection Idle และ Query/Transaction Timeout แยกกัน ดังนั้นต้องแก้ให้ตรง Layer.
FiveM Lock wait timeout exceeded แก้อย่างไร
ใช้ลำดับ:
Error
↓
SHOW ENGINE INNODB STATUS
↓
INNODB_TRX
↓
INNODB_LOCK_WAITS
↓
หา Blocking Transaction
↓
หา Resource/Query
↓
ลด Transaction Duration
↓
Optimize Query
MariaDB มีเครื่องมือทั้งหมดนี้เพื่อวิเคราะห์ InnoDB Locks และ Transactions โดยตรง.
FiveM innodb_lock_wait_timeout ควรตั้งเท่าไร
ไม่มีค่าหนึ่งที่ดีที่สุดสำหรับทุก Server
อย่า Copy ค่าจาก Server อื่นโดยไม่ดู:
Concurrency
Transaction Duration
Database Load
Deadlock Detection
การเพิ่มค่าเพียงทำให้ Transaction รอนานขึ้นหากต้นเหตุคือ Lock Contention
FiveM Lock Wait กับ Deadlock ต่างกันอย่างไร
Lock Wait คือ Transaction รอ Lock จาก Transaction อื่น
Deadlock คือ Transactions รอกันเป็นวงจรจนไม่สามารถเดินหน้าต่อได้
MariaDB เปิด Deadlock Detection โดยปริยาย และหากปิดจะพึ่ง innodb_lock_wait_timeout มากขึ้น.
FiveM ดู Transaction ที่ล็อกยังไง
ใช้:
SELECT *
FROM information_schema.INNODB_TRX;
เพื่อดู Transactions ปัจจุบัน และ:
SELECT *
FROM information_schema.INNODB_LOCK_WAITS;
เพื่อดู Blocked/Blocking Relationships.
FiveM ดู Deadlock ยังไง
ใช้:
SHOW ENGINE INNODB STATUS;
MariaDB ระบุว่าคำสั่งนี้แสดงข้อมูล InnoDB รวมถึง Deadlocks.
FiveM Transaction ใหญ่ทำ Lock Timeout ได้ไหม
ได้ในเชิง Concurrency เพราะ Transaction ที่แก้ข้อมูลหลายชุดและอยู่ได้นานสามารถถือ Locks นานขึ้น
oxmysql Transaction ควรใช้เมื่อหลาย Queries ต้อง Commit พร้อมกันจริง.
FiveM เพิ่ม innodb_lock_wait_timeout แล้วหายไหม
อาจทำให้ Error เกิดช้าลง แต่ถ้า Blocking Transaction ยังทำงานนาน ปัญหายังอยู่
ควรหา Blocking SQL ก่อน
FiveM Autosave ทำ Lock Wait ได้ไหม
ได้หาก Autosave ทำ Concurrent Writes จำนวนมากบน Records หรือ Shared Rows เดียวกัน
ควรกระจาย Save และลด Writes ที่ไม่จำเป็น
FiveM oxmysql เป็นสาเหตุหรือไม่
ไม่ควรสรุปทันที
oxmysql เป็น Database Layer ที่ Execute SQL/Transactions ให้ Resource ส่วน Lock Management เกิดใน Database Engine ตาม Queries และ Transaction Behavior ที่ Resource ส่งมา
FAQ FiveM MariaDB Lock Wait Timeout
Lock wait timeout exceeded คืออะไร
คือ Transaction รอ InnoDB Lock นานเกิน innodb_lock_wait_timeout.
innodb_lock_wait_timeout กับ wait_timeout เหมือนกันไหม
ไม่ wait_timeout ใช้กับ Idle Connection ส่วน innodb_lock_wait_timeout ใช้กับการรอ InnoDB Lock
Lock Wait กับ Deadlock เหมือนกันไหม
ไม่ Deadlock เป็นวงจรการรอกัน ส่วน Lock Wait อาจเกิดเพียง Transaction หนึ่งรออีก Transaction นานเกินไป
ดู Blocking Transaction อย่างไร
ใช้ INNODB_LOCK_WAITS ซึ่ง MariaDB ระบุว่า Map Blocked Transactions กับ Blocking Transactions.
ดู Transactions ปัจจุบันอย่างไร
ใช้ INNODB_TRX ซึ่งเก็บ State, Start Time และข้อมูล Transaction ที่กำลัง Execute.
ดู Deadlock อย่างไร
ใช้ SHOW ENGINE INNODB STATUS ซึ่งแสดงข้อมูล InnoDB รวมถึง Deadlock Information.
เพิ่ม Lock Timeout ดีไหม
ไม่ควรเป็นวิธีแรก เพราะอาจเพียงทำให้ Transaction รอนานขึ้นโดยไม่แก้ Blocking Transaction
Transaction oxmysql ทำ Lock ได้ไหม
Transaction SQL ที่แก้ข้อมูลสามารถเกี่ยวข้องกับ InnoDB Locks ได้ และ oxmysql Transaction จะ Commit เมื่อ Queries ทั้งหมดสำเร็จ.
Slow Query เกี่ยวกับ Lock Wait ไหม
เกี่ยวได้ เพราะ Transaction ที่ทำงานช้าอาจถือ Lock นานขึ้น ควรวัด Query Timing จริงด้วย oxmysql Debug Tools.
Autosave พร้อมกันมีผลไหม
มีได้หากสร้าง Concurrent Writes ไปยัง Records เดียวกันหรือ Shared Rows
Restart MariaDB แก้ถาวรไหม
ไม่ ถ้า Resource Query/Transaction Architecture เดิมยังสร้าง Lock Contention ปัญหาจะกลับมาอีก
ต้องให้ FiveM User มี PROCESS Permission ไหม
ไม่จำเป็นสำหรับ Runtime ปกติ ควรใช้ Administrative/Monitoring Account สำหรับดู InnoDB diagnostic tables ที่ต้องใช้ PROCESS.
ประเด็นสำคัญ
เมื่อ FiveM ขึ้น:
Lock wait timeout exceeded
อย่าเริ่มจาก:
เพิ่ม innodb_lock_wait_timeout
ทันที
ให้เริ่มจาก:
SHOW ENGINE INNODB STATUS
↓
INNODB_TRX
↓
INNODB_LOCK_WAITS
↓
หา Blocking Transaction
↓
หา SQL
↓
หา Resource
↓
ลด Transaction Duration
↓
Optimize Query
MariaDB มี INNODB_TRX สำหรับดู Transactions ปัจจุบัน และ INNODB_LOCK_WAITS สำหรับเชื่อมโยง Blocked Transaction กับตัวที่กำลัง Block อยู่โดยตรง.
ถ้า Resource ใช้ oxmysql Transaction ให้จำว่า Transaction ควรรวมเฉพาะ Queries ที่ต้องสำเร็จพร้อมกันจริง เพราะ oxmysql จะ Commit เมื่อ Queries ทั้งหมดสำเร็จ และ Transaction ที่ออกแบบใหญ่หรือทำงานนานเกินไปสามารถเพิ่ม Lock Contention ได้.
สูตรที่ผู้อ่าน comsiam ควรจำคือ “Lock Timeout → หา Blocking Transaction ก่อน → ไม่ใช่เพิ่ม Timeout ก่อน” และ comsiam แนะนำให้จับคู่ข้อมูลจาก MariaDB InnoDB Status กับ oxmysql Query Timing เพื่อหาว่า Resource ใดกำลังถือ Lock นานจริง เพราะเมื่อแก้ Transaction และ Query ต้นเหตุได้ ปัญหาจะเสถียรกว่าการเพิ่มเวลารอให้ Database อย่างเดียว
Comments
Post a Comment