色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

jf_78858299 ? 來源:蟬沐風的碼場 ? 作者:蟬沐風 ? 2023-03-03 10:13 ? 次閱讀

6. 意向鎖

6.1. 背景

前面提到的S鎖和X鎖的語法規則其實是針對記錄的,也就是行鎖,原因是InnoDB中行鎖用的最多。如果將鎖的粒度和鎖的基本模式排列組合一下,就會出現如下4種情況:

  • 行級S
  • 行級X
  • 表級S
  • 表級X

那么接下來的描述,也就順理成章了。

如果事務給一個表添加了表級S鎖,則:

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

如果事務給一個表添加了表級X鎖,則:

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

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

假如我要給表user添加一個S鎖,那就必須保證user在表級別上和行級別上都不能有X鎖,表級別上還好說一點,無非就是1個內存結構罷了,但是行X鎖呢?必須得逐行遍歷是否有行X鎖嗎?

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

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

6.2. 概念

我們要避免遍歷,那最好的辦法就是在給行加鎖時,先在表級別上添加一個標識。

  • 意向共享鎖(Intension Shared Lock):簡稱IS鎖,當事務試圖給行添加S鎖時,需要先在表級別上添加一個IS鎖;
  • 意向排他鎖(Intension Exclusive Lock):簡稱IX鎖,當事務試圖給行添加X鎖時,需要先在表級別上添加一個IX鎖。

這樣一來:

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

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

只有在對表添加S鎖或X鎖時才需要判斷當前表是否被添加了IS鎖或IX鎖,當為表添加IS鎖或IX鎖時,不需要關心當前表是否已經被添加了其他IS鎖或IX鎖。

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

7. 行鎖的原理

既然都叫行鎖了,我們姑且猜測一下,行鎖鎖住的是一行數據。我們做個實驗。

7.1. 沒有任何索引的表

我們先創建一張沒有任何索引的普通表,語句如下

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

表中數據如下:

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

接下來我們在兩個session中開啟兩個事務。

  • 事務1,我們通過WHERE id = 1“鎖住”第1行數據;
  • 事務2,我們通過WHERE id = 2"鎖住"第2行數據。

圖片

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

為什么我SELECT一條數據,卻給我鎖住了整個表?這個實驗直接推翻了我們的猜測, InnoDB的行鎖并非直接鎖定Record行

為什么沒有索引的情況下,給某條語句加鎖會鎖住整個表呢?別急,我們繼續。

7.2. 有主鍵索引的表

我們再創建一個表user_t2,語句如下:

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

user_t1的不同之處在于為id創建了一個主鍵索引。表中數據依然如下:

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

同樣開啟兩個事務:

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

圖片

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

我們再做最后一個實驗。

7.3. 有唯一索引的表

我們再創建一個表user_t3,語句如下:

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列創建了一個唯一索引。表中數據依然如下:

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

圖片

兩個事務:

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

通過3個實驗我們發現,行鎖鎖住的既不是Record行,也不是Column列,那到底鎖住的是什么?我們對比一下,上文的3張表的不同點在于索引不同,其實 InnoDB的行鎖,就是通過鎖住索引來實現的

接下來回答3個問題。

8. 三個問題

8.1. 鎖住索引?沒有索引怎么辦?

你說鎖住索引?如果我不創建索引,MySQL鎖定個啥?

如果我們沒有設置主鍵,InnoDB會優先選取一個不包含NULL值的Unique鍵作為主鍵,如果表中連Unique鍵也沒有的話,就會自動為每一條記錄添加一個叫做DB_ROW_ID的列作為默認主鍵,只不過這個主鍵我們看不到罷了。

下圖是數據的行格式。看不懂的話強烈推薦看一下我上面給出的兩篇文章,說得非常明白。

圖片

行格式

8.2. 為什么第一個實驗會鎖表?

因為SELECT沒有用到索引,會進行全表掃描,然后把DB_ROW_ID作為默認主鍵的聚簇索引都給鎖住了。

8.3. 為什么通過唯一索引給數據加鎖,主鍵索引也會被鎖住?

不管是Unique索引還是普通索引,它們的葉子結點中存儲的數據都不完整,其中只是存儲了作為索引并且排序好的列數據以及對應的主鍵值。

因此我們通過索引查找數據數據實際上是在索引的B+樹中先找到對應的主鍵,然后根據主鍵再去主鍵索引的B+樹的葉子結點中找到完整數據,最后返回。所以雖然是兩個索引樹,但實際上是同一行數據,必須全部鎖住。

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

假如我們通過WHERE name = '王鋼蛋'對數據進行查詢,會先用到name列的唯一索引,最終定位到主鍵值為1,然后再到主鍵索引中查詢id = 1的數據,最終拿到完整的行數據。

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

圖片

MySQL鎖-索引

9. 總結

至此,我已經回答了文章開頭的絕大多數問題。

MySQL鎖,是解決資源競爭問題的一種手段。有哪些競爭呢?讀—寫/寫—讀,寫—寫中都會出現資源競爭問題,不同的是前者可以通過MVCC的方式來解決,但是某些情況下你也不得不用鎖,因此我也順便解釋了鎖和MVCC的關系。

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

