專案經常會出現mysql的死鎖問題,當年年少總是想通過select * from information_schema.innodb_locks; 檢視被鎖的事務,然後kill掉他,或者重啟mysql,唉,治標不治本啊,下次還會出現這些問題,其實造成死鎖大多數情況就是我們的sql寫的不大好。
我們先來模擬一組死鎖,然後通過檢視死鎖日誌再反向推出死鎖的原因。
首先我們新建乙個表:
create table `t1` (
`a` int(11) not null default '0',
`b` varchar(20) default null,
`c` varchar(100) default null,
primary key (`a`),
key `a_mes` (`b`) using hash
) engine=innodb default charset=utf8;
這裡引擎用innodb,並且在b欄位建了乙個索引『a_mes』,先在表裡加幾行資料:
insert into `test`.`t1` (`a`, `b`, `c`) values ('1', 'aaa', null);
insert into `test`.`t1` (`a`, `b`, `c`) values ('2', 'asd', null);
insert into `test`.`t1` (`a`, `b`, `c`) values ('3', 'axd', null);
insert into `test`.`t1` (`a`, `b`, `c`) values ('4', 'bbb', null);
然後我這裡的事務級別是rr,可以檢視下,select @@tx_isolation;
這裡有個姿勢點,事務級別是rr的時候,當進行iud操作的時候,如果指定的是非唯一索引的那個字段,rr級別下,會加gap鎖,比如我這裡b欄位上有非唯一索引,當我執行語句delete from t1 where b='aaa';的時候就會加gap鎖,也就是相當於在0-aaa,aaa-asd的範圍加上了gap鎖,同時aaa也會加x鎖。所以接下來模擬兩個事務:
事務一:set autocommit=0;
1.delete from t1 where b='aaa';
2.insert into t1 values(19,'baa','1');
事務二:set autocommit=0;
1.delete from t1 where b='bbb';
2.insert into t1 values(16,'aab','1');
當事務一執行第1條語句時,正如前面所說aaa索引加了x鎖,並且在aaa範圍內加了gap鎖,這時事務二執行弟1條語句,同理bbb索引也會加了x鎖,並且在axd-bbb,bbb-無窮大範圍加了gap鎖,然後事務一繼續執行第二條語句,這個時候由於事務二加了鎖,事務一就等待鎖,事務二執行弟2條語句後,就報錯了,這個就模擬了一組死鎖。
然後我們檢視死鎖日誌:show engine innodb status \g
通過日誌我們看到事務一在執行insert into t1 values(19,'baa','1');這句的時候,他要去獲得索引『a_mes』上的x鎖,但是獲得不到,所以在waiting。。。而事務二,在索引a_mes上持有x鎖,並且事務二在執行insert into t1 values(16,'aab','1');這句的時候也是獲得不到鎖,然後處於waiting狀態。。。
會檢視死鎖日誌,懂得mysql的加鎖機制,去反推業務的邏輯,去查詢真正造成死鎖的原因,然後解決他,如果不了解gap鎖推薦這篇文章,寫的很好
mysql 死鎖模擬 mysql死鎖示例
mysql有三種鎖的級別 頁級 表級 行級。myisam和memory儲存引擎採用的是表級鎖 table level locking bdb儲存引擎採用的是頁面鎖 page level locking 但也支援表級鎖 innodb儲存引擎既支援行級鎖 row level locking 也支援表級鎖...
mysql怎麼模擬死鎖 mysql 模擬產生死鎖
場景描述 在update表的時候出現deadlockloserdataacces ception異常 deadlock found when trying to get lock try restarting transaction.問題分析 這個異常並不會影響使用者使用,因為資料庫遇到死鎖會自動回...
mysql 死鎖語句 MySQL死鎖
死鎖產生 行鎖的具體實現演算法有三種 record lock gap lock以及next key lock。record lock是專門對索引項加鎖 gap lock是對索引項之間的間隙加鎖 next key lock則是前面兩種的組合,對索引項及其之間的間隙加鎖。只在可重複讀或以上隔離級別下的特...