Mysql 由淺入深論行鎖

2021-08-28 21:44:15 字數 2707 閱讀 9718

對於mysql innodb的各種鎖,這裡不採用堆文字的講解方式,我們來從現象到本質,先看現象,再來說明其中的道理。

我使用的是mysql 5.5,預設隔離別-可重複讀。

建了一張表,如下圖:

id為主鍵,student_num上有唯一索引,score分數上有普通索引,nameage沒有索引。

建表語句如下:

create table `student` (

`id` bigint(20) unsigned not null auto_increment comment '主鍵',

`name` varchar(100) not null,

`student_num` varchar(100) not null,

`age` int(10) not null comment '年齡',

`score` int(10) not null comment '分數',

primary key (`id`),

unique key `idx_stu_num` (`student_num`) using btree,

key `idx_score` (`score`) using btree

) engine=innodb

現象1

如上圖,左側執行了一條更新語句,但是事物還未提交。

現在,如果執行紅框中的sql,會出現鎖等待,需要等待左側的事物提交,否則,他會等待到超時。

這就是行鎖。

行鎖,鎖的是索引鍵

現象2

如上圖,儘管查詢的不是同一行,但是紅框內sql執行的時候還是會出現鎖等待,原因就是他們使用了相同的索引鍵。innodb在實現行鎖的時候,並不是在記錄行上加的鎖,而是在索引上加的。

如下兩條sql:

update student set score = 60 where id=1;

update student set score = 60 where id=1 and student_num="x001";

由於都使用了id=1的主鍵索引鍵,所以會出現鎖等待。

如果沒有索引,變成表鎖

現象3

age列沒有索引,innodb會直接使用表鎖(表鎖即鎖住所有行)。所以即使查詢的不是相同的列,還是會鎖等待。

即使有索引,也可能變成表鎖

現象4

如上圖,student表中加了乙個性別字段***,並且***加了乙個索引。然後表中一共有4條資料,3男1女,然而當執行紅框中的sql還是會出現鎖等待,why???

另外,如果你將3個男的記錄中的任意兩條刪掉,再做上面的實驗,你會驚喜的發現,不會等鎖了。

原因在於innodb有個優化器,當你的索引區分度不大的時候,他會直接走全表掃瞄,根本不走索引。

所以上面的例子就是全表掃秒,導致成了表鎖。當你刪除,兩條男的資料之後,***的區分度又好了,成了行鎖。

優化器不使用索引選擇全表掃瞄比如一張order表中有聯合索引(order_id, goods_id),在此例子上來說明這個問題是從兩個方面來說:

查詢欄位在索引中 select order_id from order where order_id > 1000,

如果檢視其執行計畫的話,發現是用use index condition,走的是索引覆蓋。

查詢欄位不在索引中 select * from order where order_id > 1000,

此條語句查詢的是該錶所有字段,有一部分字段並未在此聯合索引中,因此走聯合索引查詢會走兩步,首先通過聯合索引確定符合條件的主鍵id,然後利用這些主鍵id再去聚簇索引中去查詢,然後得到所有記錄,利用主鍵id在聚簇索引中查詢記錄的過程是無序的,在磁碟上就變成了離散讀取的操作,假如當讀取的記錄很多時(一般是整個表的20%左右),這個時候優化器會選擇直接使用聚簇索引,也就是掃全表,因為順序讀取要快於離散讀取,這也就是為何一般不用區分度不大的字段單獨做索引,注意是單獨因為利用此欄位查出來的資料會很多,有很大概率走全表掃瞄。

總而言之,加了索引,但是sql執行的時候並沒有走索引,所以就變成了表鎖。

mysql 行鎖 訂票 mysql 行鎖

在電子商務裡,經常會出現庫存數量少,購買的人又特別多,大併發情況下如何確保商品數量不會被多次購買.其實很簡單,利用事務 for update就可以解決.我們都知道for update實際上是共享鎖,是可以被讀取的.但是如何在執行時,不被讀取呢.簡單來說 假設現在庫存為1,現在有a和b同時購買 先開啟...

mysql行鎖詳解 詳解MySQL行鎖

鎖是計算機協調多個程序或執行緒併發訪問某一資源的機制。鎖保證資料併發訪問的一致性 有效性 鎖衝突也是影響資料庫併發訪問效能的乙個重要因素。鎖是mysql在伺服器層和儲存引擎層的的併發控制。mysql中從對資料操作的粒度分為表鎖和行鎖。表鎖是指對一整張表加鎖,一般是 ddl 處理時使用 而行鎖則是鎖定...

mysql行鎖的特性 MySql的表鎖行鎖及間隙鎖

常用命令 手動新增表鎖 lock table 表名稱 read write 表名稱2 read write 檢視表上加過的鎖 show open tables 刪除表鎖 unlock tables 1.表鎖 特點 1.每次操作鎖住整張表,開銷小,加鎖快 2.不會出現死鎖 3.鎖定粒度大,發生鎖衝突的...