Mysql InnoDB底層實現

2021-10-25 03:22:52 字數 2874 閱讀 2338

innodb的基本儲存結構是頁,頁也是innodb儲存引擎管理資料庫的最小磁碟單位。

因此,我們需要將無序的資料變得相對有序,以加快查詢速度,這就是索引的作用。

innodb 是通過 b+tree 結構對主鍵建立索引,然後在葉子節點中儲存記錄,該索引被稱作聚集索引。採用 innodb 引擎的資料儲存檔案有兩個,乙個定義檔案,乙個是資料檔案。

若建索引的字段不是主鍵 id,則對該字段建索引,然後在葉子節點中儲存的是該記錄的主鍵,然後通過主鍵索引找到對應的記錄,該索引被稱作非聚集索引。

innodb一共有8種鎖型別,其中,意向鎖(intention locks)和自增鎖(auto-inc locks)是表級鎖,剩餘全部都是行級鎖。此外,共享鎖或排它鎖(shared and exclusive locks)儘管也作為8種鎖型別之一,它卻並不是具體的鎖,它是鎖的模式,用來「修飾」其他各種型別的鎖。

它並不是一種鎖的型別,而是其他各種鎖的模式,每種鎖都有shard或exclusive兩種模式。

當我們說到共享鎖(s鎖)或排它鎖(x鎖)時,一般是指行上的共享鎖或者行上的排它鎖。需要注意的是,表鎖也存在共享鎖和排它鎖,即表上的s鎖和表上的x鎖,表上的鎖除了這兩種之外,還包括下面將會提到的意向共享鎖(shard intention locks)即is鎖、意向排它鎖(exclusive intention locks)即ix鎖。表上的鎖,除了這四種之外,還有其他型別的鎖,這些鎖都是在訪問表的元資訊時會用到的(create table/alter table/drop table等)

s鎖允許乙個事務讀取一行,多個使用者可以同時讀取同乙個資源,但是阻止其他事務獲得相同資料集的x鎖,也就是不允許修改。

x鎖會允許獲得排他鎖的事務更新資料,但是阻止其他事務取得相同資料集的s鎖和x鎖,也就是說x鎖會阻塞其他的寫鎖和讀鎖。

舉例:

情景一:假設t1持有資料行r上的s鎖,則當t2請求r上的鎖時:

1. t2請求r上的s鎖,則,t2立即獲得s鎖。t1和t2同時都持有r上的s鎖。

2. t2請求r上的x鎖,則,t2無法獲得x鎖。t2必須要等待直到t1釋放r上的s鎖。

情景二:假設t1持有r上的x鎖,則當t2請求r上的鎖時:

t2請求r上的任何型別的鎖時,t2都無法獲得鎖,此時,t2必須要等待直到t1釋放r上的x鎖。

為了允許行鎖和表鎖共存,實現多粒度鎖機制,innodb有兩種內部使用的意向鎖,有shard或exclusive兩種模式,這兩種意向鎖都是表鎖。

意向鎖的目的是告知其他事務,某事務已經鎖定了或即將鎖定某個/些資料行。事務在獲取行鎖之前,首先要獲取到意向鎖,即:

事務在獲取行上的s鎖之前,事務必須首先獲取 表上的 is鎖或表上的更強的鎖。

事務在獲取行上的x鎖之前,事務必須首先獲取 表上的 ix鎖。

事務請求鎖時,如果所請求的鎖 與 已存在的鎖相容,則該事務 可以成功獲得 所請求的鎖;如果所請求的鎖 與 已存在的鎖衝突,則該事務 無法獲得 所請求的鎖。

意向鎖is和ix和任何行鎖都相容,它實際上只會阻塞全表請求
也就是所謂的行鎖,鎖定的是索引記錄。索引記錄鎖總是鎖定索引記錄,即使表上並未定義索引。表未定義索引時,innodb自動建立隱藏的聚集索引(索引名字是gen_clust_index),使用該索引執行record lock。

索引記錄之間的間隙上的鎖,鎖定尚未存在的記錄,即索引記錄之間的間隙。有shard或exclusive兩種模式,但,兩種模式沒有任何區別,二者等價。

gap lock鎖住的間隙可以是第乙個索引記錄前面的間隙,或相鄰兩條索引記錄之間的間隙,或最後乙個索引記錄後面的間隙。

innodb索引是b+樹形式的,因此索引是從小到大按序排列的,在索引記錄上查詢給定記錄時,innodb會在第乙個不滿足查詢條件的記錄上加gap lock,防止新的滿足條件的記錄插入。

gap lock存在的唯一目的就是阻止其他事務向gap中插入資料行,它用於在隔離級別為rr時,阻止幻影行(phantom row)的產生;隔離級別為rc時,搜尋和索引掃瞄時,gap lock是被禁用的,只在 外來鍵約束檢查 和 重複key檢查時gap lock才有效,正是因為此,rc時會有幻影行問題。

gap lock是rr(可重複讀)和rc(讀已提交)隔離級別的乙個重要區別
next-key lock 是 (索引記錄上的索引記錄鎖) + (該索引記錄前面的間隙上的鎖) 二者的合體,它鎖定索引記錄以及該索引記錄前面的間隙。有shard或exclusive兩種模式。

當innodb 搜尋或掃瞄索引時,innodb在它遇到的索引記錄上所設定的鎖就是next-key lock,它會鎖定索引記錄本身以及該索引記錄前面的gap。

一種特殊的gap lock。insert操作插入成功後,會在新插入的行上設定index record lock,但,在插入行之前,insert操作會首先在索引記錄之間的間隙上設定insert intention lock,該鎖的範圍是(插入值, 向下的乙個索引值)。有shard或exclusive兩種模式,但,兩種模式沒有任何區別,二者等價。、

insert intention lock發出按此方式進行插入的意圖:多個事務向同乙個index gap併發進行插入時,多個事務無需相互等待。
自增鎖也是表鎖,在向帶有auto_increment列 的表時插入資料行時,事務需要首先獲取到該錶的auto-inc表級鎖,以便可以生成連續的自增值。插入語句開始時請求該鎖,插入語句結束後釋放該鎖(注意:是語句結束後,而不是事務結束後)。

這個鎖使用較為稀少,可以檢視mysql技術文件自行拓展

MySQL InnoDB 行鎖實現

2019獨角獸企業重金招聘python工程師標準 mysql innodb 行鎖是通過給索引上的索引項加鎖來實現的。oracle 是通過在資料塊中對相應資料行加鎖來實現的。mysql innodb這種行鎖實現特點意味著 只有通過索引條件檢索資料,innodb才使用行級鎖,否則,innodb將使用表鎖...

MySQL innodb 索引 B 樹實現

首先說說mysql裡面索引的型別 從資料結構角度 1 b 樹索引 o log n 2 hash索引 a 僅僅能滿足 in 和 查詢,不能使用範圍查詢 b 其檢索效率非常高,索引的檢索可以一次定位,不像b tree 索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次的io訪問,所以 hash 索引...

MySQL Innodb的MVCC實現原理

mvcc是multi version concurrency control的縮寫,也就是多版本併發控制。大家都知道,事務的隔離可以通過行鎖來實現。在開啟事務時,對操作記錄加行鎖,事務結束時釋放鎖。但是這樣加鎖會降低事務的併發量,並且對執行緒的阻塞和恢復操作也會損耗效能。那種在事務中使用了selec...