mysql 使用 innodb_trx innodb_lock_waits innodb_locks 來分析鎖


現象:

導入一個insert 語句sql文件到數據庫中時,老是報錯:“Error Code: 1205 - Lock wait timeout exceeded; try restarting transaction”。

我們使用 innodb_trx innodb_lock_waits innodb_locks 這三個表開始調查:

1、找到被鎖卡死的SQL:

SELECT * FROM innodb_trx WHERE trx_state='LOCK WAIT'

通過改語句找到被鎖卡住,也就是申請鎖 處於鎖等待狀態的SQL信息:

 可以得到當前處於鎖等待的線程id值為:11188391835

trx_id:InnoDB存儲引擎內部唯一的事物ID
trx_status:當前事務的狀態
trx_started:事務的開始時間
trx_requested_lock_id:等待事務的鎖ID
trx_wait_started:事務等待的開始時間
trx_weight:事務的權重,反應一個事務修改和鎖定的行數,當發現死鎖需要回滾時,權重越小的值被回滾
trx_mysql_thread_id:MySQL中的進程ID,與show processlist中的ID值相對應
trx_query:事務運行的SQL語句

2、找到持有鎖的線程 和 申請鎖被卡住的線程

SELECT * FROM INNODB_LOCK_WAITS where requesting_trx_id=11188391835

 申請鎖的線程id為:11188391835;而當前持有鎖的線程id為:11184617003

3、查看鎖的信息

SELECT * FROM INNODB_LOCKS WHERE lock_trx_id IN (11188391835,11184617003)

 可以看到線程 11184617003 持有主鍵上面的 X 鎖,而線程 11188391835申請 S 鎖被卡住;、

4、查看 持有鎖的線程的mysql線程id

SELECT TIMESTAMPDIFF(SECOND,trx_started,NOW()),innodb_trx.* FROM innodb_trx WHERE trx_id='11184617003'

 可以看到該線程的mysql的線程id為:11184617003;而且已經運行了 20186秒,也就是300多分鍾,而且他的權重 15416 很大,所以不會被回滾。所以導致線程 11184617003 被回滾。

而且我們看到他的 trx_query 為空。

所以解決方法就是:kill 141278145

 搞定。重新導入就可以了。

5、原因分析

初步調查原因應該是多個線程並發導入,導致了鎖沖突。因為每個線程都是導入十幾萬的數據,有多達十幾個線程並發導入,比較容易造成鎖沖突。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM