数据库 / 各种锁
一、加鎖的目的是什么?
數(shù)據(jù)庫(kù)的鎖是為了解決事務(wù)的隔離性問題,為了讓事務(wù)之間相互不影響,每個(gè)事務(wù)進(jìn)行操作的時(shí)候都會(huì)對(duì)數(shù)據(jù)加上一把特有的鎖,防止其他事務(wù)同時(shí)操作數(shù)據(jù)。
如果你想一個(gè)人靜一靜,不被別人打擾,那么請(qǐng)?jiān)谀愕姆块T上加上一把鎖。
二、鎖實(shí)是基于什么實(shí)現(xiàn)的?
為了后面大家對(duì)鎖理解的更透徹,所以務(wù)必要對(duì)此進(jìn)行說明,鎖是基于什么實(shí)現(xiàn)的,你現(xiàn)實(shí)生活中家里的鎖是基于門來實(shí)現(xiàn)的,那么數(shù)據(jù)庫(kù)的鎖又是基于什么實(shí)現(xiàn)的呢? 那么我在這里可以告訴你,數(shù)據(jù)庫(kù)里面的鎖是基于索引實(shí)現(xiàn)的。在 Innodb 中我們的鎖都是作用在索引上面的,當(dāng)我們的 SQL 命中索引時(shí),那么鎖住的就是命中條件內(nèi)的索引節(jié)點(diǎn)(行鎖),如果沒有命中索引的話,那我們鎖的就是整個(gè)索引樹(表鎖),如下圖一下鎖住的是整棵樹還是某幾個(gè)節(jié)點(diǎn),完全取決于你的條件是否有命中到對(duì)應(yīng)的索引節(jié)點(diǎn)。
innodb索引結(jié)構(gòu)圖(B+ tree):
三、鎖的分類
數(shù)據(jù)庫(kù)里有的鎖有很多種,為了方面理解,所以我根據(jù)其相關(guān)性"人為"的對(duì)鎖進(jìn)行了一個(gè)分類,分別如下
四、屬性鎖
1、共享鎖(Share Lock)
共享鎖又稱讀鎖,簡(jiǎn)稱 S 鎖。當(dāng)一個(gè)事務(wù)為數(shù)據(jù)加上讀鎖之后,其他事務(wù)只能對(duì)該數(shù)據(jù)加讀鎖,而不能對(duì)數(shù)據(jù)加寫鎖,直到所有的讀鎖釋放之后其他事務(wù)才能對(duì)其進(jìn)行加持寫鎖。
共享鎖的特性主要是為了支持并發(fā)的讀取數(shù)據(jù),讀取數(shù)據(jù)的時(shí)候不支持修改,避免出現(xiàn)重復(fù)讀的問題。
2、排他鎖(Exclusive Lock)
排他鎖又稱寫鎖,簡(jiǎn)稱 X 鎖。當(dāng)一個(gè)事務(wù)為數(shù)據(jù)加上寫鎖時(shí),其他請(qǐng)求將不能再為數(shù)據(jù)加任何鎖,直到該鎖釋放之后,其他事務(wù)才能對(duì)數(shù)據(jù)進(jìn)行加鎖。
排他鎖的目的是在數(shù)據(jù)修改時(shí)候,不允許其他人同時(shí)修改,也不允許其他人讀取。避免了出現(xiàn)臟數(shù)據(jù)和臟讀的問題。
五、粒度鎖
1、表鎖
表鎖是指上鎖的時(shí)候鎖住的是整個(gè)表,當(dāng)下一個(gè)事務(wù)訪問該表的時(shí)候,必須等前一個(gè)事務(wù)釋放了鎖才能進(jìn)行對(duì)表進(jìn)行訪問。
特點(diǎn): 粒度大,加鎖簡(jiǎn)單,容易沖突;
2、行鎖
行鎖是指上鎖的時(shí)候鎖住的是表的某一行或多行記錄,其他事務(wù)訪問同一張表時(shí),只有被鎖住的記錄不能訪問,其他的記錄可正常訪問;
特點(diǎn):粒度小,加鎖比表鎖麻煩,不容易沖突,相比表鎖支持的并發(fā)要高。
3、記錄鎖(Record Lock)
記錄鎖也屬于行鎖中的一種,只不過記錄鎖的范圍只是表中的某一條記錄,記錄鎖是說事務(wù)在加鎖后鎖住的只是表的某一條記錄。
觸發(fā)條件:精準(zhǔn)條件命中,并且命中的條件字段是唯一索引。
例如:update user_info set name=’張三’ where id=1,這里的 id 是唯一索引。
記錄鎖的作用:加了記錄鎖之后數(shù)據(jù)可以避免數(shù)據(jù)在查詢的時(shí)候被修改的重復(fù)讀問題,也避免了在修改的事務(wù)未提交前被其他事務(wù)讀取的臟讀問題。
4、間隙鎖(Gap Lock)
間隙鎖屬于行鎖中的一種,間隙鎖是在事務(wù)加鎖后其鎖住的是表記錄的某一個(gè)區(qū)間,當(dāng)表的相鄰 ID 之間出現(xiàn)空隙則會(huì)形成一個(gè)區(qū)間,遵循左開右閉原則。
比如下面的表里面的數(shù)據(jù) ID 為 1、4、5、7、10 ,那么會(huì)形成以下幾個(gè)間隙區(qū)間,-n-1 區(qū)間,1-4 區(qū)間,7-10 區(qū)間,10-n 區(qū)間(-n 代表負(fù)無窮大,n 代表正無窮大)。
觸發(fā)條件:范圍查詢并且查詢未命中記錄,查詢條件必須命中索引、間隙鎖只會(huì)出現(xiàn)在 REPEATABLE_READ(重復(fù)讀)的事務(wù)級(jí)別中。
例如:對(duì)應(yīng)上圖的表執(zhí)行 select * from user_info where id > 1 and id < 4(這里的 id 是唯一索引) ,這個(gè) SQL 查詢不到對(duì)應(yīng)的記錄,那么此時(shí)會(huì)使用間隙鎖。
間隙鎖作用:防止幻讀問題,事務(wù)并發(fā)的時(shí)候,如果沒有間隙鎖,就會(huì)發(fā)生如下圖的問題,在同一個(gè)事務(wù)里,A 事務(wù)的兩次查詢出的結(jié)果會(huì)不一樣。
?
5、臨鍵鎖(Next-Key Lock)
臨鍵鎖也屬于行鎖的一種,并且它是 INNODB 的行鎖默認(rèn)算法,總結(jié)來說它就是記錄鎖和間隙鎖的組合,臨鍵鎖會(huì)把查詢出來的記錄鎖住,同時(shí)也會(huì)把該范圍查詢內(nèi)的所有間隙空間也會(huì)鎖住,再之它會(huì)把相鄰的下一個(gè)區(qū)間也會(huì)鎖住。
例如:下面表的數(shù)據(jù)執(zhí)行 select * from user_info where id > 1 and id <= 13 for update 。
會(huì)鎖住 ID 為 1,5,10 的記錄;同時(shí)會(huì)鎖住,1 至 5,5 至 10,10 至 15 的區(qū)間。
觸發(fā)條件:范圍查詢并命中,查詢命中了索引。
臨鍵鎖的作用:結(jié)合記錄鎖和間隙鎖的特性,臨鍵鎖避免了在范圍查詢時(shí)出現(xiàn)臟讀、重復(fù)讀、幻讀問題。加了臨鍵鎖之后,在范圍區(qū)間內(nèi)數(shù)據(jù)不允許被修改和插入。
六、狀態(tài)鎖
狀態(tài)鎖包括意向共享鎖和意向排它鎖,把他們區(qū)分為狀態(tài)鎖的一個(gè)核心邏輯,是因?yàn)檫@兩個(gè)鎖都是都是描述是否可以對(duì)某一個(gè)表進(jìn)行加表鎖的狀態(tài)。
意向鎖的解釋:當(dāng)一個(gè)事務(wù)試圖對(duì)整個(gè)表進(jìn)行加鎖(共享鎖或排它鎖)之前,首先需要獲得對(duì)應(yīng)類型的意向鎖(意向共享鎖或意向共享鎖)。
1、意向共享鎖
當(dāng)一個(gè)事務(wù)試圖對(duì)整個(gè)表進(jìn)行加共享鎖之前,首先需要獲得這個(gè)表的意向共享鎖。
2、意向排他鎖
當(dāng)一個(gè)事務(wù)試圖對(duì)整個(gè)表進(jìn)行加排它鎖之前,首先需要獲得這個(gè)表的意向排它鎖。
為什么我們需要意向鎖?
意向鎖光從概念上可能有點(diǎn)難理解,所以我們有必要從一個(gè)案例來分析其作用,這里首先我們先要有一個(gè)概念那就是 innodb 加鎖的方式是基于索引,并且加鎖粒度是行鎖,然后我們來看下面的案例。
第一步:
事務(wù) A 對(duì) user_info 表執(zhí)行一個(gè)SQL:update user_info set name = “張三” where id = 6 加鎖情況如下圖;
第二步:
與此同時(shí)數(shù)據(jù)庫(kù)又接收到事務(wù) B 修改數(shù)據(jù)的請(qǐng)求 SQL:update user_info set name =“李四”。
思考:
在 A 事務(wù)的操作過程中,后面的每個(gè)需要對(duì) user_info 加持表鎖的事務(wù)都需要遍歷整個(gè)索引樹才能知道自己是否能夠進(jìn)行加鎖,這種方式是不是太浪費(fèi)時(shí)間和損耗數(shù)據(jù)庫(kù)性能了?
所以就有了意向鎖的概念:如果當(dāng)事務(wù) A 加鎖成功之后就設(shè)置一個(gè)狀態(tài)告訴后面的人,已經(jīng)有人對(duì)表里的行加了一個(gè)排他鎖了,你們不能對(duì)整個(gè)表加共享鎖或排它鎖了,那么后面需要對(duì)整個(gè)表加鎖的人只需要獲取這個(gè)狀態(tài)就知道自己是不是可以對(duì)表加鎖,避免了對(duì)整個(gè)索引樹的每個(gè)節(jié)點(diǎn)掃描是否加鎖,而這個(gè)狀態(tài)就是我們的意向鎖。
?
轉(zhuǎn)載于:https://zhuanlan.zhihu.com/p/52312376
?
(SAW:Game Over!)
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
- 上一篇: OS / 5 种 IO 模型
- 下一篇: MySQL / 各种锁