《MySQL——幻讀與next-key lock與間隙鎖帶來的死鎖》

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);

該表除了主鍵id,還有索引c。

問下面的語句序列,是怎么加鎖的,加的鎖又是什么時候釋放的呢?

begin;
select * from t where d = 5 for update;
commit;

這條語句會命中d=5這一行,對應主鍵id=5,因此在select語句執行完成后,id=5這一行會加一個寫鎖,并且由于兩階段鎖協議,這個寫鎖會在執行commit語句的時候釋放。

由于字段d上沒有索引,因此這條查詢語句會做全表掃描,那么,其他被掃描的不滿足的行記錄會不會被加鎖?

幻讀現象

如果旨在id=5這一行加鎖,而其他行不加鎖,在下面這個情況下:
在這里插入圖片描述
session A執行了三次當前讀,并且加上了寫鎖。

幻讀指的是一個事務在前后兩次查詢同一個范圍的時候,后一次查詢看到了前一次查詢沒有看到的行。

幻讀與不可重復讀的區別

在同一個事務中,兩次讀取到的數據不一致的情況稱為幻讀和不可重復讀。幻讀是針對insert導致的數據不一致,不可重復讀是針對 delete、update導致的數據不一致。

1、在可重復讀隔離級別下,普通的查詢是快照讀,是不會看到別的事務插入的數據的。

2、session B的修改結果被session A之后的select語句用當前讀看到,不能稱為幻讀。幻讀僅僅指"新插入的行"

幻讀帶來的問題

1、破壞語義。

session A在T1就說了,把d=5的行鎖住,不準別的事務進行讀寫,此時被破壞。

因為如果我們這時插入d=5的數據,這條新的數據不在鎖的保護范圍之內。

2、數據一致性問題

鎖的設計是為了保證數據的一致性,不止是數據庫內部數據狀態在此刻的一致性,還包含了數據和日志在邏輯上的一致性。

即使給所有行加上了鎖,也避免不了幻讀,這是因為給行加鎖的時候,這條記錄還不存在,沒法加鎖 。

也就是說即使把所有的記錄都上鎖了,還是阻止不了新插入的記錄

如何解決幻讀

產生的幻讀的原因是:行鎖只能鎖住行

為了解決幻讀問題,InnoDB引入新的鎖:間隙鎖(Gap Lock)

間隙鎖,鎖的就是兩個值之間的空隙,比如在表t,初始化插入了6個記錄,就產生了7個間隙:
在這里插入圖片描述

執行:

select * from t where d = 5 for update

6個記錄加上了行鎖,同時加上了7個間隙鎖。

間隙鎖與行鎖有點不一樣

行鎖可以分為讀鎖與寫鎖
在這里插入圖片描述

與行鎖有沖突關系的是另外一個行鎖。

間隙鎖不一樣,間隙鎖之間不存在沖突關系。

與間隙鎖存在沖突關系的,是"向間隙中插入一個記錄"這個操作。

舉例:
在這里插入圖片描述
由于表t中并沒有c=7這個記錄,所以session A加的是間隙鎖(5,10)。而session B也是在這個間隙加的間隙鎖,它們的目標都是保護這個間隙,不允許插入值,所以兩者不沖突。

next-key lock

間隙鎖與行鎖合稱next-key lock,每個lock都是前開后閉區間。間隙鎖是開區間。

如上面我們插入數據,使用:

select * from t for update

形成了7個next-key lock,分別是:

(-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]

supremum是一個不存在的最大值。

next-key lock 的引入解決了幻讀問題,但是也帶來了新的問題。

如,現在有這樣一個業務邏輯:

任意鎖住一行,如果這一行不存在的話就插入,如果存在這一行就更新它的數據。

begin;
select * from t where id = N for update;
--如果行不存在
insert into t values(N,N,N);
--如果行存在
update t set d = N set id = N;commit;

現在出現這個現象:這個邏輯一旦有并發,就會碰到死鎖。
在這里插入圖片描述

