国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

一文帶你弄懂 MySQL 的加鎖規則!

數據庫 其他數據庫
在這些文章中,我們大致了解了一些加鎖的情況。但實際上 MySQL 的加鎖規則是怎樣的,我還不是特別清楚。所以今天我們就來深入了解下 MySQL 的加鎖規則。

?大家好,我是樹哥。

在之前的文章里,我們討論了關于 MySQL 的許多問題,包括:

  1. MySQL 啥時候用表鎖,啥時候用行鎖?
  2. MySQL 不同隔離級別,都使用了什么鎖?
  3. MySQL 啥時候用記錄鎖,啥時候用間隙鎖?

在這些文章中,我們大致了解了一些加鎖的情況。但實際上 MySQL 的加鎖規則是怎樣的,我還不是特別清楚。所以今天我們就來深入了解下 MySQL 的加鎖規則。

圖片

MySQL 的加鎖規則到底是怎樣的?

迷霧找真相

為了弄清楚這些加鎖規則,我查閱了許多資料。但在這些資料中,我覺得比較有質量的只有兩個:一個是極客時間《MySQL 45 講》第 20/21 節講得內容,另一個是一篇從源碼角度解析加鎖規則的文章。

《MySQL 45 講》是丁奇老師出的一個專欄,現在是騰訊云數據庫負責人。在該專欄的第 21、22 節中講到了具體的加鎖規則,并且也舉了非常多的例子。本文也將摘取其中一些內容,來跟大家討論學習。

另一篇從源碼角度講加鎖規則的,是網名為「小孩子」的網友寫得一篇文章,其后續出了一本書叫《從根上了解 MySQL》,內容非常多并且很詳細。這篇文章從源碼角度從頭到尾分析了整個加鎖規則,講得還是比較詳細。

在看著兩份資料之前,我總是嘗試去找到一個簡單好記的加鎖規律,但看完之后覺得:這或許不太可能。丁奇大神在其專欄也提到他是怎么去分析加鎖規則的。

首先說明一下,這些加鎖規則我沒在別的地方看到過有類似的總結,以前我自己判斷的時候都是想著代碼里面的實現來腦補的。這次為了總結成不看代碼的同學也能理解的規則,是我又重新刷了代碼臨時總結出來的。

可以看到,就連大神也是想著代碼腦補加鎖規律的。再結合「小孩子」從源碼角度去分析加鎖規則,我一下子就覺得:或許還是該深入到源碼角度,才能一窺真相。

即使后面丁奇老師為了方便我們理解,也總結出了一些加鎖(如下圖所示)。但實際上這些加鎖規則也沒啥規律,只能是記著就好。此外,他也提出:我們需要用動態的眼光去看加鎖。言外之意就是,這些規則可能都是變化的,也不一定是完全正確的。

圖片

圖片來自極客時間專欄

看到這里,我會想:那我們應該怎么學習 MySQL 的加鎖規則呢?

我思考了片刻,給出的答案是:我們可以按照丁奇老師總結出的加鎖規則先行學習,后續再深入源碼層面不斷地補足一些細節。

MySQL 加鎖全局視角

在講一些具體加鎖規則之前,我覺得有必要先給大家一個 MySQL 加鎖的全局視角。這個是丁奇老師在文章中沒講到的,但我覺得如果不知道全局視角,那么會影響到對一些規則的理解。

我們知道 MySQL 分成了 Server 層和存儲引擎兩部分,每當執行一個查詢時,Server 層負責生成執行計劃,然后交給存儲引擎去執行。其整個過程可以這樣描述:

  1. Server 層向 Innodb 獲取到掃描區間的第 1 條記錄。
  2. Innodb 通過 B+ 樹定位到掃描區間的第 1 條記錄,然后返回給 Server 層。
  3. Server 層判斷是否符合搜索條件,如果符合則發送給客戶端,不負責則跳過。接著繼續向 Innodb 要下一條記錄。
  4. Innodb 繼續根據 B+ 樹的雙休鏈表找到下一條記錄,會執行具體的 row_search_mvcc 函數做加鎖等操作,返回給 Server 層。
  5. Server 層繼續處理該條記錄,并向 Innodb 要下一條記錄。
  6. 繼續不停執行上述過程,直到 Innodb 讀到一條不符合邊界條件的記錄為止。

通過上面這個過程,我想讓大家明白兩個重要的認識:

  1. Innodb 并不是一次性把所有數據找到,然后返回給 Server 層的,而是會循環很多次。
  2. row_search_mvcc 這個函數是做具體的加鎖、加什么鎖的重要邏輯,并且由于 Server 層與 Innodb 會循環多次,因此該函數也是會執行多次的。

