在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一文徹底搞懂MySQL鎖究竟鎖的啥2

jf_78858299 ? 來(lái)源:蟬沐風(fēng)的碼場(chǎng) ? 作者:蟬沐風(fēng) ? 2023-03-03 10:13 ? 次閱讀

6. 意向鎖

6.1. 背景

前面提到的S鎖和X鎖的語(yǔ)法規(guī)則其實(shí)是針對(duì)記錄的,也就是行鎖,原因是InnoDB中行鎖用的最多。如果將鎖的粒度和鎖的基本模式排列組合一下,就會(huì)出現(xiàn)如下4種情況:

  • 行級(jí)S
  • 行級(jí)X
  • 表級(jí)S
  • 表級(jí)X

那么接下來(lái)的描述,也就順理成章了。

如果事務(wù)給一個(gè)表添加了表級(jí)S鎖,則:

  • 其他事務(wù)可以繼續(xù)獲得該表的S鎖,但是無(wú)法獲取該表的X鎖;
  • 其他事務(wù)可以繼續(xù)獲得該表某些行的S鎖,但是無(wú)法獲取該表某些行的X鎖。

如果事務(wù)給一個(gè)表添加了表級(jí)X鎖,則:

  • 不論是該表的S鎖、X鎖,還是該表某些行的S鎖、X鎖,其他事務(wù)都只能干瞪眼兒,啥也獲取不了。

挺好理解的吧,總之就是 S鎖只能和S鎖相容,X鎖和其他任何鎖都互斥 。問(wèn)題來(lái)了,雖然用的不多,但是萬(wàn)一我真的想給整個(gè)表添加一個(gè)S鎖或者X鎖怎么辦?

假如我要給表user添加一個(gè)S鎖,那就必須保證user在表級(jí)別上和行級(jí)別上都不能有X鎖,表級(jí)別上還好說(shuō)一點(diǎn),無(wú)非就是1個(gè)內(nèi)存結(jié)構(gòu)罷了,但是行X鎖呢?必須得逐行遍歷是否有行X鎖嗎?

同理,假如我要給表user添加一個(gè)X鎖,那就必須保證user在表級(jí)別上和行級(jí)別上都不能有任何鎖(SX都不能有),難不成得逐行遍歷是否有SX鎖嗎?

遍歷是不可能遍歷的!這輩子都不可能遍歷的!于是, 意向鎖 (Intension Lock)誕生了。

6.2. 概念

我們要避免遍歷,那最好的辦法就是在給行加鎖時(shí),先在表級(jí)別上添加一個(gè)標(biāo)識(shí)。

  • 意向共享鎖(Intension Shared Lock):簡(jiǎn)稱(chēng)IS鎖,當(dāng)事務(wù)試圖給行添加S鎖時(shí),需要先在表級(jí)別上添加一個(gè)IS鎖;
  • 意向排他鎖(Intension Exclusive Lock):簡(jiǎn)稱(chēng)IX鎖,當(dāng)事務(wù)試圖給行添加X鎖時(shí),需要先在表級(jí)別上添加一個(gè)IX鎖。

這樣一來(lái):

  • 如果想給user表添加一個(gè)S鎖(表級(jí)鎖),就先看一下user表有沒(méi)有IX鎖;如果有,就說(shuō)明user表的某些行被加了X鎖(行鎖),需要等到行的X鎖釋放,隨即IX鎖被釋放,才可以在user表中添加S鎖;
  • 如果想給user表添加一個(gè)X鎖(表級(jí)鎖),就先看一下user有沒(méi)有IS鎖或IX鎖;如果有,就說(shuō)明user表的某些行被加了S鎖或X鎖(行鎖),需要等到所有行鎖被釋放,隨即IS鎖或IX鎖被釋放,才可以在user表中添加X鎖。

需要注意的是,意向鎖和意向鎖之間是不沖突的,意向鎖和行鎖之間也不沖突。

只有在對(duì)表添加S鎖或X鎖時(shí)才需要判斷當(dāng)前表是否被添加了IS鎖或IX鎖,當(dāng)為表添加IS鎖或IX鎖時(shí),不需要關(guān)心當(dāng)前表是否已經(jīng)被添加了其他IS鎖或IX鎖。