死鎖的產生:兩個間隙鎖不沖突,相互等待行鎖

執行流程:

1、session A執行select…for update語句,由于id=9這一行不存在,因此會加上間隙鎖(5,10)

2、session B執行select…for update語句,同樣會加上間隙鎖(5,10)

3、session B插入(9,9,9),被session A的間隙鎖鎖住,進入等待

4、session A擦汗如·插入(9,9,9),被session B的間隙鎖鎖住。

InnoDB死鎖檢測發現了這對死鎖關系,然后報錯返回了。

所以說間隙鎖的引入可能會導致相同的語句鎖住更大的范圍,從而影響并發度。

間隙鎖是在可重復讀隔離級別下才會生效的。所以,你如果把隔離級別設置為讀提交的話,就沒有間隙鎖了。 但同時,你要解決可能出現的數據和日志不一致問題,需要把 binlog 格式設置為 row。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377209.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377209.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377209.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

css 陰影 效果_CSS陰影效果

css 陰影 效果CSS中的陰影效果 (Shadow Effects in CSS) It is always good to make our web pages stylish and beautiful, web pages that would catch users eyes instantly but one gets confused as to how to style his or her web page. The confusion is quite legit t…

java常見的ClassNotFoundException-----菜鳥學習java

java常見的ClassNotFoundException 1 - java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory 添加包common-logging.jar2 - java.lang.ClassNotFoundException: javax.transaction.Synchronization 添加包jta.jar(hiberante)3 - java.lang.ClassNo…

關于easyui的一些小知識點(1)

讓layout布局自動適應瀏覽器寬度只需要加上fit"true"屬性。轉載于:https://www.cnblogs.com/haifg/p/3613789.html

《MySQL——加鎖規則(待補全,有些沒看懂)》

