MySQL / 各种锁
一、相關(guān)名詞
- 表級鎖:鎖定整個(gè)表。
- 頁級鎖:鎖定一頁。
- 行級鎖:鎖定一行。
- 間隙鎖(Next-Key):鎖定不存在記錄的間隙。
- 共享鎖:S 鎖,MyISAM 叫做讀鎖。
- 排他鎖:X 鎖,MyISAM 叫做寫鎖。
- 悲觀鎖:抽象性,不真實(shí)存在這個(gè)鎖。
- 樂觀鎖:抽象性,不真實(shí)存在這個(gè)鎖。
二、InnoDB 與 MyISAM
Mysql 在5.5之前默認(rèn)使用 MyISAM 存儲引擎,之后使用 InnoDB 。查看當(dāng)前存儲引擎:
show variables like '%storage_engine%';MyISAM 操作數(shù)據(jù)都是使用的表鎖,你更新一條記錄就要鎖整個(gè)表,導(dǎo)致性能較低,并發(fā)不高。當(dāng)然同時(shí)它也不會存在死鎖問題。
而 InnoDB 與 MyISAM 的最大不同有兩點(diǎn):一是 InnoDB 支持事務(wù);二是 InnoDB 采用了行級鎖。也就是你需要修改哪行,就可以只鎖定哪行。
索引分為主鍵索引和非主鍵索引兩種,如果一條 sql 語句操作了主鍵索引,Mysql 就會鎖定這條主鍵索引;如果一條語句操作了非主鍵索引,MySQL會先鎖定該非主鍵索引,再鎖定相關(guān)的主鍵索引。
InnoDB 行鎖是通過給索引項(xiàng)加鎖實(shí)現(xiàn)的,如果沒有索引,InnoDB 會通過隱藏的聚簇索引來對記錄加鎖。也就是說:如果不通過索引條件檢索數(shù)據(jù),那么InnoDB將對表中所有數(shù)據(jù)加鎖,實(shí)際效果跟表鎖一樣。因?yàn)闆]有了索引,找到某一條記錄就得掃描全表,要掃描全表,就得鎖定表。
三、行鎖
在 Mysql 中,行級鎖并不是直接鎖記錄,而是鎖索引。InnoDB行鎖是通過給索引上的索引項(xiàng)加鎖來實(shí)現(xiàn)的,這一點(diǎn)MySQL與Oracle不同,后者是通過在數(shù)據(jù)塊中對相應(yīng)數(shù)據(jù)行加鎖來實(shí)現(xiàn)的。?InnoDB 這種行鎖實(shí)現(xiàn)特點(diǎn)意味著:只有通過索引條件檢索數(shù)據(jù),InnoDB 才使用行級鎖,否則,InnoDB 將使用表鎖!
即便在條件中使用了索引字段,但是否使用索引來檢索數(shù)據(jù)是由 MySQL 通過判斷不同執(zhí)行計(jì)劃的代價(jià)來決定的,如果 MySQL 認(rèn)為全表掃描效率更高,比如對一些很小的表,它就不會使用索引,這種情況下InnoDB 將使用表鎖,而不是行鎖。因此,在分析鎖沖突時(shí),別忘了檢查 SQL 的執(zhí)行計(jì)劃,以確認(rèn)是否真正使用了索引。
四、間隙鎖
當(dāng)我們用范圍條件而不是相等條件檢索數(shù)據(jù),并請求共享或排他鎖時(shí),InnoDB 會給符合條件的已有數(shù)據(jù)記錄的索引項(xiàng)加鎖;對于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”,InnoDB 也會對這個(gè)“間隙”加鎖,這種鎖機(jī)制就是所謂的間隙鎖(Next-Key鎖)。
舉例來說,假如 emp 表中只有 101 條記錄,其 empid 的值分別是 1、2、…、100、101,下面的 SQL:
Select * from emp where empid > 100 for update;該 SQL 是一個(gè)范圍條件的檢索,InnoDB 不僅會對符合條件的 empid 值為 101 的記錄加鎖,也會對 empid 大于 101(這些記錄并不存在)的“間隙”加鎖。
InnoDB 使用間隙鎖的目的,一方面是為了防止幻讀,以滿足相關(guān)隔離級別的要求。對于上面的例子,要是不使用間隙鎖,如果其他事務(wù)插入了 empid 大于 100 的任何記錄,那么本事務(wù)如果再次執(zhí)行上述語句,就會發(fā)生幻讀。
很顯然,在使用范圍條件檢索并鎖定記錄時(shí),InnoDB 這種加鎖機(jī)制會阻塞符合條件范圍內(nèi)鍵值的并發(fā)插入,這往往會造成嚴(yán)重的鎖等待。因此,在實(shí)際應(yīng)用開發(fā)中,尤其是并發(fā)插入比較多的應(yīng)用,我們要盡量優(yōu)化業(yè)務(wù)邏輯,盡量使用相等條件來訪問更新數(shù)據(jù),避免使用范圍條件。
還要特別說明的是,InnoDB 除了通過范圍條件加鎖時(shí)使用間隙鎖外,如果使用相等條件請求給一個(gè)不存在的記錄加鎖,InnoDB 也會使用間隙鎖!
?
轉(zhuǎn)載于:https://blog.csdn.net/localhost01/article/details/78720727
?
(SAW:Game Over!)
總結(jié)
以上是生活随笔為你收集整理的MySQL / 各种锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++ / 函数调用规则汇总
- 下一篇: MySQL / 多版本并发控制