探索Mysql鎖機(jī)制(二)——共享鎖&排他鎖&意向鎖&間隙鎖

MileStone


上一篇,我們講了Mysql的樂觀鎖和悲觀鎖,大家有興趣可以連起來一起看。

本文需要閱讀時(shí)間大約在1小時(shí),請(qǐng)抽出完整的時(shí)間來閱讀,拒絕一目十行。

后面會(huì)按照下圖,分批次對(duì)Mysql的鎖和大家一起分享

image.png

??花絮


image.png

??仔細(xì)看哦 ??
今天采蜜采到一份看起來不錯(cuò)的簡歷,正襟危坐,電話call過去。
對(duì)方的電話響著粵語版的《明年今日》,讓我想起了村里的小芳,鞭子粗又長。
“喂,哪位?”,對(duì)方的聲音很Young很有錢。
“同學(xué)你好,我是巴巴的面試官,你對(duì)XX巴巴有興趣嗎,現(xiàn)在方不方便聊聊?”
“...你好,有啊,方便的。”
“okay,那我們簡單的聊一會(huì),你能先簡單的介紹一下自己嗎?”
“好,我叫小明,在OO上班,工作3年,無房無車,有個(gè)女朋友叫清風(fēng)...”
吧啦吧啦......
“項(xiàng)目用到了SpringBoot、MQ、Mysql...”
“好的,那我們聊一聊mysql的鎖吧!”

1. Mysql的事務(wù)


偉人說:“想了解一件事情,你就得了解它的前因后果”,
想了解透徹mysql的鎖,不得不說mysql的事務(wù)機(jī)制。

于是我問小明:你對(duì)mysql的事務(wù)了解嗎?
小明輕咳一下,娓娓道來:

1.1 事務(wù)概述

數(shù)據(jù)庫事務(wù)是數(shù)據(jù)庫執(zhí)行過程中的一個(gè)邏輯單位,一個(gè)事務(wù)通常包含了對(duì)數(shù)據(jù)庫的讀/寫操作。它的存在包含有以下兩個(gè)目的:

  • 為數(shù)據(jù)庫操作序列提供了一個(gè)回滾的方法,同時(shí)提供了數(shù)據(jù)庫即使在異常狀態(tài)下仍能保持一致性的方法。
  • 當(dāng)多個(gè)應(yīng)用程序在并發(fā)訪問數(shù)據(jù)庫時(shí),可以在這些應(yīng)用程序之間提供一個(gè)隔離方法(版面問題下次討論),以防止彼此的操作互相干擾。

1.2 事務(wù)的特性:ACID

  • 原子性 aotmic

事務(wù)必須是原子工作單元;對(duì)于其數(shù)據(jù)修改,要么全都執(zhí)行,要么全都不執(zhí)行。

  • 一致性 consistent

事務(wù)在完成時(shí),必須使所有的數(shù)據(jù)都保持一致狀態(tài)。

  • 隔離性 isolaton

由并發(fā)事務(wù)所作的修改必須與任何其它并發(fā)事務(wù)所作的修改隔離。事務(wù)查看數(shù)據(jù)時(shí)數(shù)據(jù)所處的狀 態(tài),要么是另一并發(fā)事務(wù)修改它之前的狀態(tài),要么是另一事務(wù)修改它之后的狀態(tài),事務(wù)不會(huì)查看中間狀態(tài)的數(shù)據(jù)

  • 持久性 duration

事務(wù)完成后,它對(duì)系統(tǒng)的影響是永久性的

2. 排他鎖&共享鎖


我心想,這個(gè)誰都懂,繼續(xù)追問:那你能在講講鎖嗎?
好的,那我講一下Mysql的幾個(gè)鎖。小明竊喜,我已經(jīng)看了imooc(公眾號(hào)微信)大神的鎖了,我怕你?

2.1 共享鎖(shared locks,S鎖)

小明說:在你沒有女朋友的時(shí)候,你想和女人滾床單時(shí)候,只能去找紅燈區(qū),別人也可以找紅燈區(qū),這就是共享!

共享鎖又叫讀鎖,如果事務(wù)T1對(duì)行R加上S鎖,則

  • 其它事務(wù)T2/T3/Tn只能對(duì)行R再加S鎖,不能加其它鎖
  • 獲得S鎖的事務(wù)只能讀數(shù)據(jù),不能寫數(shù)據(jù)(你傻呀,當(dāng)然也不能刪咯)。
select … lock in share mode;

2.2 排他鎖(exclusive locks,X鎖)

小明說:你有錢找了個(gè)女票,你就要獨(dú)占這個(gè)女票,別人不能使用,看(讀)都不行!這就是排他!我們重點(diǎn)說一下排它鎖。

