Lock Wait Timeout Exceeded เกิดเมื่อ Transaction รอ Lock นานเกิน innodb_lock_wait_timeout (Default: 50 วินาที)
การ Debug: SHOW ENGINE INNODB STATUS
SHOW ENGINE INNODB STATUS\G
Output Sections ที่สำคัญ
1. TRANSACTIONS - ดู Transaction ที่ Block/Others
------------
TRANSACTIONS
------------
Trx id counter 21000
---TRANSACTION 283438498772800, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 12345, ACTIVE 30 sec
2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 10, OS thread handle 1234, query id 100 localhost root
Trx read view will not see trx with id >= 12346
TABLE LOCK table `business`.`accounts` trx id 12345 lock_mode X
RECORD LOCKS space id 123 page no 5 n bits 72 index PRIMARY of table `business`.`accounts`
trx id 12345 lock_mode X locks rec but not gap
Record lock, heap no 2
------------------
2. SEMAPHORES - Mutex/RW-lock Contention
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 3, signal count 3
RW-shared spins 0, rounds 0, OS waits 0
Spin rounds per wait: 0.00 RW-shared, 0.00 RW-excl
3. FILE I/O - Disk Bottleneck
--------
FILE I/O
--------
I/O thread 0 state: wait Windows aio (insert buffer thread)
Pending normal aio reads: [0, 0, 0, 0], aio writes: [0, 0, 0, 0]
0.00 reads/s, 0.00 writes/s, 0.00 fsyncs/s
4. BUFFER POOL - Memory Pressure
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 8585216
Buffer pool size 512
Free buffers 251
Database pages 256
Buffer pool hit rate 1000 / 1000
วิธีแก้ Lock Wait Timeout
1. หา Blocking Query
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX
WHERE TRX_STATE = 'LOCK WAIT';
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS
WHERE LOCK_TRX_ID IN (SELECT TRX_ID FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_STATE = 'LOCK WAIT');
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
2. เพิ่ม Timeout (Temporary)
SET GLOBAL innodb_lock_wait_timeout = 120; -- 2 นาที
SET SESSION innodb_lock_wait_timeout = 120;
3. Optimize Query/Index (Root Cause)
- เพิ่ม Index ให้ Query เร็วลง → Lock น้อยลง
- ลด Transaction Scope (Commit เร็วขึ้น)
- หลีกเลี่ยง Long-running Transaction
- ใช้ Row-level Locking อย่างถูกต้อง (Index บน FK, WHERE)
4. Kill Blocking Transaction
KILL blocking_thread_id;
Prevention
- Monitor
Innodb_row_lock_waits,Innodb_row_lock_time_avg - Set
innodb_lock_wait_timeoutให้เหมาะสม (50-120s) - ใช้
SELECT ... FOR UPDATE SKIP LOCKED(MySQL 8.0+) สำหรับ Queue Processing - Application: Retry Logic with Exponential Backoff