弄懂了上面兩個認識,會對后續大家理解有很大幫助。例如:對于 select * from user where id >= 5 進行分析的時候,為什么會出現說第一次加鎖是精確查詢?它明明是范圍查詢呀!這是因為第一次是要尋找到 id = 5 的記錄,對于 Innodb 來說,它就是精確查找,不是范圍查找。隨后找到 id = 5 的記錄之后,就要找 id > 5 的記錄了,此時就變成了范圍查找了。

MySQL 加鎖規則

這里的加鎖規則,我直接引用丁奇老師的總結:兩個原則、兩個優化、一個 bug。

  • 原則 1:加鎖的基本單位是 next-key lock。其中 next-key lock 是前開后閉區間,例如:(2, 5]。
  • 原則 2:查找過程中訪問到的對象才會加鎖。
  • 優化 1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock 退化為行鎖。
  • 優化 2:索引上的等值查詢,向右遍歷時且最后一個值不滿足等值條件的時候,next-key lock 退化為間隙鎖。
  • 一個 bug:唯一索引上的范圍查詢會訪問到不滿足條件的第一個值為止。

對于原則 1 說的:加鎖的基本單位是 Next-Key 鎖,意思是默認都是先加上 Next-Key,之后根據 2 個優化點選擇性退化為行鎖或間隙鎖。

對于原則 2 說的:訪問到的對象才會加鎖,意思是如果直接索引覆蓋到了,不需要回表,那么就不會對聚簇索引加鎖。這樣的話,其他事務就可以對聚簇索引進行操作,而不會阻塞。

為了解釋這些規則,建立表 t 并插入一些數據。

CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `c` (`c`)
) ENGINE=InnoDB;

insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);

等值查詢間隙鎖

如下圖所示的例子,是一個等值條件加間隙鎖的例子。

圖片

圖片來自極客時間專欄

在事務 A 中,要查找 id = 7 的記錄,其查找過程為:從左到右查找 id 聚簇索引,依次對比 0、5 兩個索引,發現不對。接著,對比 10 這個索引,發現 7 <10,于是停止搜索。根據原則 1 默認給其加上一個 Next-Key 鎖,即 (5, 10]。根據優化 2 退化為間隙鎖,即 (5,10)。

所以,session B 要插入 id=8 的記錄會被鎖住,而 session 修改 id=10 這行是可以的。

非唯一索引等值鎖

圖片

圖片來自極客時間專欄

在事務 A 中,要查找 c=5 的記錄,其中 c 是非唯一索引。其查找過程為:從左到右查找 c 索引,找到了 c=5 的索引,根據原則 1 對其加 Next-Key 鎖,即 (0,5]。

由于普通索引可能重復,因此其還會繼續往后搜索,接著搜索到 10,根據原則 2,訪問到的都要加鎖,因此再給其加 Next-Key 鎖,即 (5,10]。由于這個還負責優化 2:等值判斷,向右遍歷,最后一個不滿足等值條件,因此退化為間隙鎖 (5,10)。

此外,根據原則 2,只有訪問到的對象才會加鎖。這個查詢使用查詢覆蓋索引,并不需要訪問主鍵索引,所以主鍵索引上沒有加任何鎖。也就是說 (0,5] 和 (5,10) 這兩個鎖,只在索引 c 上加鎖,并不在主鍵索引上加鎖,因此 session B 可以執行。

session C 中插入一個 c 為 7 的值,c 為 7 的值在 (5,10) 之間,因此會被鎖住。

主鍵索引范圍鎖

對于我們這個表 t,下面這兩條查詢語句,加鎖范圍相同嗎?

mysql> select * from t where id=10 for update;
mysql> select * from t where id>=10 and id<11 for update;

在邏輯上,這兩條查語句肯定是等價的,但是它們的加鎖規則不太一樣。現在,我們就讓 session A 執行第二個查詢語句,來看看加鎖效果。

圖片

圖片來自極客時間專欄

我們來分析一下整體的加鎖規則吧。

事務 A 開始執行的時候,要找到 id 為 10 的記錄,于是從左到右找到了 id 為 10 的索引。根據原則 1 會給其加 Next-Key 鎖,即 (5,10]。根據優化 1,id = 10 是等值查詢,因此其退化為行鎖,即只對 id = 10 這行加了行鎖。

接著繼續進行范圍查找,找到 id=15 這一行,繼續加 Next-Key 鎖 (10,15]。這時候 id=15 大于 11,因此其不再查找。TODO

非唯一索引范圍鎖

下面的 c 字段是非唯一普通索引,使用了范圍查詢。

圖片

圖片來自極客時間專欄