排它鎖又叫寫鎖,如果事務(wù)T1對(duì)行R加上X鎖,則

  • 其它事務(wù)T2/T3/Tn都不能對(duì)行R加任何類型的鎖,直到T1事務(wù)在行R上的X鎖釋放。
  • 獲得X鎖的事務(wù)既能讀數(shù)據(jù),又能寫數(shù)據(jù)(也可以刪除數(shù)據(jù))。
select ... for update 

舉例表USER:

id name desc
1 馬云 首富
2 小明 首負(fù)

T1(事務(wù)1):

// start T1
SELECT * FROM USER WHERE id = 1 lock in share mode; (S鎖)
......

// start T2
UPDATE USER SET name = '小明' WHERE id = 1;
......

如果T1不進(jìn)行提交,則S鎖不會(huì)釋放,
那么T2就拿著X鎖眼巴巴的看著,一直等待T1(事務(wù)1)釋放S鎖。

此時(shí)

// 接上文代碼塊
// start T3
// 此時(shí),如果 T3 做同樣查詢,可以直接獲取S鎖進(jìn)行查詢
SELECT * FROM USER WHERE id = 1 lock in share mode; (S鎖)

這個(gè)時(shí)候如果T1(事務(wù)1)要進(jìn)行 DELETE 操作

// start T1
SELECT * FROM USER WHERE id = 1 lock in share mode; (S鎖)
......
DELETE FROM USER WHERE id = 1;
......

此時(shí):
T1發(fā)現(xiàn)X鎖被T2占據(jù)著,所以T1拿不到X鎖一直等待T2釋放X鎖,而T2拿著X鎖等待T1釋放S鎖,這樣互相等待就產(chǎn)生了死鎖,deadLock。
發(fā)生死鎖以后,InnoDB 會(huì)產(chǎn)生錯(cuò)誤信息,并且釋放鎖(后面會(huì)專門講業(yè)務(wù)中遇到的死鎖和解決方案)。

上述X鎖的代碼可以用下圖來顯示:

image.png

用時(shí)間流程來顯示3個(gè)線程的交互如下:

image.png

你可以把排它鎖對(duì)行的保護(hù),看作你對(duì)你女的保護(hù),只能你碰,別人不能動(dòng)!前提你得有女,不認(rèn)真學(xué)習(xí),你就是個(gè)屌絲...單身狗

聽到這里我覺得小明同學(xué)很有意思哦,這個(gè)栗子??舉得很有力氣很有代入感!不愧是有女朋友的人啊!

3. 意向鎖


我對(duì)小明已經(jīng)開始有點(diǎn)興趣了,繼續(xù)追問,那你能否再說一下意向鎖?
好!

3.1 意向鎖(Intention Locks)

小明說: 他在找蒼老師或者女票時(shí)候,先要遠(yuǎn)程看看對(duì)方有沒有被人家共享或者獨(dú)占,而不是到面前有沒有人鎖住她,可以節(jié)省成本!

意向鎖是表鎖,多用在innoDB中,是數(shù)據(jù)庫自身的行為,不需要人工干預(yù),在事務(wù)結(jié)束后會(huì)自行解除。

意向鎖分為意向共享鎖(IS鎖)和意向排它鎖(IX鎖)

  • 鎖:表示事務(wù)中將要對(duì)某些行加S鎖
  • IX鎖:表示事務(wù)中將要對(duì)某些行加X鎖

意向鎖的主要作用是提升存儲(chǔ)引擎性能,innoDB中的S鎖和X鎖是行鎖,每當(dāng)事務(wù)到來時(shí),存儲(chǔ)引擎需要遍歷所有行的鎖持有情況,性能較低,因此引入意向鎖,檢查行鎖前先檢查意向鎖是否存在,如果存在則阻塞線程。

3.2 意向鎖的使用

順上面的思路講下去,我們看下使用的邏輯

舉個(gè)栗子??:

T1:
SELECT * FROM A WHERE id = 1 lock in share mode;(加S鎖)

T2:
SELECT * FROM A WHERE id > 0 for update; (加X鎖)

看上面這2個(gè)SQL事務(wù),T1執(zhí)行時(shí)候,對(duì)id=1這行加上了S鎖,T2執(zhí)行前,需要獲取全表的更新鎖進(jìn)行判斷,即:
step1:判斷表A是否有表級(jí)鎖
step2:判斷表A每一行是否有行級(jí)鎖
當(dāng)數(shù)據(jù)量較大時(shí)候(我們一張表一般500-5000萬數(shù)據(jù)),step2這種判斷極其低效

亞麻跌!亞麻跌!亞麻跌!于是乎,我們就need意向鎖協(xié)議。

意向鎖協(xié)議

  • 事務(wù)要獲取表A某些行的S鎖必須要獲取表A的IS鎖
  • 事務(wù)要獲取表A某些行的X鎖必須要獲取表A的IX鎖