catalog加鎖規則等值查詢間隙鎖非唯一索引等值鎖主鍵索引范圍鎖非唯一索引范圍鎖唯一索引范圍鎖 bug非唯一索引上存在"等值"的例子limit語句加鎖關于死鎖總結 1、查詢過程中訪問到的對象才會加鎖,而加鎖的基本單位是next-key lock(前開后閉&am…

c# 命名空間命名規范_C#中的命名空間

c# 命名空間命名規范C#命名空間 (C# Namespace ) In C# namespaces are used to group similar type of classes. Two classes with same name in different namespaces never conflict to each other. 在C#中,名稱空間用于對相似類型的類進…

PHP環境搭建:Windows 7下安裝配置PHP+Apache+Mysql環境教程

這兩天剛裝好Windows 7,碰巧前段時間有朋友問我Windows下如何安裝搭建PHP環境,所以打算勤勞下,手動一步步搭建PHP環境,暫且不使用PHP環境搭建軟件了,在此詳細圖解在Windows 7下安裝配置PHPApacheMysql環境的教程&#…

《MySQL—— 業務高峰期的性能問題的緊急處理的手段 》

catalog短連接風暴先處理占著連接但是不工作地線程減少連接過程的消耗慢查詢性能問題索引沒有設計好語句沒寫好選錯索引QPS突增問題短連接風暴 正常的短連接: 執行很少sql語句就斷開,下次需要的時候再重連。MySQL建立連接的過程成本很高,包含…

sql 算出下級銷售總和_找出總和字符串

sql 算出下級銷售總和Description: 描述: This is a standard interview problem to check that the given string is a sum string or not using backtracking. 這是一個標準的面試問題,用于檢查給定的字符串是否為總和字符串或不使用回溯。 Problem…

Request 分別獲取具有相同 name 屬性表單元素值

html 中是允許多個具有相同name屬性的元素的&#xff0c;例如 <div> <input name"txtName" id"txtFirstName" type"text" /> <input name"txtName" id"txtMiddleName" type"text" /> <input…

《MySQL——redo log 與 binlog 寫入機制》

目錄binlog寫入機制redo log寫入機制組提交機制實現大量的TPS理解WAL機制如何提升IO性能瓶頸WAL機制告訴我們&#xff1a;只要redo log與binlog保證持久化到磁盤里&#xff0c;就能確保MySQL異常重啟后&#xff0c;數據可以恢復。 下面主要記錄一下MySQL寫入binlog和redo log的…

BBIAB的完整形式是什么?

BBIAB&#xff1a;再回來一點 (BBIAB: Be Back In A Bit) BBIAB is an abbreviation of "Be Back In A Bit". BBIAB是“ Be Back in A Bit”的縮寫 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites lik…

字符串:KMP Eentend-Kmp 自動機 trie圖 trie樹 后綴樹 后綴數組

涉及到字符串的問題&#xff0c;無外乎這樣一些算法和數據結構&#xff1a;自動機 KMP算法 Extend-KMP 后綴樹 后綴數組 trie樹 trie圖及其應用。當然這些都是比較高級的數據結構和算法&#xff0c;而這里面最常用和最熟悉的大概是kmp&#xff0c;即使如此還是有相當一部分人也…

WPF CanExecuteChanged

繼承ICommand ,RelayCommand命令 1 public class RelayCommand : ICommand2 {3 private readonly Action _execute;4 private readonly Func<bool> _canExecute;5 public event EventHandler CanExecuteChanged;6 public RelayComma…

《MySQL——主備一致性六問六答》

目錄備庫為什么要設置為只讀模式&#xff1f;備庫設置為只讀&#xff0c;如何與主庫保持同步更新&#xff1f;A到B的內部流程如何&#xff1f;binlog內容是什么&#xff1f;row格式對于恢復數據有何好處M-M結構的循環復制問題以及解決方案備庫為什么要設置為只讀模式&#xff1…

代碼管理工具

http://blogs.msdn.com/b/visualstudio/archive/2012/06/11/world-of-samples-at-your-fingertips.aspx轉載于:https://www.cnblogs.com/hebeiDGL/archive/2012/09/25/2700961.html

fyi 在郵件里是什么意思_FYI的完整形式是什么?

fyi 在郵件里是什么意思僅供參考&#xff1a;供您參考 (FYI: For Your Information) FYI is an acronym of "For Your Information". It is a widespread internet slang used these days in text messaging, instant messaging, and chatting on Facebook, WhatsApp…

Hyper-V 替換 vmwp

要激活 Hyper-V 下的虛機 最簡單的方法是用帶證書的vmwp替換掉原來的 帶證書的vmwp參見&#xff1a;http://bbs.pcbeta.com/viewthread-1408240-1-1.html 下載后腰替換 先把 Hyper-V 的倆服務停止掉 然后找到 C:\Windows\System32\vmwp.exe 右鍵--安全 替換掉所有者 然后給自己…

《MySQL——主備切換流程與主備延遲》

目錄主備切換主備延遲的原因可靠性優先策略的主備切換流程可用性優先策略的主備切換流程主備切換 主備切換分為主動運維與被動操作。 軟件升級、主庫所在機器按計劃下線為主動運維。 主庫所在機器掉電為被動操作。 同步延遲 1、主庫A執行完一個事務&#xff0c;寫入binlog…

ejb模式_EJB的完整形式是什么?

ejb模式EJB&#xff1a;企業Java Bean (EJB: Enterprise Java Bean) EJB is an abbreviation of Enterprise Java Bean. EJB is one of many Java application programming interfaces (API) for flexible and manageable structuring of Java Platform, Enterprise Edition (J…

Android之PreferenceActivity

http://www.cnblogs.com/wservices/archive/2010/07/08/1773449.html 看到很多書中都沒有對PreferenceActivity做介紹&#xff0c;而我正好又在項目中用到&#xff0c;所以就把自己的使用的在這總結一下&#xff0c;也方便日后查找。 PerferenceActivity是什么&#xff0c;看下…