最后解釋了鎖到底鎖的是什么的問題。通過3個實驗,最終解釋了InnoDB鎖本質上鎖的是索引。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 計算機
    +關注

    關注

    19

    文章

    7500

    瀏覽量

    88019
  • MySQL
    +關注

    關注

    1

    文章

    813

    瀏覽量

    26594
  • MVCC
    +關注

    關注

    0

    文章

    13

    瀏覽量

    1476
收藏 人收藏

    評論

    相關推薦

    基于MySQL機制

    在數據庫系統中,為了保證數據的致性和并發控制,機制發揮著至關重要的作用。尤其在關系型數據庫MySQL中,其獨特的機制設計更是贏得了許多開發者的喜愛。 本文將詳細探討
    的頭像 發表于 09-30 11:16 ?888次閱讀

    redis分布式場景實現

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

    請問DSPflash死后,RAM還可以用嗎,還是這塊芯片就徹底廢了?

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

    InnoDB的特點和狀態查詢

    MySQL探秘(五)InnoDB的類型和狀態查詢
    發表于 08-07 11:45

    讀懂eMMC究竟

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

    360為什么會入局智能市場

    很難界定智能究竟屬于哪個行業?智能是五金門鎖行業、安防行業、家居行業和產業互聯網行業的交匯產物。硬件是基礎,安防及家居是應用,網絡是消費渠道及用戶交互界面,物聯網讓智能
    發表于 11-05 15:21 ?1499次閱讀

    詳細介紹MySQL InnoDB存儲引擎各種不同類型的

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

    徹底搞懂PID到底是

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

    數據庫的機制真正的原理

    問候選人,你知道MySQL Innodb的,到底的是什么嗎?關于這個問題的回答,聽到過很多種,但是很少有人可以把他回答的很完美。因為想要回答好這個問題,需要對數據庫的隔離級別、索引等都有
    的頭像 發表于 11-12 09:33 ?2276次閱讀

    說說MySQL有哪些

    增加自增為 innodb_autoinc_lock_mode = 2 模式時,為什么主從環境會有不安全問題的說明
    的頭像 發表于 10-24 10:15 ?873次閱讀

    MySQL是怎么加行級的?有什么規則?

    是不是很多人都對 MySQL 加行級的規則搞的迷迷糊糊,對記錄會加的是 next-key 會加是間隙
    的頭像 發表于 11-17 09:28 ?819次閱讀

    徹底搞懂MySQL究竟1

    MySQL系列文章已經鴿了挺久了,最近趕緊擠了擠時間,和大家聊MySQL。 只要學計算機,「`
    的頭像 發表于 03-03 10:12 ?475次閱讀
    <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互斥的作用 互斥是什么

    。如果釋放互斥時有個以上的線程阻塞,那么這些阻塞的線程會被喚醒,它們都會嘗試對互斥進行加鎖,當有個線程成功對互斥鎖上鎖之后,其它線程就不能再次上鎖了,只能再次陷入阻塞,等待下
    的頭像 發表于 07-21 11:13 ?950次閱讀

    自旋和互斥的區別有哪些

    自旋 自旋與互斥很相似,在訪問共享資源之前對自旋進行上鎖,在訪問完成后釋放自旋(解鎖);事實上,從實現方式上來說,互斥
    的頭像 發表于 07-21 11:19 ?9505次閱讀

    互斥和自旋的實現原理

    互斥和自旋是操作系統中常用的同步機制,用于控制對共享資源的訪問,以避免多個線程或進程同時訪問同資源,從而引發數據不致或競爭條件等問題。 互斥
    的頭像 發表于 07-10 10:07 ?501次閱讀
    主站蜘蛛池模板: 亚洲国产精品日本无码网站| 欧美日韩免费播放一区二区| 两个吃奶一个添下面视频| 偷偷鲁青春草原视频| 扒开老师粉嫩的泬10P| 免费韩国伦理2017最新| 中文字幕精品在线观看| 久久嫩草影院网站| 伊人网综合在线观看| 久99视频精品免费观看福利| 伊人精品久久久大香线蕉99| 激情办公室| 伊人久在线观看视频| 久久中文字幕人妻AV熟女| 在线精彩视频在线观看免费| 久亚洲AV无码专区A片| 最新黄yyid| 欧美成 人 网 站 免费| 爆操大胸美女| 无人区在线日本高清免费| 国产精品资源网站在线观看| 亚洲 欧美 国产 综合 在线| 国产在线一区二区三区四区| 亚洲性无码av在线| 美女MM131爽爽爽| 宝贝好紧好爽再搔一点试視頻| 甜性涩爱在线播放| 寂寞夜晚看免费视频| 最近日本免费观看MV免费| 青草伊人久久| 国产免费阿v精品视频网址| 亚洲视频无码高清在线| 美女被触手注入精子强制受孕漫画 | 伊人网中文字幕| 男人J进女人P| 国产成人精品综合在线观看| 亚洲国产夜色在线观看| 麻豆一二三区果冻| 国产AV无码一二三区视频| 妖精视频免费看| 欧美一级黄色影院|