成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL 核心模塊揭秘—隱式鎖

開發 前端
隱式鎖,是排他普通記錄鎖的一種特殊存在形式。我們查詢不到隱式鎖的加鎖情況,只能根據我們的經驗判斷記錄上是否存在隱式鎖。

1. 什么是隱式鎖?

前面我們介紹了行鎖的共享鎖、排他鎖。按照精確模式,它們又都可以細分為普通記錄鎖、間隙鎖、Next-Key 鎖。

另外,還有一種專門用于插入記錄場景的插入意向鎖。

事務讀寫記錄需要加這些行鎖時,會發起加鎖操作,申請新的行鎖結構或者復用已有的行鎖結構。

有了對應的行鎖結構,我們就可以通過 performance_schema.data_locks 表查詢到這些行鎖的加鎖情況了。InnoDB 內部把這種有對應鎖結構的行鎖稱為顯式鎖。

隱式鎖,是相對于顯式鎖而言的,它也是一種行鎖,而且是普通記錄鎖的一種特殊存在形式。

顧名思義,既然是隱式鎖,也就意味著我們查詢不到它的加鎖情況。

我們之所以查詢不到,是因為隱式鎖沒有對應的行鎖結構,它就像空氣一樣,神在,形不在。

我們知道空氣是存在的,通常情況下,我們看不見,也摸不著。但是,熱空氣遇冷之后,凝結成小水珠,我們就能看得見,也能摸得著了。

我們也知道隱式鎖是存在的,卻查詢不到。它也會像空氣一樣,有被看見的時候嗎?

是的,它也有被看見的時候。但是,當它被看見的時候,已經換了一種形式,不再是隱式鎖了,而是變成了顯式鎖。

隱式鎖變成顯式鎖之后,我們就可以通過 performance_schema.data_locks 表查詢到加鎖情況了。

那么,問題來了,隱式鎖到底是被看見了,還是沒有被看見呢?

2. 怎么判斷存在隱式鎖?

隱式鎖,不僅可以存在于主鍵索引記錄上,還可以存在于二級索引記錄上。

在它變成顯式鎖之前,我們怎么判斷一條記錄上是否存在隱式鎖呢?

我根據代碼邏輯歸納了四種情況。

情況 1,事務執行 insert 語句或者 update 語句插入一條記錄到主鍵索引中,事務提交之前,這條記錄上存在隱式鎖。

update 語句不是更新記錄嗎,怎么還會插入記錄?

如果你也有這樣的疑問,說明這是個好問題。

有一種場景:如果 update 語句更新了主鍵字段值,主鍵索引的原記錄會被標記刪除,然后插入一條新記錄。

其中,原記錄的主鍵字段為更新之前的值,新記錄的主鍵字段為更新之后的值。

情況 2,事務執行 insert 語句插入一條記錄到二級索引中,事務提交之前,這條記錄上存在隱式鎖。

情況 3,事務執行 update 語句更新了二級索引的某個字段,二級索引的原記錄會被標記刪除,然后插入一條新記錄,事務提交之前,原記錄和新記錄上都存在隱式鎖。

情況 4,事務執行 delete 語句,如果掃描記錄時沒有使用二級索引,二級索引記錄不會被顯式加鎖。

二級索引記錄被標記刪除之后,事務提交之前,記錄上都存在隱式鎖。

根據代碼邏輯歸納出所有情況是很困難的,為了幫助我們更好的判斷記錄上是否存在隱式鎖,我們有必要看看 InnoDB 代碼里的判斷邏輯長什么樣。

InnoDB 代碼里,判斷記錄上是否存在隱式鎖的邏輯,和索引類型有關。

對于主鍵索引,判斷邏輯比較簡單。

InnoDB 會從主鍵索引記錄的 DB_TRX_ID 字段中讀取事務 ID,找到最后操作這條記錄的事務。

只要主鍵索引記錄上沒有顯式鎖,并且最后操作記錄的事務還沒有提交,就認為這條記錄上存在隱式鎖。

對于二級索引,因為索引記錄中沒有 DB_TRX_ID 字段,判斷邏輯會比主鍵索引復雜一點。

二級索引數據頁的頭信息中有個 PAGE_MAX_TRX_ID 字段,表示最后修改數據頁中任意一條記錄的事務 ID。

以某個二級索引中的一條記錄(S1)為例,判斷這條記錄上是否存在隱式鎖的主要步驟如下:

第 1 步,讀取 S1 所屬數據頁頭信息中的 PAGE_MAX_TRX_ID 字段,看看這個事務 ID 對應的事務是否已經提交了。

如果事務已經提交,說明 S1 上不存在隱式鎖。

如果事務還沒有提交,進入第 2 步。

第 2 步,根據 S1 中的主鍵字段,回表查詢對應的主鍵索引記錄。

找到主鍵索引記錄之后,從它的 DB_TRX_ID 字段中讀取事務 ID,看看這個事務 ID 對應的事務是否已經提交了。

如果事務已經提交,說明 S1 上不存在隱式鎖。

如果事務還沒有提交,那就麻煩了,需要進一步判斷,這個代碼邏輯就很晦澀了。

不過,值得欣慰的是,雖然代碼邏輯很晦澀,但是用大白話描述起來可以很簡單。

用大白話描述是這樣的:只要這個還沒有提交的事務操作過 S1,不管這個操作是插入,還是刪除,都意味著 S1 上存在隱式鎖。

3. 轉換為顯式鎖

如果某條記錄上存在隱式鎖,在需要時,會被轉換被顯式鎖。這個轉換主要發生在兩種場景下。

場景一,記錄(R1)上存在隱式鎖,其它事務(A)讀寫 R1 之前,如果需要對 R1 加行鎖,事務 A 會把 R1 上的隱式鎖轉換為顯式鎖,然后等待 R1 上的行鎖被釋放之后,事務 A 才能獲得鎖。

場景二,某個事務部分回滾時,如果它操作過的記錄上存在隱式鎖,會被轉換為顯式鎖。

部分回滾,指的是把事務回滾到某個保存點。這個保存點可以是我們手動創建的保存點,也可以是 InnoDB 內部創建的保存點。

InnoDB 內部創建的保存點,主要用于插入記錄出現沖突時,回滾已經執行的操作。

介紹完隱式鎖轉換為顯式鎖的場景,我們再來看看隱式鎖會被轉換成什么樣的顯式鎖。

前面我們介紹過,隱式鎖是普通記錄鎖的一種特殊存在形式,所以,它也是普通記錄鎖。

隱式鎖,既可以存在于剛剛插入的記錄上,也可以存在于標記刪除的二級索引記錄上,所以,它又是一種排他鎖。

兩者綜合起來,隱式鎖本質上相當于排他普通記錄鎖。

發生轉換時,隱式鎖會被轉換為排他普通記錄鎖。這個轉換邏輯是不是又簡單又粗暴?

4. 總結

隱式鎖,是排他普通記錄鎖的一種特殊存在形式。

我們查詢不到隱式鎖的加鎖情況,只能根據我們的經驗判斷記錄上是否存在隱式鎖。

在某些場景下,隱式鎖會被轉換為顯式鎖,然后,我們就可以通過 performance_schema.data_locks 表查詢到加鎖情況了。

責任編輯:武曉燕 來源: 愛可生開源社區
相關推薦

2024-04-03 08:20:53

MySQL核心模塊

2024-06-05 11:49:33

2024-05-15 09:05:42

MySQL核心模塊

2024-08-07 14:58:00

MySQL釋放鎖核心模塊

2024-10-30 10:38:08

2024-10-16 11:11:51

隔離InnoDB死鎖

2024-09-04 08:44:18

MySQL核心模塊

2024-03-27 13:33:00

MySQLInnoDB事務

2024-05-29 10:17:01

2025-02-26 08:26:38

2010-11-16 15:11:52

Oracle隱式游標

2024-11-05 10:52:07

2017-12-20 14:14:16

數據庫MySQL數據類型

2022-02-23 21:24:21

索引SQL字符

2024-07-29 09:57:47

2023-12-12 08:50:22

MySQL隱式轉換varchar

2010-01-26 14:04:02

2009-09-01 10:49:28

C#具有隱式類型聲明

2009-09-04 10:49:19

C#隱式轉換

2009-09-11 10:07:05

Linq隱式類型化局部
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产区在线视频 | 国产亚洲一区二区三区 | 91精品国产色综合久久不卡98 | 激情五月婷婷在线 | 欧美一区二区三区在线视频 | 色视频网站在线观看 | 欧美国产一区二区 | 蜜臀av日日欢夜夜爽一区 | 亚洲午夜精品一区二区三区 | 国产精品成人一区二区三区夜夜夜 | 国产欧美在线播放 | 亚洲精品在线视频 | 日本视频中文字幕 | 国产精品国产成人国产三级 | 毛片一区二区三区 | 国产精品一二区 | www.干| 欧美激情亚洲 | 深夜福利影院 | jlzzjlzz欧美大全 | 二区在线观看 | 本道综合精品 | 岛国av免费观看 | 伊人色综合久久天天五月婷 | 午夜激情一区 | 看片91 | 国产精品久久久久久久久久久新郎 | 欧美日韩淫片 | 中文在线一区二区 | 欧美一区中文字幕 | 午夜精品视频 | 欧美一级全黄 | 日韩免费在线 | 国产黄色网址在线观看 | 99精品一区二区三区 | 91久久北条麻妃一区二区三区 | 午夜寂寞影院列表 | 成人妇女免费播放久久久 | 成人国产在线观看 | 伊人精品一区二区三区 | 欧美精品一区二区三区四区五区 |