<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 22, comments - 32, trackbacks - 0, articles - 73
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    InnoDB的鎖的機制探究

    Posted on 2021-07-12 15:38 為自己代言 閱讀(115) 評論(0)  編輯  收藏 所屬分類: 數據庫

    InnoDB的鎖

    InnoDB的行鎖:共享鎖、排他鎖、MDL鎖

    共享鎖:又稱讀鎖、S鎖。一個事務獲取一個數據行的共享鎖,其他事務能獲取該行對應的共享鎖,但不能獲得排他鎖;即一個事務在讀取一個數據行時,其他事務也可以讀,但不能對數據進行增刪改查。

    應用:

    1.自動提交模式下的select查詢,不加任何鎖,直接返回查詢結果

    2.通過select……lock in share mode在被讀取的行記錄或范圍上加一個讀鎖,其他事務可以讀,但是申請加寫鎖會被阻塞

    排他鎖:又稱寫鎖、X鎖。一個事務獲取了一個數據行的寫鎖,其他事務就不能再獲取該行的其他鎖,寫鎖優先級最高。

    應用:

    1.一些DML操作會對行記錄加寫鎖

    2.select for update會對讀取的行記錄上加一個寫鎖,其他任何事務都不能對鎖定的行加任何鎖,否則會被阻塞

    MDL鎖:MySQL5.5引入,用于保證表中元數據的信息。在會話A中,表開啟了查詢事務后,會自動獲得一個MDL鎖,會話B就不能執行任何DDL語句的操作

    行鎖實現方式

    InnoDB 行鎖是通過給索引上的索引項加鎖來實現的,這一點 MySQL 與 Oracle 不同,后者是 通過在數據塊中對相應數據行加鎖來實現的。InnoDB 這種行鎖實現特點意味著:只有通過 索引條件檢索數據,InnoDB 才使用行級鎖,否則,InnoDB 將使用表鎖! 在實際應用中,要特別注意 InnoDB 行鎖的這一特性,不然的話,可能導致大量的鎖沖突, 從而影響并發性能。

    行鎖的三種算法

    InnoDB 存儲引擎有三種行鎖的算法,其分別是:

    • Record Lock: 單個行記錄上的鎖
    • Gap Lock: 間隙鎖,鎖定一個范圍,但不包含記錄本身
    • Next-Key 鎖: Gap Lock + Record Lock,鎖定一個范圍,并且會鎖定記錄本身

    RC模式下只采用Record Lock,RR模式下采用了Next-Key

    加鎖場景分析

    • 主鍵索引

    如果我們加鎖的行上存在主鍵索引,那么就會在這個主鍵索引上添加一個 Record Lock。

    • 輔助索引

    如果我們加鎖的行上存在輔助索引,那么我們就會在這行的輔助索引上添加 Next-Key Lock,并在這行之后的輔助索引上添加一個 Gap Lock

    輔助索引上的 Next-Key Lock 和 Gap Lock 都是針對 Repeatable Read 隔離模式存在的,這兩種鎖都是為了防止幻讀現象的發生。

    • 唯一的輔助索引

    這里有一個特殊情況,如果輔助索引是唯一索引的話,MySQL 會將 Next-Key Lock 降級為 Record Lock,只會鎖定當前記錄的輔助索引。

    如果唯一索引由多個列組成的,而我們只鎖定其中一個列的話,那么此時并不會進行鎖降級,還會添加 Next-Key Lock 和 Gap Lock。

    • Insert 語句

    在 InnoDB 存儲引擎中,對于 Insert 的操作,其會檢查插入記錄的下一條記錄是否被鎖定,若已經被鎖定,則不允許查詢。

    意向鎖

    意向鎖可以分為意向共享鎖(Intention Shared Lock, IS)和意向排他鎖(Intention eXclusive Lock, IX)。但它的鎖定方式和共享鎖和排他鎖并不相同,意向鎖上鎖只是表示一種“意向”,并不會真的將對象鎖住,讓其他事物無法修改或訪問。例如事物T1想要修改表test中的行r1,它會上兩個鎖:

    1. 在表test上意向排他鎖
    2. 在行r1上排他鎖

    事物T1在test表上上了意向排他鎖,并不代表其他事物無法訪問test了,它上的鎖只是表明一種意向,它將會在db中的test表中的某幾行記錄上上一個排他鎖。


    意向共享鎖 意向排他鎖 共享鎖 排他鎖
    意向共享鎖 兼容 兼容 兼容 不兼容
    意向排他鎖 兼容 兼容 不兼容 不兼容
    共享鎖 兼容 不兼容 兼容 不兼容
    排他鎖 不兼容 不兼容 不兼容 不兼容

    一致性非鎖定讀

    一致性非鎖定讀是指 InnoDB 存儲引擎通過行多版本控制(multi version)的方式來讀取當前執行時間數據庫中行的數據。具體來說就是如果一個事務讀取的行正在被鎖定,那么它就會去讀取這行數據之前的快照數據,而不會等待這行數據上的鎖釋放。這個讀取流程如圖1所示:

    圖1

    行的快照數據是通過undo段來實現的,而undo段用來回滾事務,所以快照數據本身沒有額外的開銷。此外,讀取快照數據時不需要上鎖的,因為沒有事務會對快照數據進行更改。

    MySQL 中并不是每種隔離級別都采用非一致性非鎖定讀的讀取模式,而且就算是采用了一致性非鎖定讀,不同隔離級別的表現也不相同。在 READ COMMITTED 和 REPEATABLE READ 這兩種隔離級別下,InnoDB存儲引擎都使用一致性非鎖定讀。但是對于快照數據,READ COMMITTED 隔離模式中的事務讀取的是當前行最新的快照數據,而 REPEATABLE READ 隔離模式中的事務讀取的是事務開始時的行數據版本。

    一致性鎖定讀

    在 InnoDB 存儲引擎中,select語句默認采取的是一致性非鎖定讀的情況,但是有時候我們也有需求需要對某一行記錄進行鎖定再來讀取,這就是一致性鎖定讀。

    InnoDB 對于select語句支持以下兩種鎖定讀:

    • select ... for update
    • select ... lock in share mode

    select ... for update會對讀取的記錄加一個X鎖,其他事務不能夠再來為這些記錄加鎖。select ... lock in share mode會對讀取的記錄加一個S鎖,其它事務能夠再為這些記錄加一個S鎖,但不能加X鎖。

    對于一致性非鎖定讀,即使行記錄上加了X鎖,它也是能夠讀取的,因為它讀取的是行記錄的快照數據,并沒有讀取行記錄本身。

    select ... for updateselect ... lock in share mode這兩個語句必須在一個事務中,當事務提交了,鎖也就釋放了。因此在使用這兩條語句之前必須先執行begin, start transaction,或者執行set autocommit = 0。

    InnoDB 在不同隔離級別下的一致性讀及鎖的差異

    consisten read //一致性讀
    share locks //共享鎖
    Exclusive locks //排他鎖
    


    讀未提交 讀已提交 可重復讀 串行化
    SQL 條件



    select 相等 None locks Consisten read/None lock Consisten read/None lock Share locks

    范圍 None locks Consisten read/None lock Consisten read/None lock Share Next-Key
    update 相等 Exclusive locks Exclusive locks Exclusive locks Exclusive locks

    范圍 Exclusive next-key Exclusive next-key Exclusive next-key Exclusive next-key
    Insert N/A Exclusive locks Exclusive locks Exclusive locks Exclusive locks
    Replace 無鍵沖突 Exclusive locks Exclusive locks Exclusive locks Exclusive locks

    鍵沖突 Exclusive next-key Exclusive next-key Exclusive next-key Exclusive next-key
    delete 相等 Exclusive locks Exclusive locks Exclusive locks Exclusive locks

    范圍 Exclusive next-key Exclusive next-key Exclusive next-key Exclusive next-key
    Select … from … Lock in share mode 相等 Share locks Share locks Share locks Share locks

    范圍 Share locks Share locks Exclusive next-key Exclusive next-key
    Select * from … For update 相等 Exclusive locks Exclusive locks Exclusive locks Exclusive locks

    范圍 Exclusive locks Exclusive locks Exclusive next-key Exclusive next-key
    Insert into … Select … innodb_locks_ unsafe_for_bi nlog=off Share Next-Key Share Next-Key Share Next-Key Share Next-Key
    (指源表鎖) innodb_locks_ unsafe_for_bi nlog=on None locks Consisten read/None lock Consisten read/None lock Share Next-Key
    create table … Select … innodb_locks_ unsafe_for_bi nlog=off Share Next-Key Share Next-Key Share Next-Key Share Next-Key
    (指源表鎖) innodb_locks_ unsafe_for_bi nlog=on None locks Consisten read/None lock Consisten read/None lock Share Next-Key
    在了解 InnoDB 鎖特性后,用戶可以通過設計和 SQL 調整等措施減少鎖沖突和死鎖,包括:
    • 盡量使用較低的隔離級別;
    • 精心設計索引,并盡量使用索引訪問數據,使加鎖更精確,從而減少鎖沖突的機會;
    • 選擇合理的事務大小, 小事務發生鎖沖突的幾率也更小;
    • 給記錄集顯示加鎖時,最好一次性請求足夠級別的鎖。比如要修改數據的話,最好直接申請排他鎖,而不是先申請共享鎖,修改時再請求排他鎖,這樣容易產生死鎖;
    • 不同的程序訪問一組表時,應盡量約定以相同的順序訪問各表,對一個表而言,盡可能以固定的順序存取表中的行。這樣可以大大減少死鎖的機會;
    • 盡量用相等條件訪問數據,這樣可以避免間隙鎖對并發插入的影響;
    • 不要申請超過實際需要的鎖級別;除非必須,查詢時不要顯示加鎖;
    • 對于一些特定的事務,可以使用表鎖來提高處理速度或減少死鎖的可能。

    參考資料

    1.https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-intention-locks  mysql官網開發手冊

    2.《MySQL 技術內幕 – InnoDB 存儲引擎》

    3.《深入淺出MySQL》

    4.https://www.modb.pro/db/33873



    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 久久亚洲精品中文字幕三区| 亚洲а∨精品天堂在线| 国产成人免费爽爽爽视频 | 免费中文字幕在线| 最近免费字幕中文大全| 亚洲乱码日产精品BD在线观看| 四虎永久免费影院| 桃子视频在线观看高清免费视频| 亚洲中文字幕无码爆乳| 国产亚洲精品美女久久久| 毛片免费观看网址| 免费看成人AA片无码视频吃奶| 亚洲性线免费观看视频成熟| 久久久久亚洲AV无码专区网站| 手机看黄av免费网址| 一区二区三区免费精品视频| 亚洲av永久综合在线观看尤物| 亚洲伊人色欲综合网| 永久免费观看的毛片的网站| 久久中文字幕免费视频| 日本激情猛烈在线看免费观看 | 亚洲Aⅴ无码专区在线观看q| 国产高清免费的视频| 中文字幕免费视频| 精品国产呦系列在线观看免费 | 在线观看人成视频免费无遮挡| 亚洲精品无码高潮喷水A片软| 亚洲AV成人片色在线观看高潮| 亚洲第一成人影院| 黄a大片av永久免费| 亚洲精品视频在线观看免费| 黄桃AV无码免费一区二区三区| 久久亚洲精品无码gv| 日本视频一区在线观看免费| 97无码人妻福利免费公开在线视频| 亚洲精品色在线网站| 亚洲日韩精品无码专区加勒比| 亚洲欧洲国产成人精品| 中文字幕在线观看亚洲日韩| 久久亚洲精品AB无码播放| 亚洲无码黄色网址|