事務 A 開始執行的時候,要找到 id 為 10 的記錄,于是根據原則 1 加了 Next-Key 鎖,即 (5,10]。由于索引 C 是非唯一索引,沒有優化規則,因此不會退化為行鎖。因此對于事務 A 來說,索引 C 上加的是 (5,10] 和 (10,15] 兩個 Next-Key 鎖。

所以當 session B 和 session C 要操作 c 值為 8 和 15 的數據時會被阻塞。

總結

最后我們總結一下 MySQL 的加鎖規則:

  • 首先,明白 server 層與存儲引擎層是多次數據交互的,并不是存儲引擎層一次性查找完數據。
  • 其次,根據兩個原則去分析加鎖的范圍,核心是加鎖單位是 Next-Key 鎖。
  • 最后,根據兩個優化去進行鎖退化,核心因素是唯一索引及等值查詢。

其中「兩個原則、兩個優化」是:

  • 原則 1:加鎖的基本單位是 next-key lock。其中 next-key lock 是前開后閉區間,例如:(2, 5]。
  • 原則 2:查找過程中訪問到的對象才會加鎖。
  • 優化 1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock 退化為行鎖。
  • 優化 2:索引上的等值查詢,向右遍歷時且最后一個值不滿足等值條件的時候,next-key lock 退化為間隙鎖。

通過上面這樣的加鎖規則,我們就可以有一個大致的分析思路,至少能開始分析加鎖規律了。

但要注意的是,實際上的情況非常復雜,例如 limit 參數也會影響加鎖的范圍,非唯一索引多個值夜會影響鎖范圍。簡單地說,就是有很多特例的情況,我們還需要繼續去積累。

參考資料

  • 20 | 幻讀是什么,幻讀有什么問題?
  • 21 | 為什么我只改一行的語句,鎖這么多?
  • 完整版:Innodb 到底是怎么加鎖的
責任編輯:武曉燕 來源: 樹哥聊編程
相關推薦

2023-03-30 08:52:40

DartFlutter

2023-10-26 16:27:50

前端 WebCSS開發

2023-09-18 08:02:45

CSS布局屬性

2022-08-03 08:01:16

CDN網站服務器

2023-12-12 07:31:51

Executors工具開發者

2022-09-05 09:25:53

KubernetesService

2023-04-04 08:01:47

2024-10-16 10:11:52

2022-09-09 10:00:13

KubernetesConfigMap

2022-08-09 09:10:43

Kubernetes容器

2023-11-28 09:31:55

MySQL算法

2021-06-02 05:43:36

比特幣虛擬貨幣區塊鏈

2022-09-01 08:01:56

Pythongunicorn

2024-05-09 10:11:30

2023-11-20 08:18:49

Netty服務器

2022-12-20 07:39:46

2023-12-21 17:11:21

Containerd管理工具命令行

2023-07-31 08:18:50

Docker參數容器

2021-05-29 10:11:00

Kafa數據業務

2022-11-11 19:09:13

架構
點贊
收藏

51CTO技術棧公眾號

