MySQL - 锁等待及死锁初探
生活随笔
收集整理的這篇文章主要介紹了
MySQL - 锁等待及死锁初探
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- 生猛干貨
- 版本信息
- MySQL 行鎖分析
- MySQL死鎖演示
- 排查過(guò)程
- 查看近期死鎖日志信息
- 查詢鎖等待命令及kill 鎖
- 優(yōu)化建議
- 搞定MySQL
生猛干貨
帶你搞定MySQL實(shí)戰(zhàn),輕松對(duì)應(yīng)海量業(yè)務(wù)處理及高并發(fā)需求,從容應(yīng)對(duì)大場(chǎng)面試
版本信息
mysql> select version(); +-----------+ | version() | +-----------+ | 5.7.28 | +-----------+ 1 row in setmysql>MySQL 行鎖分析
mysql> show status like'innodb_row_lock%'; +-------------------------------+--------+ | Variable_name | Value | +-------------------------------+--------+ | Innodb_row_lock_current_waits | 0 | | Innodb_row_lock_time | 222821 | | Innodb_row_lock_time_avg | 27852 | | Innodb_row_lock_time_max | 51017 | | Innodb_row_lock_waits | 8 | +-------------------------------+--------+ 5 rows in setmysql>變量說(shuō)明:
- Innodb_row_lock_current_waits 當(dāng)前正在等待鎖定的數(shù)量 單位毫秒
- Innodb_row_lock_time 從系統(tǒng)啟動(dòng)到現(xiàn)在鎖定總時(shí)間長(zhǎng)度 單位毫秒
- Innodb_row_lock_time_avg 每次等待所花平均時(shí)間 單位毫秒
- Innodb_row_lock_time_max 從系統(tǒng)啟動(dòng)到現(xiàn)在等待最長(zhǎng)的一次所花時(shí)間 單位毫秒
- Innodb_row_lock_waits 系統(tǒng)啟動(dòng)后到現(xiàn)在總共等待的次數(shù)
重點(diǎn)關(guān)注 : Innodb_row_lock_time_avg 、Innodb_row_lock_waits 、Innodb_row_lock_time
MySQL死鎖演示
事務(wù)隔離級(jí)別, 默認(rèn) 可重復(fù)讀
mysql> show variables like '%tx_isolation%'; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | tx_isolation | REPEATABLE-READ | +---------------+-----------------+ 1 row in setmysql>【操作步驟】
| begin 模擬開啟事務(wù) | |
| select * from art_info where id=1 for update; | |
| begin 模擬開啟事務(wù) | |
| select * from account where id=2 for update; | |
| select * from art_info where id=2 for update; ---->一直等待 | |
| select * from art_info where id=1 for update; —> Deadlock found when trying to get lock; try restarting transaction |
大多數(shù)情況mysql可以自動(dòng)檢測(cè)死鎖并回滾產(chǎn)生死鎖的那個(gè)事務(wù),但是有些情況mysql沒(méi)法自動(dòng)檢測(cè)死鎖
排查過(guò)程
【模擬鎖等待 】
| begin 模擬開啟事務(wù) | |
| select * from art_info where id=1 for update; | |
| begin 模擬開啟事務(wù) | |
| select * from account where id=2 for update; | |
| select * from account where id=2 for update; |
-- 查看事務(wù) select * from information_schema.INNODB_TRX; -- 查看鎖 select * from information_schema.INNODB_LOCKS; -- 查看鎖等待 select * from information_schema.INNODB_LOCK_WAITS;-- 鎖釋放 information_schema.INNODB_TRX 查詢 trx_mysql_thread_id 然后去 kill 對(duì)應(yīng)的value kill trx_mysql_thread_id
來(lái)吧 ,用上面的SQL查吧
查看近期死鎖日志信息
show engine innodb status \G;查詢鎖等待命令及kill 鎖
-- 查看事務(wù) select * from information_schema.INNODB_TRX; -- 查看鎖 select * from information_schema.INNODB_LOCKS; -- 查看鎖等待 select * from information_schema.INNODB_LOCK_WAITS;-- 鎖釋放 information_schema.INNODB_TRX 查詢 trx_mysql_thread_id 然后去 kill 對(duì)應(yīng)的value kill trx_mysql_thread_id鎖等待有自己的超時(shí)時(shí)間,超過(guò)后一般都會(huì)自動(dòng)釋放
mysql> select * from art_info where id =2 for update ; 1205 - Lock wait timeout exceeded; try restarting transaction優(yōu)化建議
- 盡可能讓所有數(shù)據(jù)檢索都通過(guò)索引來(lái)完成,避免無(wú)索引行鎖升級(jí)為表鎖
- 合理設(shè)計(jì)索引,盡量縮小鎖的范圍
- 盡可能減少檢索條件范圍,避免間隙鎖
- 盡量控制事務(wù)大小,減少鎖定資源量和時(shí)間長(zhǎng)度,涉及事務(wù)加鎖的sql盡量放在事務(wù)最后執(zhí)行
- 盡可能低級(jí)別事務(wù)隔離
搞定MySQL
總結(jié)
以上是生活随笔為你收集整理的MySQL - 锁等待及死锁初探的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MySQL - 践行索引优化
- 下一篇: MySQL - 无索引行锁升级为表锁