Now!do you get me sense ?
這個(gè)時(shí)候step2就改變成了對(duì)意向鎖的判斷
step2:發(fā)現(xiàn)表A有IS鎖,說明表肯定有行級(jí)的S鎖,因此,T2申請(qǐng)X鎖阻塞等待,不需要判斷全表,判斷效率極大提高(是不是省了很多錢)

4. 間隙鎖


小明先飚了一段英語,想來壓制我?
但是我并不care,who care?9012年了,誰不會(huì)英語?so easy!我可是從小用步步高點(diǎn)讀機(jī)長大的人哦。
我say:pardon ? (上小學(xué)我就會(huì),小樣,你再飚啊!)

4.0 官方原文:

image.png

非常重要,必須讀懂,讀不懂,就去幼兒園回爐吧,親

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record. For example, SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; prevents other transactions from inserting a value of 15 into column t.c1, whether or not there was already any such value in the column, because the gaps between all existing values in the range are locked.

當(dāng)我們用范圍條件條件檢索數(shù)據(jù)(非聚簇索引、非唯一索引),并請(qǐng)求共享或排他鎖時(shí),InnoDB會(huì)給符合條件的數(shù)據(jù)記錄的索引項(xiàng)加鎖;對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄,稱為間隙,InnoDB也會(huì)為這些間隙加鎖,即間隙鎖。
Next-Key鎖是符合條件的行鎖加上間隙鎖

4.1 間隙鎖產(chǎn)生的條件

在InnoDB下,間隙鎖的產(chǎn)生需要滿足三個(gè)條件:

  • 隔離級(jí)別為RR
  • 當(dāng)前讀
  • 查詢條件能夠走到索引

4.2 間隙鎖的作用

MySQL官方文檔:間隙鎖的目的是為了讓其他事務(wù)無法在間隙中新增數(shù)據(jù)。

在RR模式的InnoDB中,間隙鎖能起到兩個(gè)作用:

1. 保障數(shù)據(jù)的恢復(fù)和復(fù)制
2. 防止幻讀
  • 防止在間隙中執(zhí)行insert語句
  • 防止將已有數(shù)據(jù)update到間隙中

數(shù)據(jù)庫數(shù)據(jù)的恢復(fù)和復(fù)制是通過binlog實(shí)現(xiàn)的,binlog中記錄了執(zhí)行成功的DML語句(在阿里得到了極廣泛的應(yīng)用),在數(shù)據(jù)恢復(fù)時(shí)需要保證數(shù)據(jù)之間的事務(wù)順序,間隙鎖可以避免在一批數(shù)據(jù)中插入其他事務(wù)。

對(duì)于間隙鎖,筆者人為,你只要能get到上述英語片段的點(diǎn),就Okay了,小學(xué)5年級(jí)就能讀懂,如果讀不懂,你真的要去學(xué)一下英語了,不會(huì)英語的程序員,一定是個(gè)最low逼的程序員!


廣而告之

最后,做個(gè)廣告,現(xiàn)在阿里開放為數(shù)不多的HC,如果有想來的同學(xué),給我私聊,幫你內(nèi)推哦~簡歷飛來吧,同學(xué)們。
和小明的故事還在繼續(xù),他又回去看imooc的公眾號(hào)去了,很快就會(huì)回來。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,382評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,616評(píng)論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,112評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,355評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,869評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,727評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,928評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,165評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評(píng)論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,585評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,892評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容

  • 前言 數(shù)據(jù)庫鎖定機(jī)制是數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性而使各種共享資源在并發(fā)訪問時(shí)變的有序的一種規(guī)則。MySQL數(shù)據(jù)庫的...
    Justlearn閱讀 1,681評(píng)論 0 4
  • 一、概述 數(shù)據(jù)庫鎖定機(jī)制簡單來說,就是數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性,而使各種共享資源在被并發(fā)訪問變得有序所設(shè)計(jì)的一種...
    忘憂谷主閱讀 601評(píng)論 0 3
  • MYSQL 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫概要 2 簡單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 MySQL基本操...
    Kingtester閱讀 7,830評(píng)論 5 116
  • 一、概述 數(shù)據(jù)庫鎖定機(jī)制簡單來說,就是數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性,而使各種共享資源在被并發(fā)訪問變得有序所設(shè)計(jì)的一種...
    不變甄心閱讀 2,741評(píng)論 0 3
  • 人們總是會(huì)一切以結(jié)果為導(dǎo)向,而往往忽略了過程! 學(xué)了結(jié)果偏見的課程后,果然過程也是要必須追究的。 忽然有了一種為一...
    FineYoga桔子閱讀 212評(píng)論 0 0