App下載

mysql數(shù)據(jù)庫(kù)死鎖:Deadlock found when trying to get lock; try restarting transaction

不許揪我的小耳朵 2021-08-26 17:06:47 瀏覽數(shù) (10865)
反饋

查看mysql死鎖日志

show engine innodb status

找到信息中LATEST DETECTED DEADLOCK這一行,可以看到mysql的死鎖信息詳情

------------------------
LATEST DETECTED DEADLOCK
------------------------
2021-08-25 14:13:37 0x7facac6b8700
*** (1) TRANSACTION:
TRANSACTION 1589867098, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
LOCK WAIT 508 lock struct(s), heap size 57552, 4 row lock(s)
MySQL thread id 201608808, OS thread handle 140379228206848, query id 3088485657 172.18.119.16 root updating
UPDATE web_viewlog SET viewcount=viewcount+1,lasttime='2021-08-25 14:13:37' WHERE uid=2150174 and kename='21es1mmi'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 564 page no 16179 n bits 208 index PRIMARY of table `w3cschool`.`web_viewlog` trx id 1589867098 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 16; compact format; info bits 0


MySQL有三種鎖的級(jí)別:頁(yè)級(jí)、表級(jí)、行級(jí)。

表級(jí)鎖:開銷小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。

行級(jí)鎖:開銷大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。

頁(yè)面鎖:開銷和加鎖時(shí)間界于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般。


行級(jí)鎖

行級(jí)鎖在使用的時(shí)候并不是直接鎖掉這行記錄,而是鎖索引
如果一條sql用到了主鍵索引(mysql主鍵自帶索引),mysql會(huì)鎖住主鍵索引;
如果一條sql操作了非主鍵索引,mysql會(huì)先鎖住非主鍵索引,再鎖定主鍵索引.


什么情況下會(huì)造成死鎖

所謂死鎖<DeadLock>: 是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過(guò)程中,
因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,若無(wú)外力作用,它們都將無(wú)法推進(jìn)下去。
此時(shí)稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖,這些永遠(yuǎn)在互相等竺的進(jìn)程稱為死鎖進(jìn)程。
表級(jí)鎖不會(huì)產(chǎn)生死鎖.所以解決死鎖主要還是針對(duì)于最常用的InnoDB。


收集死鎖信息:

  1. 利用命令 SHOW ENGINE INNODB STATUS查看死鎖原因。
  2. 調(diào)試階段開啟 innodb_print_all_deadlocks,收集所有死鎖日志。

減少死鎖:

  1. 使用事務(wù),不使用 lock tables 。
  2. 保證沒有長(zhǎng)事務(wù)。
  3. 操作完之后立即提交事務(wù),特別是在交互式命令行中。
  4. 如果在用 (SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),嘗試降低隔離級(jí)別。
  5. 修改多個(gè)表或者多個(gè)行的時(shí)候,將修改的順序保持一致。
  6. 創(chuàng)建索引,可以使創(chuàng)建的鎖更少。
  7. 最好不要用 (SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE)。
  8. 如果上述都無(wú)法解決問題,那么嘗試使用 lock tables t1, t2, t3 鎖多張表

 

解決方法

首先先用sql查詢一下mysql的事務(wù)處理表

select * from information_schema.INNODB_TRX;



正常情況下的狀態(tài)都是RUNNING,但是在被鎖之后就會(huì)變成LOCK WAIT ,

一旦出現(xiàn)這種情況,就得殺死這個(gè)進(jìn)程,如果進(jìn)程殺不死就只能重啟Mysql服務(wù)了。


殺死進(jìn)程

kill 進(jìn)程ID


0 人點(diǎn)贊