目前為止MySQL鎖的基本模式就介紹完了,接下來(lái)回到這片文章的題目,MySQL鎖,鎖住的到底是什么?由于InnoDB的行鎖用的最多,這里的鎖自然指的是行鎖。

7. 行鎖的原理

既然都叫行鎖了,我們姑且猜測(cè)一下,行鎖鎖住的是一行數(shù)據(jù)。我們做個(gè)實(shí)驗(yàn)。

7.1. 沒(méi)有任何索引的表

我們先創(chuàng)建一張沒(méi)有任何索引的普通表,語(yǔ)句如下

CREATE TABLE `user_t1` (
  `id` int DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

表中數(shù)據(jù)如下:

mysql> SELECT * FROM user_t1;
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | chanmufeng  |
|    2 | wanggangdan |
|    3 | wangshangju |
|    4 | zhaotiechui |
+------+-------------+

接下來(lái)我們?cè)趦蓚€(gè)session中開(kāi)啟兩個(gè)事務(wù)。

  • 事務(wù)1,我們通過(guò)WHERE id = 1“鎖住”第1行數(shù)據(jù);
  • 事務(wù)2,我們通過(guò)WHERE id = 2"鎖住"第2行數(shù)據(jù)。

圖片

一件詭異的事情是,第2個(gè)加鎖的操作被阻塞了。實(shí)際上,T2中不管我們要給user_t1中哪行數(shù)據(jù)加鎖,都會(huì)失敗!

為什么我SELECT一條數(shù)據(jù),卻給我鎖住了整個(gè)表?這個(gè)實(shí)驗(yàn)直接推翻了我們的猜測(cè), InnoDB的行鎖并非直接鎖定Record行

為什么沒(méi)有索引的情況下,給某條語(yǔ)句加鎖會(huì)鎖住整個(gè)表呢?別急,我們繼續(xù)。

7.2. 有主鍵索引的表

我們?cè)賱?chuàng)建一個(gè)表user_t2,語(yǔ)句如下:

CREATE TABLE `user_t2` (
	`id` int NOT NULL,
	`name` varchar(255) DEFAULT NULL,
	PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

user_t1的不同之處在于為id創(chuàng)建了一個(gè)主鍵索引。表中數(shù)據(jù)依然如下:

mysql> SELECT * FROM user_t2;
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | chanmufeng  |
|    2 | wanggangdan |
|    3 | wangshangju |
|    4 | zhaotiechui |
+------+-------------+

同樣開(kāi)啟兩個(gè)事務(wù):

  • 事務(wù)1,通過(guò)WHERE id = 1“鎖住”第1行數(shù)據(jù);
  • 事務(wù)2
    • 依然使用WHERE id = 1嘗試加鎖,加鎖失敗;
    • 使用WHERE id = 2嘗試加鎖,加鎖成功。

圖片

既然鎖的不是Record行,難不成鎖的是id這一列嗎?

我們?cè)僮鲎詈笠粋€(gè)實(shí)驗(yàn)。

7.3. 有唯一索引的表

我們?cè)賱?chuàng)建一個(gè)表user_t3,語(yǔ)句如下:

