資料庫的鎖

2021-10-19 10:04:35 字數 2321 閱讀 6511

是用於管理對共享資源的併發訪問,是資料庫系統區別於檔案系統的乙個關鍵特性

本文主要來談innodb引擎,innodb引擎支援行鎖、表鎖粒度的鎖

為了支援多粒度鎖定,innodb 儲存引擎引入了意向鎖(intention lock

意向鎖是表級鎖

什麼是意向鎖呢?如果沒有意向鎖,當已經有人使用行鎖對錶中的某一行進行修改時,如果另外乙個請求要對全表進行修改,那麼就需要對所有的行是否被鎖定進行掃瞄,在這種情況下,效率是非常低的;不過,在引入意向鎖之後,當有人使用行鎖對錶中的某一行進行修改之前,會先為表新增意向排他鎖(ix),再為行記錄新增排他鎖(x),在這時如果有人嘗試對全表進行修改就不需要判斷表中的每一行資料是否被加鎖了

申請意向鎖的動作是資料庫完成的,就是說,事務a申請一行的行鎖的時候,資料庫會自動先開始申請表的意向鎖,不需要我們程式設計師使用**來申請。ix,is是表級鎖,不會和行級的x,s鎖發生衝突。只會和表級的x,s發生衝突

共享鎖(讀鎖、s鎖),允許事務讀一行資料。

排他鎖(寫鎖、x鎖),允許事務刪除或更新一行資料。

讀鎖會阻塞其他事務寫,寫鎖會阻塞其他事務的讀和寫

首先需要了解mvcc + 2pl + 事務隔離級別

ref:

首先我們需要了解mvcc(multi-version concurrency control),與mvcc相對的,是基於鎖的併發控制,lock-based concurrency control)

特點:讀不加鎖,讀寫不衝突

innodb之所以併發高,因為快照讀不加鎖,所有普通select都是快照讀

mvcc只在 read committed 和 repeatable read 2個隔離級別下工作

快照讀:簡單的select操作,屬於快照讀,不加鎖。(當然,也有例外)

select * from table where ?;
當前讀:特殊的讀操作,插入/更新/刪除操作,屬於當前讀,需要加鎖。

select * from table where ? lock in share mode;

select * from table where ? for update;

insert into table values (…);

update table set ? where ?;

delete from table where ?;

所有以上的語句,都屬於當前讀,讀取記錄的最新版本。並且,讀取之後,還需要保證其他併發事務不能修改當前記錄,對讀取記錄加鎖。其中,除了第一條語句,對讀取記錄加s鎖 (共享鎖)外,其他的操作,都加的是x鎖 (排它鎖)。

在rr級別下,快照讀是通過mvvc(多版本控制)和undo log來實現的,當前讀是通過加record lock(記錄鎖)和gap lock(間隙鎖)來實現的。

mvcc原理分析

資料庫遵循的是兩段鎖協議,將事務分成兩個階段,加鎖階段和解鎖階段(所以叫兩段鎖)

鎖可以實現事務併發,但也導致了一些問題

read uncommited

可以讀取未提交記錄。此隔離級別,不會使用,忽略。

read committed (rc)

針對當前讀,rc隔離級別保證對讀取到的記錄加鎖 (記錄鎖),存在不可重複讀

repeatable read (rr)

針對當前讀,rr隔離級別保證對讀取到的記錄加鎖 (記錄鎖),同時保證對讀取的範圍加鎖,新的滿足查詢條件的記錄不能夠插入 (間隙鎖),存在幻讀

這也是innodb的預設隔離級別

serializable

從mvcc併發控制退化為基於鎖的併發控制。不區別快照讀與當前讀,所有的讀操作均為當前讀,讀加讀鎖 (s鎖),寫加寫鎖 (x鎖),不存在幻讀。

innobdb加鎖是對索引加行鎖。如果沒有索引的話,會給整張表的所有資料行的加行鎖,再進行過濾,發現不滿足後,會呼叫unlock_row方法,把不滿足條件的記錄釋放鎖 (違背了二段鎖協議的約束)

實現方式:

實現方式:

避免幻讀 next-key = 行鎖+gap鎖

資料庫的鎖

相當好的文章!希望以後結合實踐再好好理解。innodb中的事務隔離級別和鎖的關係 mysql faq 系列 如何檢視當前最新事務id mysql 對於千萬級的大表要怎麼優化?鎖有悲觀鎖和樂觀鎖。悲觀鎖中分共享鎖和排他鎖。在事務中,讀資料的時候加分享鎖 其他事務還可以加分享鎖,但是不能加排他鎖 寫資料...

資料庫的鎖

innodb 除了支援行級鎖,還支援由 mysql 服務層實現的表級鎖 lock tables write在指定的表加上表級排他鎖 當這兩種鎖同時存在時,可能導致衝突。例如,事務 a 獲取了表中一行資料的讀鎖 然後事務 b 申請該錶的寫鎖 例如修改表的結構 如果事務 b 加鎖成功,那麼它就應該能修改...

資料庫的鎖

資料庫的鎖用來鎖住資料庫中的某些資料,使得當前只能有乙個使用者 會話可以更新資料。所以,資料庫的鎖用來防止同時有乙個或多個使用者更新同一塊資料。當資料被鎖起來,這意味著另乙個資料庫會話在鎖釋放之前不能更新這塊被鎖起來的資料。畫重點 假如會話a嘗試訪問被會話b鎖起來的資料,會話a會發生什麼?會話a會被...