1. 程式人生 > >資料更新導致鎖表

資料更新導致鎖表

 一、資料表結構

12345678910CREATE TABLE `jx_attach` (`attach_id` int(11) NOT NULL AUTO_INCREMENT,`feed_id` int(11) DEFAULT NULL ,`attach_name` varchar(255) NOT NULL,`cycore_file_id` varchar(255) DEFAULT NULL `attach_size` bigint(20) NOT NULL DEFAULT '0',`complete` smallint(6) NOT NULL DEFAULT '0' ,PRIMARY KEY
 (`attach_id`),KEY `jx_trend_attach_FK` (`feed_id`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=394160 DEFAULT CHARSET=utf8;

二、現象

  當多個連線同時對一個表的資料進行更新操作,那麼速度將會越來越慢,持續一段時間後將出現資料表被鎖,從而影響到其它的查詢及更新。  

儲存過程迴圈30次更新操作

12345678/*30次更新操作*/BEGINDECLARE v1 INT DEFAULT 30;WHILE v1 > 0 DOupdate jx_attach set complete=1,attach_size=63100 
where cycore_file_id='56677142da502cd8907eb58f';SET v1 = v1 - 1;END WHILE;END

執行結果(速度非常慢)

時間: 29.876s

Procedure executed successfully
受影響的行: 0

200個數據更新操作,三個資料庫連線同時執行

1234567update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';update jx_attach set complete=1,attach_size=63100 
where cycore_file_id='56677142da502cd8907eb58f';update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';...等等

執行結果(持續一段時間後速度越來越慢,出現等待鎖) 

複製程式碼

# Time: 151208 22:41:24
# [email protected]: zmduan[zmduan] @ [192.168.235.1] Id: 2
# Query_time: 1.848644 Lock_time: 0.780778 Rows_sent: 0 Rows_examined: 393382
SET timestamp=1449643284;
update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';

.........
........

# User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2 # Query_time: 2.868598 Lock_time: 1.558542 Rows_sent: 0 Rows_examined: 393382 SET timestamp=1449643805; update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f'; [[email protected] log]# tail -f slow_query.log # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 19 # Query_time: 1.356797 Lock_time: 0.000169 Rows_sent: 1 Rows_examined: 393383 SET timestamp=1449643805; SELECT * FROM jx_attach ja,jx_feed jf where ja.feed_id=jf.feed_id and ja.cycore_file_id='56677146da502cd8907eb5b7'; # User@Host: zmduan[zmduan] @ [192.168.235.1] Id: 2 # Query_time: 2.868598 Lock_time: 1.558542 Rows_sent: 0 Rows_examined: 393382 SET timestamp=1449643805; update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';
複製程式碼

 三、原因分析

MySQL的innodb儲存引擎支援行級鎖,innodb的行鎖是通過給索引項加鎖實現的,這就意味著只有通過索引條件檢索資料時,innodb才使用行鎖,否則使用表鎖。根據當前的資料更新語句(update jx_attach set complete=1,attach_size=63100 where cycore_file_id='56677142da502cd8907eb58f';),該條件欄位cycore_file_id並沒有新增索引,所以導致資料表被鎖。

四、解決辦法

為cycore_file_id新增索引

五、最終效果(30次更新操作)

時間: 0.094s

Procedure executed successfully
受影響的行: 0