午夜精品福利一区二区三区蜜桃| 九九亚洲精品| 久久精品亚洲| 欧美精品一区二区三区高清aⅴ | 女人香蕉久久**毛片精品| 中文字幕日韩电影| 国产盗摄在线视频网站| 亚洲精品水蜜桃| 国产天堂在线播放| 99在线视频精品| 久久国产精品网| 成人短视频下载| 黄色一级视频在线播放| 国产ts人妖一区二区| 国产午夜精品视频一区二区三区| 日本亚洲天堂网| 亚洲国产成人不卡| 爽好多水快深点欧美视频| 久久天天狠狠| 日韩av不卡一区二区| 日韩精品欧美专区| 超碰在线国产| 亚洲精品国精品久久99热一| 日韩欧美综合| 川上优的av在线一区二区| 亚洲欧美自拍偷拍| 欧美激情手机在线视频 | 成人欧美大片| 亚洲美女动态图120秒| 欧美性爽视频| 日韩成人在线观看| japanese23hdxxxx日韩| 色偷偷综合社区| 韩国三级大全久久网站| 久久天天躁狠狠躁夜夜av| 秋霞一区二区三区| 97精品伊人久久久大香线蕉 | 麻豆乱码国产一区二区三区 | 日韩—二三区免费观看av| 日本伊人精品一区二区三区介绍| 成人高清网站| 日韩欧美一级特黄在线播放| 欧美手机在线视频| 免费特级黄毛片| 粉嫩一区二区三区四区公司1| 日日噜噜噜夜夜爽亚洲精品| 久久久久久久久成人| 奇米4444一区二区三区| 亚洲成av人片乱码色午夜| 九九九九九精品| 国内精品在线播放| 先锋影音资源999| 欧美性开放视频| 咪咪网在线视频| 97视频在线观看网址| 天天做天天爱天天综合网2021| 国产精品久久久久久久久久直播 | 亚洲综合色丁香婷婷六月图片| 毛片网站在线| 日韩精品高清在线| 日韩欧洲国产| av免费观看久久| 国产不卡在线视频| 美女黄视频在线播放 | 中文子幕无线码一区tr| 国产精品免费播放| 日韩色av导航| 亚洲一级电影| 成人性做爰aaa片免费看不忠| 91成人免费在线视频| 精品欧美日韩精品| 国产日韩欧美综合| 国产乱码字幕精品高清av| 资源视频在线播放免费| 亚洲欧美制服中文字幕| 第四色成人网| 日本中文字幕在线视频观看| 精品欧美aⅴ在线网站| 在线看欧美视频| 成人黄动漫网站免费| 国产成都精品91一区二区三| 黄页网站在线播放| 丝袜美腿亚洲一区二区| 99精品视频免费| 国产九色porn网址| 亚洲欧洲国产一区| 在线电影一区| 三级a在线观看| 亚洲精品按摩视频| 欧美日本中文| 日韩精品视频一二三| 精品小视频在线| 伊人精品成人久久综合软件| www.这里只有精品| 国产一区二区免费| 午夜亚洲视频| 亚洲成人av高清| 久久久久久久久中文字幕| 日本aⅴ免费视频一区二区三区| 自拍av在线| 欧美成人午夜激情在线| 韩国午夜理伦三级不卡影院| 第三区美女视频在线| 人妖精品videosex性欧美| 国产精品自拍av| 草美女在线观看| 国产一级二级三级精品| 午夜精品久久久久久久久久| 黄色美女久久久| 久久综合色视频| 亚洲欧洲在线看| 久久aⅴ国产欧美74aaa| 日本三级视频在线播放| 91精品久久久久久久久青青| 国产精品久久久久久久久免费丝袜 | 蜜臀av一区二区在线免费观看| 亚洲尤物在线视频| 91精品国产色综合| 国产欧美日韩另类一区| 成人免费观看49www在线观看| 欧美日韩dvd| 亚洲视频777| 国产成人精品aa毛片| 欧美黄色网页| 韩国无码av片在线观看网站| 日韩电影在线观看中文字幕| 精品一区二区三区av| 大菠萝精品导航| 中文字幕乱码免费| 亚洲人成五月天| 国产福利不卡视频| 视频二区不卡| 人妻av中文系列| 久热精品视频在线免费观看| 97国产一区二区| 日韩中文一区二区| 韩国av电影免费观看| 欧美专区在线播放| 亚洲一区视频在线| 亚洲欧美偷拍自拍| 成人全视频高清免费观看| 国产在线观看一区| 日韩欧美一区在线| 国产精品99久久久| 久久青草免费| www.com操| 国产精品偷伦视频免费观看国产| 精品二区三区线观看| 国产精品激情| 青草影视电视剧免费播放在线观看| 日韩动漫在线观看| 中文字幕亚洲字幕| 国产精品久久久久精k8| 欧美精品羞羞答答| 在线国产情侣| 亚洲区一区二区三区| 国产亚洲福利一区| 国产精品久久久久久妇女6080| 国产成人一区| 求av网址在线观看| 国产乱淫av片杨贵妃| 91tv亚洲精品香蕉国产一区7ujn| 午夜精品福利在线| 蜜桃在线一区二区三区| 风间由美一区二区av101| 色综合久久中文综合久久牛| 日韩欧美在线免费| 欧美国产禁国产网站cc| 中文字幕 久热精品 视频在线 | 男女视频在线| 亚洲成人影院麻豆| www.神马久久| 秋霞欧美视频| 亚洲国产二区| 极品美女销魂一区二区三区| 91丨porny丨蝌蚪视频| 在线观看三级视频欧美| 欧美性猛交xxxxx水多| 亚洲精品国产美女| 国产视频精品久久久| 国产精品麻豆va在线播放| 农村寡妇一区二区三区| 亚洲人成网站在线播放2019| 91久久影院| 香蕉人人精品| 欧美日韩色图| 国产精品乱码一区二区三区软件| 欧美亚洲高清一区| 国产欧美亚洲精品| 日本欧洲一区| 欧美日韩看看2015永久免费| 久久午夜老司机| 色综合天天视频在线观看| 日韩中文综合网| 国产日韩欧美日韩| 小小水蜜桃在线观看| 麻豆蜜桃在线观看| 中文视频一区| 一区二区三区在线观看动漫| 日韩欧美一区在线观看|