欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL間隙鎖解決幻讀問題

 更新時間:2023年06月06日 11:07:33   作者:逆流°只是風景-bjhxcc  
本文主要介紹了MySQL間隙鎖解決幻讀問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、間隙鎖概念

  • 當我們用范圍條件而不是相等條件檢索數據, 并請求共享或排他鎖時,InnoDB 會給符合條件的已有數據記錄的索引項加鎖;對于鍵值在條件范圍內但并不存在的記錄,叫做“間隙(GAP)” ,InnoDB 也會對這個“間隙”加鎖,這種鎖機制就是所謂的間隙鎖
  • 舉例來說, 假如 user 表中只有 101 條記錄, 其userid 的值分別是 1,2,…,100,101, 下面的 SQL: select * from user where userid > 100 for update;是一個范圍條件的檢索,InnoDB 不僅會對符合條件的 userid 值為 101 的記錄加鎖,也會對userid 大 于 101(但是這些記錄并不存在)的"間隙"加鎖,防止其它事務在表的末尾增加數據
  • InnoDB 使用間隙鎖的目的,是為了防止幻讀,以滿足串行化隔離級別的要求 ,對于上面的例子,要是不使用間隙鎖,如果其他事務插入了 userid 大于 100 的任何記錄,那么本事務如果再次執(zhí)行上述語句,就會發(fā)生幻讀

InnoDB串行化隔離級別使用間隙鎖(gap lock)解決幻讀(事務并發(fā)情況下兩次查詢的數據量不同)問題

間隙鎖專用于串行化隔離級別,可解決幻讀問題,幻讀問題表現為:當前事務沒做操作,前后兩次相同的查詢語句,顯示的數據量不一致

我們把事務2 select的指定的條件分為2類:范圍查詢、等值查詢

record lock:記錄鎖,就是行鎖
gap lock:間隙鎖,不包含記錄本身
next-key lock:record lock(記錄本身) + gap lock(不包括記錄本身)

二、測試間隙鎖范圍加鎖

設置事務為手動提交,然后把隔離級別設置成串行化

查看表結構,id、age、name都有索引

場景1:用不可重復的主鍵id測試間隙鎖

范圍查詢

事務2的select操作只給三行數據加了共享鎖,為什么插入id為24的數據也不行呢?

這是因為在串行化隔離級別中,不僅僅是獲取了滿足條件的這3行的行鎖,而且把表記錄之間以及后邊空洞的地方也加上了間隙鎖

圖中紅色線的地方都上了next-key鎖,上鎖范圍(左開右閉)為:( 11 , 12 ] ∪ ( 12 , 22 ] ∪ ( 22 , 23 ] ∪ ( 23 , + ∞ ] (11,12]\cup(12,22]\cup(22,23]\cup(23,+\infty](11,12]∪(12,22]∪(22,23]∪(23,+∞]

上述select不僅僅獲取了12,22,23的共享行鎖(record-lock),還把間隙加了間隙鎖,其實就是給間隙加上共享鎖或者排他鎖,由于我們這里是select,所以是給間隙加上了共享鎖(我們select id>11還是可以的,不能update、insert、delete id>11的數據)

也就是說,我們可以在id小于11的地方update/delete,加排它鎖。但是操作了id<=11的部分,不影響相同的select * from stu where id>11所獲取的數據量,這樣就能防止幻讀發(fā)生

串行化隔離級別通過給select的部分加間隙鎖,防止其他事務在加了間隙鎖的區(qū)間進行增加或刪除數據,就能防止幻讀

場景2:用可重復的age(有索引)測試間隙鎖

測試輔助索引樹上,間隙鎖的范圍

我們先查看一下表結構、表數據,然后回滾

開啟事務進行測試

很明顯,由于age>20的區(qū)間都被事務1加上了間隙鎖(這里加的是共享鎖),所以事務2插入age=22和age=21都失敗了

幻讀就是同一事務兩次用相同的條件查詢數據,下一次查出的數據量和上一次的數據量不一樣,就算事務1把age=20的數據插入表,事務2再用age>20查詢,得到的數據量也不會改變。

那事務1插入age=20的數據能否成功呢?

依然不能成功,這是因為我們插入的數據id是自增的,所以這條數據(age=20,id=24),位于輔助索引樹中(age=20,id=12)的右邊,由于(age=20,id=12)右邊都被上了鎖,(age=20,id=24)自然無法插入

也就是說,如果我們指定age=20,id合法且<12,則可插入

很顯然,事務1插入的age=18和age=19都不在事務2上鎖的范圍,所以可以插入

如果只是在輔助索引樹上查找,不回表,那么主鍵索引樹上不會加鎖

select id from stu where age>14后,輔助索引樹加鎖區(qū)間如下:

場景3:實際情況需要具體分析用的到底是行鎖還是表鎖

回滾,重新開啟事務

開始測試

我們發(fā)現事務1無論是插入age>18范圍內的數據,還是范圍外的數據,都無法成功

這時我們就要分析了,這應該沒有用到索引,因為我們用索引,過濾出的數據占了整張表的一大半,MySQL server沒使用索引。

沒有加行鎖,只能加表鎖(這時加的是共享鎖),所以事務1無論插入什么數據都不行

果然,沒有用到索引

age>20用到了索引,所以可以用行鎖

三、測試等值間隙鎖

查看表結構和表數據

