回顧一下線上資料庫(5.1.68)的CASE,高峰期的時候出現了大量的thread_running,發現基本上線程處于deadlock狀态,涉及到的隻有一張表,并且隻有一行:
table a
(`id` smallint(5) unsigned NOT NULL DEFAULT'0',
`key` varchar(32) NOT NULL,
`value` varchar(32) NOT NULL,
`time` int(10) unsigned NOT NUL)engine=innodb;
資料庫的版本是5.1.68 innodb-plugin;原來的邏輯是:
Lock table awrite;讀取并更新該表;unlocktable;
後來改了邏輯begin;select id,key,value from a for update;更新;commit;
而出現問題的時候這2個邏輯同時存在,這就造成了MySQL Server層和Storage層的死鎖;
一種時序如下
Session1:
begin;
Select * from a for update ; -- lock everyrow in execlusive mode
Session2:
Lock table a write; -- lock table a in server
Update a set key=xxx where id=xxx –-holdserver lock and acquire row lock
同上;--hold row lock andacquire server lock
是以發生了死鎖;原因是RD釋出代碼隻釋出了一部分,後來復原解決了;另外一個Solution就是将該表改成MyISAM引擎,這樣就破除了row lock;
不過這個問題在5.5通過引入MDL解決了,當這裡session2執行lock table t write時會被阻塞在:Waiting for table metadata lock 上,打破了死鎖條件
本文轉自MIKE老畢 51CTO部落格,原文連結:http://blog.51cto.com/boylook/1298750,如需轉載請自行聯系原作者