資料庫的隔離級別和鎖

2021-09-23 13:39:30 字數 2530 閱讀 8655

關於鎖和資料庫的隔離級別可以參考下面的部落格

資料庫悲觀鎖:更新鎖u和u,排他鎖x互斥,和讀鎖s共享。當for update的時候會對所查詢行上u鎖,這時候select 語句上s鎖可以正常查詢,但是select for update 會等u鎖釋放,以加u鎖。修改操作也會等u鎖釋放以加x鎖。

注:共享鎖和共享鎖不互斥,共享鎖和更新鎖不互斥,其他都互斥。

mysql的可重讀和讀已提交級別用的mcvv概念,讀已提交讀的都是最新的snapshot,可重讀是讀取的當前事務id及以前的資料:

innodb會為每一行新增兩個字段,分別表示該行建立的版本刪除的版本,填入的是事務的版本號,這個版本號隨著事務的建立不斷遞增。在repeated read的隔離級別(事務的隔離級別請看這篇文章)下,具體各種資料庫操作的實現:

select:滿足以下兩個條件innodb會返回該行資料:(1)該行的建立版本號小於等於當前版本號,用於保證在select操作之前所有的操作已經執行落地。(2)該行的刪除版本號大於當前版本或者為空。刪除版本號大於當前版本意味著有乙個併發事務將該行刪除了。

insert:將新插入的行的建立版本號設定為當前系統的版本號。

delete:將要刪除的行的刪除版本號設定為當前系統的版本號。

update:不執行原地update,而是轉換成insert + delete。將舊行的刪除版本號設定為當前版本號,並將新行insert同時設定建立版本號為當前版本號。

其中,寫操作(insert、delete和update)執行時,需要將系統版本號遞增。

由於舊資料並不真正的刪除,所以必須對這些資料進行清理,innodb會開啟乙個後台執行緒執行清理工作,具體的規則是將刪除版本號小於當前系統版本的行刪除,這個過程叫做purge。

mysql實現mvcc:

在mysql中mvcc是在innodb儲存引擎中得到支援的,innodb為每行記錄都實現了三個隱藏字段:

6位元組的事物id用來標識該行所述的事務,7位元組的回滾指標需要了解下innodb的事務模型。

為了支援事務,innbodb引入了下面幾個概念:

mvcc執行在 讀已提交 和可重讀 這兩個隔離級別下,當innodb隔離級別設定為二者其一時,在select資料時就會用到版本鏈。innodb為了解決這個問題,設計了readview(可讀檢視)的概念。核心問題是版本鏈中哪些版本對當前事務可見

在 可重讀隔離級別下,每個事務touch first read時(本質上就是執行第乙個select語句時,後續所有的select都是復用這個readview,其它update,delete,insert語句和一致性讀snapshot的建立沒有關係),會將當前系統中的所有的活躍事務拷貝到乙個列表生成readview。在 讀已提交 隔離級別下,每個select語句開始時,都會重新將當前系統中的所有的活躍事務拷貝到乙個列表生成readview。二者的區別就在於生成readview的時間點不同,乙個是事務之後第乙個select語句開始、乙個是事務中每條select語句開始。

參考下面

個人理解是,readview會把生成readview時候資料庫當前最大的事物id記錄下來。如果要讀取的mvcc中的乙個記錄的事物id大於readview記錄下的最大id,說明是當前事物建立readview之後提交的,不能訪問,或者是等於readview中的乙個id,說明當前事物建立readview時還沒有提交或者回滾的,也不能訪問,其餘情況都可以訪問(只要刪除標誌不是刪除,因為delete只是將標誌刪除置為刪除,即delete_flagtrue,說明這條記錄已被刪除,不返回。)。讀已提交和可重讀二者的區別就在於生成readview的時間點不同。別的都一樣。

像其他人說的,每條資料會記錄建立時間和刪除時間,mvcc是通過當前事物id和建立時間和刪除時間進行讀取。都是扯淡。

innodb的行級鎖是鎖的索引,如果索引失效或者沒用到索引,就會使用表級鎖,因為他的mvcc特性,導致查詢count(*)必須全表查(畢竟每個事務內訪問的資料域版本都是不一樣的)。

innodb是索引組織表iot,即聚集索引和資料域在乙個儲存空間,儲存的檔案也是乙個,主鍵就是聚集索引,如果沒有主鍵的話會找乙個非空的唯一索引來當聚集索引,如果還沒有的話就預設用innodb的6個位元組的rowid來當聚集索引。非聚集索引的葉子節點儲存的是索引值和聚集索引值,通過索引找到聚集索引值,然後再根據聚集索引值去聚集索引裡面找到資料域。

mylsam是堆組織表hot,即資料域和索引分開,不要求必須有主鍵,儲存的檔案有兩個,myi為索引,myd為資料域,主鍵和普通索引的區別就是主鍵是唯一不空的。他們的葉子節點都是儲存的索引值和資料域的位址。

mvcc詳解

資料庫鎖 隔離級別

併發控制主要是為了多執行緒操作時帶來的資源讀寫問題。如果不加以空間可能會出現死鎖,讀髒資料 不可重複讀 丟失更新等異常。併發操作可以通過加鎖的方式進行控制,鎖又可分為樂觀鎖和悲觀鎖。悲觀鎖 pessimistic locking 併發模式假定系統中存在足夠多的資料修改操作,以致於任何確定的讀操作都可...

資料庫鎖和事務隔離級別

建立表account create table account id int not null auto increment,name varchar 255 default null,balance int default null,primary key id engine innodb def...

資料庫鎖和資料庫隔離級別

最近突然發現忘了資料庫鎖和資料庫隔離級別,時常弄混它們之間的關係。為此特此寫下此部落格,以方便自己複習,同時也可以幫助博友。資料庫鎖 資料庫鎖就是事務t在對某個資料物件 例如表 記錄等 操作之前,先向系統發出請求,對其加鎖。加鎖後事務t就對該資料物件有了一定的控制,在事務t釋放它的鎖之前,其它的事務...