CREATE TABLE `user_t3` (
	`id` int NOT NULL,
	`name` varchar(255) DEFAULT NULL,
	PRIMARY KEY (`id`),
  UNIQUE KEY (`uk_name`) (`name`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

user_t2的不同之處在于為name列創(chuàng)建了一個(gè)唯一索引。表中數(shù)據(jù)依然如下:

mysql> SELECT * FROM user_t3;
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | chanmufeng  |
|    2 | wanggangdan |
|    3 | wangshangju |
|    4 | zhaotiechui |
+------+-------------+

圖片

兩個(gè)事務(wù):

  • 事務(wù)1,通過(guò)name字段 “鎖住”name為“chanmufeng”的數(shù)據(jù);
  • 事務(wù)2
    • 依然使用WHERE name = “chanmufeng” 嘗試加鎖,可以預(yù)料,加鎖失敗;
    • 使用WHERE id = 1嘗試給同樣的行加鎖,加鎖失敗。

通過(guò)3個(gè)實(shí)驗(yàn)我們發(fā)現(xiàn),行鎖鎖住的既不是Record行,也不是Column列,那到底鎖住的是什么?我們對(duì)比一下,上文的3張表的不同點(diǎn)在于索引不同,其實(shí) InnoDB的行鎖,就是通過(guò)鎖住索引來(lái)實(shí)現(xiàn)的

接下來(lái)回答3個(gè)問(wèn)題。

8. 三個(gè)問(wèn)題

8.1. 鎖住索引?沒(méi)有索引怎么辦?

你說(shuō)鎖住索引?如果我不創(chuàng)建索引,MySQL鎖定個(gè)啥?

如果我們沒(méi)有設(shè)置主鍵,InnoDB會(huì)優(yōu)先選取一個(gè)不包含NULL值的Unique鍵作為主鍵,如果表中連Unique鍵也沒(méi)有的話(huà),就會(huì)自動(dòng)為每一條記錄添加一個(gè)叫做DB_ROW_ID的列作為默認(rèn)主鍵,只不過(guò)這個(gè)主鍵我們看不到罷了。

下圖是數(shù)據(jù)的行格式。看不懂的話(huà)強(qiáng)烈推薦看一下我上面給出的兩篇文章,說(shuō)得非常明白。

圖片

行格式

8.2. 為什么第一個(gè)實(shí)驗(yàn)會(huì)鎖表?

因?yàn)?code>SELECT沒(méi)有用到索引,會(huì)進(jìn)行全表掃描,然后把DB_ROW_ID作為默認(rèn)主鍵的聚簇索引都給鎖住了。

8.3. 為什么通過(guò)唯一索引給數(shù)據(jù)加鎖,主鍵索引也會(huì)被鎖住?

不管是Unique索引還是普通索引,它們的葉子結(jié)點(diǎn)中存儲(chǔ)的數(shù)據(jù)都不完整,其中只是存儲(chǔ)了作為索引并且排序好的列數(shù)據(jù)以及對(duì)應(yīng)的主鍵值。

因此我們通過(guò)索引查找數(shù)據(jù)數(shù)據(jù)實(shí)際上是在索引的B+樹(shù)中先找到對(duì)應(yīng)的主鍵,然后根據(jù)主鍵再去主鍵索引的B+樹(shù)的葉子結(jié)點(diǎn)中找到完整數(shù)據(jù),最后返回。所以雖然是兩個(gè)索引樹(shù),但實(shí)際上是同一行數(shù)據(jù),必須全部鎖住。

下面給了一張圖,讓不了解索引的朋友大致了解一下。上半部分是name列創(chuàng)建的唯一索引的B+樹(shù),下半部分是主鍵索引(也叫聚簇索引)。

假如我們通過(guò)WHERE name = '王鋼蛋'對(duì)數(shù)據(jù)進(jìn)行查詢(xún),會(huì)先用到name列的唯一索引,最終定位到主鍵值為1,然后再到主鍵索引中查詢(xún)id = 1的數(shù)據(jù),最終拿到完整的行數(shù)據(jù)。

這兩張圖在我索引文章中都有哦~

圖片

MySQL鎖-索引

9. 總結(jié)

至此,我已經(jīng)回答了文章開(kāi)頭的絕大多數(shù)問(wèn)題。

MySQL鎖,是解決資源競(jìng)爭(zhēng)問(wèn)題的一種手段。有哪些競(jìng)爭(zhēng)呢?讀—寫(xiě)/寫(xiě)—讀,寫(xiě)—寫(xiě)中都會(huì)出現(xiàn)資源競(jìng)爭(zhēng)問(wèn)題,不同的是前者可以通過(guò)MVCC的方式來(lái)解決,但是某些情況下你也不得不用鎖,因此我也順便解釋了鎖和MVCC的關(guān)系。

然后介紹了MySQL鎖的基本模式,包括共享鎖(S鎖)和排他鎖(X鎖),還引入了意向鎖。

最后解釋了鎖到底鎖的是什么的問(wèn)題。通過(guò)3個(gè)實(shí)驗(yàn),最終解釋了InnoDB鎖本質(zhì)上鎖的是索引。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7494

    瀏覽量

    87965
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    809

    瀏覽量

    26575
  • MVCC
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    1470
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于MySQL機(jī)制

    在數(shù)據(jù)庫(kù)系統(tǒng)中,為了保證數(shù)據(jù)的致性和并發(fā)控制,機(jī)制發(fā)揮著至關(guān)重要的作用。尤其在關(guān)系型數(shù)據(jù)庫(kù)MySQL中,其獨(dú)特的機(jī)制設(shè)計(jì)更是贏得了許多開(kāi)發(fā)者的喜愛(ài)。 本文將詳細(xì)探討
    的頭像 發(fā)表于 09-30 11:16 ?882次閱讀

    redis分布式場(chǎng)景實(shí)現(xiàn)

    今天帶大家深入剖析下Redis分布式徹底搞懂它。 場(chǎng)景 既然要搞懂Redis分布式,那肯
    的頭像 發(fā)表于 09-25 17:09 ?722次閱讀

    請(qǐng)問(wèn)DSPflash死后,RAM還可以用嗎,還是這塊芯片就徹底廢了?

    本帖最后由 只耳朵怪 于 2018-6-13 16:47 編輯 請(qǐng)問(wèn)DSPflash死后,RAM還可以用嗎,還是這塊芯片就徹底廢了?
    發(fā)表于 06-13 04:19

    InnoDB的特點(diǎn)和狀態(tài)查詢(xún)

    MySQL探秘(五)InnoDB的類(lèi)型和狀態(tài)查詢(xún)
    發(fā)表于 08-07 11:45

    讀懂eMMC究竟

    eMMC究竟?eMMC長(zhǎng)什么樣?eMMC用在哪?主要是干嘛用的?eMMC究竟是如何工作的呢?
    發(fā)表于 06-18 06:04

    360為什么會(huì)入局智能市場(chǎng)

    很難界定智能究竟屬于哪個(gè)行業(yè)?智能是五金門(mén)鎖行業(yè)、安防行業(yè)、家居行業(yè)和產(chǎn)業(yè)互聯(lián)網(wǎng)行業(yè)的交匯產(chǎn)物。硬件是基礎(chǔ),安防及家居是應(yīng)用,網(wǎng)絡(luò)是消費(fèi)渠道及用戶(hù)交互界面,物聯(lián)網(wǎng)讓智能
    發(fā)表于 11-05 15:21 ?1498次閱讀

    詳細(xì)介紹MySQL InnoDB存儲(chǔ)引擎各種不同類(lèi)型的

    T1執(zhí)行時(shí),需要獲取i=1的行的X(不需要獲取t1表的意向了);T2執(zhí)行時(shí),需要獲取t1表的X,T2能否獲取到T1表的X
    的頭像 發(fā)表于 02-20 11:12 ?7648次閱讀
    詳細(xì)介紹<b class='flag-5'>MySQL</b> InnoDB存儲(chǔ)引擎各種不同類(lèi)型的<b class='flag-5'>鎖</b>

    徹底搞懂PID到底是

    先來(lái)徹底搞懂PID到底是? PID,就是比例(proportional)、積分(integral)、微分(differential),是種很常見(jiàn)的控制算法。在工程實(shí)際中,應(yīng)用最為廣
    的頭像 發(fā)表于 11-13 18:21 ?2.5w次閱讀

    數(shù)據(jù)庫(kù)的機(jī)制真正的原理

    問(wèn)候選人,你知道MySQL Innodb的,到底的是什么嗎?關(guān)于這個(gè)問(wèn)題的回答,聽(tīng)到過(guò)很多種,但是很少有人可以把他回答的很完美。因?yàn)橄胍卮鸷眠@個(gè)問(wèn)題,需要對(duì)數(shù)據(jù)庫(kù)的隔離級(jí)別、索引等都有
    的頭像 發(fā)表于 11-12 09:33 ?2271次閱讀

    說(shuō)說(shuō)MySQL有哪些

    增加自增為 innodb_autoinc_lock_mode = 2 模式時(shí),為什么主從環(huán)境會(huì)有不安全問(wèn)題的說(shuō)明
    的頭像 發(fā)表于 10-24 10:15 ?871次閱讀

    MySQL是怎么加行級(jí)的?有什么規(guī)則?

    是不是很多人都對(duì) MySQL 加行級(jí)的規(guī)則搞的迷迷糊糊,對(duì)記錄會(huì)加的是 next-key 會(huì)加是間隙
    的頭像 發(fā)表于 11-17 09:28 ?813次閱讀

    徹底搞懂MySQL究竟1

    MySQL系列文章已經(jīng)鴿了挺久了,最近趕緊擠了擠時(shí)間,和大家聊MySQL。 只要學(xué)計(jì)算機(jī),「`
    的頭像 發(fā)表于 03-03 10:12 ?472次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文</b><b class='flag-5'>徹底</b><b class='flag-5'>搞懂</b><b class='flag-5'>MySQL</b><b class='flag-5'>鎖</b><b class='flag-5'>究竟</b><b class='flag-5'>鎖</b>的<b class='flag-5'>啥</b>1

    Linux互斥的作用 互斥是什么

    。如果釋放互斥時(shí)有個(gè)以上的線(xiàn)程阻塞,那么這些阻塞的線(xiàn)程會(huì)被喚醒,它們都會(huì)嘗試對(duì)互斥進(jìn)行加鎖,當(dāng)有個(gè)線(xiàn)程成功對(duì)互斥鎖上鎖之后,其它線(xiàn)程就不能再次上鎖了,只能再次陷入阻塞,等待下
    的頭像 發(fā)表于 07-21 11:13 ?946次閱讀

    自旋和互斥的區(qū)別有哪些

    自旋 自旋與互斥很相似,在訪(fǎng)問(wèn)共享資源之前對(duì)自旋進(jìn)行上鎖,在訪(fǎng)問(wèn)完成后釋放自旋(解鎖);事實(shí)上,從實(shí)現(xiàn)方式上來(lái)說(shuō),互斥
    的頭像 發(fā)表于 07-21 11:19 ?9497次閱讀

    互斥和自旋的實(shí)現(xiàn)原理

    互斥和自旋是操作系統(tǒng)中常用的同步機(jī)制,用于控制對(duì)共享資源的訪(fǎng)問(wèn),以避免多個(gè)線(xiàn)程或進(jìn)程同時(shí)訪(fǎng)問(wèn)同資源,從而引發(fā)數(shù)據(jù)不致或競(jìng)爭(zhēng)條件等問(wèn)題。 互斥
    的頭像 發(fā)表于 07-10 10:07 ?495次閱讀
    主站蜘蛛池模板: 好吊色7777sao在线视频观看| 中文字幕视频二区| 欧美猛交xxxx免费看| 男女交性永久免费视频播放| 性欧美护士18xxxxhd| 久久青草视频| 久久这里只精品热在线8| 午夜毛片免费看| 一本到卡二卡三卡福利| 日韩精品网址| 欧美人与动性视频在线观| 国产一级特黄全黄毛片| 波多野结衣的毛片| 四虎影城库| 你懂得网址在线观看| 国产三级精品视频| 天天干天天拍天天射| 国产在线精品一区二区夜色| 色婷婷在线观看视频| 天天干天天操天天爽| h视频在线免费| 天堂网www中文在线资源| 天天操天天射天天插| 亚洲插插| 看黄a大片 免费| 成人毛片一区二区三区| 欧美色图888| 奇米7777影视| 日本黄色小视频网站| 天天做日日爱| 色聚网久久综合| 2018天天操夜夜操| 三级色图| 免费看国产黄色片| vr性资源在线观看| 亚洲三级电影在线播放| 欧美乱妇15p| 免费视频爰爱太爽了| 日本aaaaa高清免费看| 午夜在线免费观看视频| 无夜精品久久久久久|