mysql鎖等待/死鎖

對(duì)于 5.7 版本,出現(xiàn)鎖等待時(shí),我們可以查看 information_schema 中的幾張系統(tǒng)表來(lái)查詢事務(wù)狀態(tài)。

innodb_trx 當(dāng)前運(yùn)行的所有事務(wù)。
innodb_locks 當(dāng)前出現(xiàn)的鎖。
innodb_lock_waits 鎖等待的對(duì)應(yīng)關(guān)系

鎖等待發(fā)生時(shí) 查看innodb_trx表可以看到所有事務(wù)
trx_state值為L(zhǎng)OCK WAIT 則代表該事務(wù)處于等待狀態(tài)

mysql> select * from information_schema.innodb_trx\G

# innodb_trx 字段值含義
trx_id:事務(wù)ID。
trx_state:事務(wù)狀態(tài),有以下幾種狀態(tài):RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING。
trx_started:事務(wù)開(kāi)始時(shí)間。
trx_requested_lock_id:事務(wù)當(dāng)前正在等待鎖的標(biāo)識(shí),可以和 INNODB_LOCKS 表 JOIN 以得到更多詳細(xì)信息。
trx_wait_started:事務(wù)開(kāi)始等待的時(shí)間。
trx_weight:事務(wù)的權(quán)重。
trx_mysql_thread_id:事務(wù)線程 ID,可以和 PROCESSLIST 表 JOIN。
trx_query:事務(wù)正在執(zhí)行的 SQL 語(yǔ)句。
trx_operation_state:事務(wù)當(dāng)前操作狀態(tài)。
trx_tables_in_use:當(dāng)前事務(wù)執(zhí)行的 SQL 中使用的表的個(gè)數(shù)。
trx_tables_locked:當(dāng)前執(zhí)行 SQL 的行鎖數(shù)量。
trx_lock_structs:事務(wù)保留的鎖數(shù)量。
trx_isolation_level:當(dāng)前事務(wù)的隔離級(jí)別。

# sys.innodb_lock_waits 視圖也可看到事務(wù)等待狀況,且給出了殺鏈接的SQL
mysql> select * from sys.innodb_lock_waits\G

sys.innodb_lock_waits 視圖整合了事務(wù)等待狀況,同時(shí)給出殺掉堵塞源端的 kill 語(yǔ)句。不過(guò)是否要?dú)⒌翩溄舆€是需要綜合考慮的。


發(fā)生死鎖后會(huì)選擇一個(gè)事務(wù)進(jìn)行回滾,想查明死鎖原因,可以執(zhí)行 show engine innodb status 來(lái)查看死鎖日志,根據(jù)死鎖日志,結(jié)合業(yè)務(wù)邏輯來(lái)進(jìn)一步定位死鎖原因。

在實(shí)際應(yīng)用中,我們要盡量避免死鎖現(xiàn)象的發(fā)生,可以從以下幾個(gè)方面入手:

事務(wù)盡可能小,不要講復(fù)雜邏輯放進(jìn)一個(gè)事務(wù)里。
涉及多行記錄時(shí),約定不同事務(wù)以相同順序訪問(wèn)。
業(yè)務(wù)中要及時(shí)提交或者回滾事務(wù),可減少死鎖產(chǎn)生的概率。
表要有合適的索引。
可嘗試將隔離級(jí)別改為 RC 。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容