報錯信息
Lock wait timeout exceeded; try restarting transaction
超過鎖定等待超時;嘗試重新啟動事務發生原因
流程不嚴謹問題導致SQL執行操作了全部數據,導致update語句執行時間過長導致死鎖。
發生現象
死鎖導致表被鎖定,系統其他對這個表的RUD操作會被卡住,導致報錯等一系列問題。
排查步驟
使用命令窗口或者Navicat 連接數據庫后使用以下命令語句進行排查:
1、查看當前數據庫所有的執行中的進程。
show processlist;
在結果列表里可以看到數據庫下所有的進程,以及相關語句。
id:進程ID,如果需要結束某個進程可以直接kill 線程id,例如:kill 1。
user:當前用戶,如果不是root,這個命令只會顯示你權限范圍內的sql語句。
host:顯示這個語句是從哪個ip 的哪個端口上發出的。可用來追蹤出問題語句的用戶。
db:顯示這個進程目前連接的是哪個數據庫。
command:顯示當前連接的執行的命令,一般就是休眠(sleep),查詢(query),連接(connect)。
2、查看數據庫中當前運行的所有事務
select * from information_schema.innodb_trx;
在結果列表中可以看到是否有表鎖等待或者死鎖,如果有死鎖發生,可以通過一下命令來殺掉當前運行的事務。
kill 581; kill 后面的數字是 trx_mysql_thread_id 列的值。
自己解決這個問題的時候也是參考的這個結果列表,可以根據對應的SQL語句,以及trx_started:事務開始時間字段,開始時間字段可以看到是否已經開始很長一段時間。
根據對應的SQL語句進行分析優化或者殺掉對應的事務即可。
trx_id:事務ID。
trx_state:事務狀態,有以下幾種狀態:RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING。
trx_started:事務開始時間。
trx_requested_lock_id:事務當前正在等待鎖的標識,可以和 INNODB_LOCKS 表 JOIN 以得到更多詳細信息。
trx_wait_started:事務開始等待的時間。
trx_weight:事務的權重。
trx_mysql_thread_id:事務線程 ID,可以和 PROCESSLIST 表 JOIN。
trx_query:事務正在執行的 SQL 語句。
trx_operation_state:事務當前操作狀態。
trx_tables_in_use:當前事務執行的 SQL 中使用的表的個數。
trx_tables_locked:當前執行 SQL 的行鎖數量。
trx_lock_structs:事務保留的鎖數量。
trx_lock_memory_bytes:事務鎖住的內存大小,單位為 BYTES。
trx_rows_locked:事務鎖住的記錄數。包含標記為 DELETED,並且已經保存到磁盤但對事務不可見的行。
trx_rows_modified:事務更改的行數。
trx_concurrency_tickets:事務並發票數。
trx_isolation_level:當前事務的隔離級別。
trx_unique_checks:是否打開唯一性檢查的標識。
trx_foreign_key_checks:是否打開外鍵檢查的標識。
trx_last_foreign_key_error:最后一次的外鍵錯誤信息。
trx_adaptive_hash_latched:自適應散列索引是否被當前事務鎖住的標識。
trx_adaptive_hash_timeout:是否立刻放棄為自適應散列索引搜索 LATCH 的標識。