設置成手動提交,設置串行化隔離級別?;貪L,然后啟動事務

測試不能重復的主鍵索引
此時事務2 select,由于是等值查詢,相當于給這條數據加上了共享鎖

事務1現在插入新的數據是可以成功的,因為主鍵id不能重復,我們不能再插入主鍵id=9的數據

在這種情況下,由于id=9的數據已經存在,主鍵和唯一鍵是不能重復的,事務2進行等值查詢時,事務1插入一個新的數據,不用擔心這條新插入的數據和查詢條件是一樣的,如果主鍵一樣,SQL語句執(zhí)行失敗,所以肯定能成功

測試能重復的輔助索引
回滾并重啟事務

事務2等值查詢,給age=18這行數據加上共享鎖(record-lock)

事務1插入age=18,這是不能允許的,否則事務2再查詢age=18就有兩條記錄了(幻讀)

奇怪的是,我們插入age=17、16、15都被阻塞了,而14、13成功了

這是因為,為了防止幻讀,除了age=18這條數據加了共享鎖,其兩側也被加上了間隙鎖,因為在這種情況下,插入(age=18,id=10)和(age=18,id=8)是會發(fā)生幻讀的,所以在一切會影響select * from user where age=18查詢結果的地方都加上了間隙鎖,但這也會導致一些本不影響查詢結果的語句也執(zhí)行失敗,比如插入(age=17,id=24)雖然不影響上述SQL執(zhí)行結果,由于在間隙鎖范圍內,依然無法插入

如果插入(age=15,id=1)就可以成功,根據輔助索引值相同,按照主鍵值升序排列,(age=15,id=1)應該放在(age=15,id=23)前面,不在間隙鎖范圍內

間隙鎖是給不存在的數據記錄的范圍加鎖:

對于輔助索引,若值允許重復,在串行隔離級別中如果進行等值查詢,InnoDB會給數據加上record-lock和gap-lock(防止別的事務插入索引值重復的數據,造成幻讀)對于主鍵索引,或者唯一鍵索引,值不允許重復,那只需要加行鎖就夠了,不需要再加間隙鎖(對于唯一鍵索引,不可能發(fā)生插入索引值重復的數據)

串行化隔離級別通過排它鎖和共享鎖解決臟讀、不可重復讀(兩次查詢的數據內容不同),通過間隙鎖解決幻讀(兩次查詢的數據量不同)

到此這篇關于MySQL間隙鎖解決幻讀問題的文章就介紹到這了,更多相關MySQL間隙鎖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL主鍵批量修改的坑與解決方案

    MySQL主鍵批量修改的坑與解決方案

    在日常開發(fā)中,我們可能會遇到需要批量修改 MySQL 數據表主鍵的情況,乍一看,修改主鍵 ID 似乎是一個簡單的操作,但如果處理不當,會導致操作失敗甚至數據丟失,本文將詳細剖析問題成因,并總結多種安全高效的解決方案,需要的朋友可以參考下
    2024-12-12
  • Mysql覆蓋索引和前綴索引的實戰(zhàn)

    Mysql覆蓋索引和前綴索引的實戰(zhàn)

    SQL是優(yōu)化數據庫的一個重要手段,本文主要介紹了Mysql覆蓋索引和前綴索引的實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-07-07
  • Mysql不同服務器跨庫查詢解決方案

    Mysql不同服務器跨庫查詢解決方案

    本文主要介紹了Mysql不同服務器跨庫查詢解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • MYSQL突破secure_file_priv寫shell問題

    MYSQL突破secure_file_priv寫shell問題

    這篇文章主要介紹了MYSQL突破secure_file_priv寫shell問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • MySQL 5.7 zip版本(zip版)安裝配置步驟詳解

    MySQL 5.7 zip版本(zip版)安裝配置步驟詳解

    這篇文章主要介紹了MySQL 5.7 zip版本(zip版)安裝配置步驟詳解,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • Mysql優(yōu)化調優(yōu)中兩個重要參數table_cache和key_buffer

    Mysql優(yōu)化調優(yōu)中兩個重要參數table_cache和key_buffer

    這篇文章主要介紹了Mysql優(yōu)化調優(yōu)中兩個重要參數table_cache和key_buffer,需要的朋友可以參考下
    2014-12-12
  • 淺談MySQL表空間回收的正確姿勢

    淺談MySQL表空間回收的正確姿勢

    隨著時間的推移,表里面的數據越來越多,表數據文件越來越大,數據庫占用的空間自然也逐漸增長,本文主要介紹了MySQL表空間回收,感興趣的可以了解一下
    2021-09-09
  • MySQL安全配置向導mysql_secure_installation詳解

    MySQL安全配置向導mysql_secure_installation詳解

    這篇文章主要介紹了MySQL安全配置向導mysql_secure_installation各項配置的含義,并依據經驗給予一了一些建議,需要的朋友可以參考下
    2014-03-03
  • 配置hive元數據到Mysql中的全過程記錄

    配置hive元數據到Mysql中的全過程記錄

    這篇文章主要給的大家介紹了關于配置hive元數據到Mysql中的全過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • 詳細分析mysql視圖的原理及使用方法

    詳細分析mysql視圖的原理及使用方法

    這篇文章主要介紹了mysql視圖的相關資料,幫助大家更好的理解和學習MySQL,感興趣的朋友可以了解下
    2020-08-08

最新評論