回顧一下線上資料庫(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
Session2:
Update a set key=xxx where id=xxx –-holdserver lock and acquire row lock
Session1:
同上;--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老畢的部落格” 部落格,請務必保留此出處http://boylook.blog.51cto.com/7934327/1298750