MySQL insert語句鎖分析


最近對insert的鎖操作比較費解,所以自己動手,一看究竟。主要是通過一下三個sql來看一下執行中的sql的到底使用了什么鎖。

select * from information_schema.INNODB_TRX\G; //記錄當前正在執行的事務,以及事務的一些狀態

select * from information_schema.INNODB_LOCKS\G; //包含了InnoDB事務鎖的具體情況,包括事務正在申請加的鎖和事務加上的鎖。

select * from information_schema.INNODB_LOCK_WAITS; //包含了blocked的事務的鎖等待的狀態

mysql的版本:5.6.25-73.1-log  使用了innodb,隔離級別是 REPEATABLE-READ

首先看下表結構: 表中有唯一鍵

分別在倆個事務中執行同樣的insert操作:

insert into room_poi_cut_result (poi_id,poi_orgunit_id,old_bd,new_bd,cut_reason,is_execute) values(12345,22,12,12,0,0);

首先看下 INNODB_TRX 表的數據:可以看到 事務10722584462處於執行狀態,事務10722584486處於阻塞狀態

然后再看下鎖的狀態:可以看到,事務10722584462和事務10722584486都是在獲取行鎖,一個是S鎖,一個是X鎖

最后我們看下 INNODB_LOCK_WAITS 這個表中的數據:可以看到事務10722584486正在被阻塞在10722584486:29178:10:638 這個鎖上,而這個鎖的持有者是事務10722584462

所以,這里可以得到結論,首先會在唯一鍵加上行鎖,其次insert語句會有一個鎖升級的過程,從S鎖升級到X鎖。

 

接下來做第二個實驗,在inser中加入 on update語句。

分別在倆個事務中執行同樣的insert操作:

insert into room_poi_cut_result (poi_id,poi_orgunit_id,old_bd,new_bd,cut_reason,is_execute) values(12345,22,12,12,0,0) on duplicate key update poi_id=12345;

然后再看下INNODB_TRX,INNODB_LOCKS,INNODB_LOCK_WAITS 這三個表的數據:

結論,首先會在唯一鍵加上行鎖,其次和第一次實驗不同的是,直接是在唯一鍵上加X鎖。

 

接下來做第三個實驗,把表的唯一鍵去掉,然后執行insert操作:

表結構:

然后在倆個事務中執行以下insert語句:

insert into room_poi_cut_result2 (poi_id,poi_orgunit_id,old_bd,new_bd,cut_reason,is_execute) values(12345,22,12,12,0,0);

結果沒有發生阻塞,看下INNODB_TRX 這個表中的數據:可以看到倆個事務都是在running狀態,而且trx_rows_locked 都是0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM