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 ตรวจ:

  1. Error เกิดเวลาไหน

  2. Resource ไหน Error

  3. SQL อะไร Error

  4. Transaction ใช่หรือไม่

  5. Transaction เริ่มเมื่อไร

  6. INNODB_TRX มี LOCK WAIT หรือไม่

  7. INNODB_LOCK_WAITS ใคร Block ใคร

  8. SHOW ENGINE INNODB STATUS

  9. Query ช้าหรือไม่

  10. Index เหมาะหรือไม่

  11. UPDATE Row เดียวหรือหลาย Rows

  12. Shared Hot Row หรือไม่

  13. Autosave พร้อมกันหรือไม่

  14. Login Burst หรือไม่

  15. Transaction ใหญ่หรือไม่

  16. มี Wait() ระหว่าง Logic หรือไม่

  17. รอ Client Response ระหว่าง Transaction หรือไม่

  18. Query Order สม่ำเสมอหรือไม่

  19. Isolation Level ถูกเปลี่ยนหรือไม่

  20. มี Resource ใหม่หรือไม่

  21. มี Migration ใหม่หรือไม่

  22. Database CPU สูงหรือไม่

  23. Disk I/O สูงหรือไม่

  24. Slow Query Warning มีหรือไม่

  25. mysql_debug บอกอะไร

  26. Timeout ปัจจุบันเท่าไร

  27. อย่าเพิ่ม Timeout ก่อนหา Root Cause

  28. Test Concurrent Writes

  29. Backup ก่อน Schema Change

  30. Monitor หลังแก้

ตาราง Timeout ที่ควรแยกให้ออก

ค่าใช้กับ
wait_timeoutIdle Database Connection
innodb_lock_wait_timeoutรอ InnoDB Lock
interactive_timeoutIdle Interactive Connection
Query TimeoutQuery Execution
Network TimeoutNetwork/Driver
Transaction TimeoutTransaction 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

Popular posts from this blog

FiveM ยังน่าเล่นไหม? Enhanced เปลี่ยน FiveM แค่ไหน

FiveM คืออะไร เล่นอย่างไร สำหรับมือใหม่ เริ่มต้นตั้งแต่ศูนย์

วิธีตั้ง Admin Permission ด้วย add_ace และ add_principal FiveM แบบละเอียด