<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          mysql的鎖

          共 2622字,需瀏覽 6分鐘

           ·

          2022-03-16 13:44

          作者:小強(qiáng)Zzz

          來(lái)源:SegmentFault  思否社區(qū) 


          前言



          mysql按鎖的范圍分三種


          • 表級(jí)鎖:開(kāi)銷小,加鎖快;不會(huì)出現(xiàn)死鎖,鎖定粒度大,發(fā)生鎖沖突概率最高,并發(fā)度最低。

          • 行級(jí)鎖:開(kāi)銷大,加鎖慢,會(huì)出現(xiàn)死鎖,鎖定粒度小,發(fā)生鎖沖突的概率最低,并發(fā)度最高。

          • 頁(yè)面鎖:開(kāi)銷和加鎖時(shí)間界于表鎖和行鎖之間,會(huì)出現(xiàn)死鎖,鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般。


          從上述三種鎖的特點(diǎn)來(lái)看,很難說(shuō)哪種鎖更好,只能就具體應(yīng)用的特點(diǎn)來(lái)說(shuō)哪種鎖更合適。比如,MyISAM和MEMORY引擎采用的是表級(jí)鎖;InnoDB引擎既支持行級(jí)鎖,也支持表級(jí)鎖,但默認(rèn)情況下采用行級(jí)鎖。


          InnoDB的加鎖模式



          InnoDB實(shí)現(xiàn)了以下兩種類型的行鎖。


          • 共享鎖(S):允許一個(gè)事務(wù)讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)的排他鎖,也叫讀鎖。

          • 排他鎖(X):允許獲得排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同數(shù)據(jù)集的共享鎖與排他鎖,也叫寫(xiě)鎖。


          同時(shí)mysql還支持與行共享鎖和行排他鎖類似的表共享鎖和表排他鎖因?yàn)殒i的粒度不同,表鎖的范圍覆蓋了行鎖的范圍,所以表鎖和行鎖會(huì)產(chǎn)生沖突,例如事務(wù)A對(duì)表中某一行數(shù)據(jù)加了行鎖,然后事務(wù)B想加表鎖,正常來(lái)說(shuō)是應(yīng)該要沖突的。要判斷是否沖突就得遍歷每一行數(shù)據(jù)了,這樣的效率不高,因此我們就有了意向表鎖。


          意向鎖的主要目的是為了使得 行鎖 和 表鎖 共存,事務(wù)在申請(qǐng)行鎖前,必須先申請(qǐng)表的意向鎖,成功后再申請(qǐng)行鎖。


          意向鎖分為意向共享鎖和意向排他鎖。


          • 意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行加行共享鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加共享鎖之前必須先去的該表的意向共享鎖

          • 意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加行排他鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加排他鎖前必須先取得該表的意向排他鎖。


          上述鎖模式的兼容情況如下表所示



          如果一個(gè)事務(wù)請(qǐng)求的鎖模式與當(dāng)前的鎖模式兼容,InnoDB就將請(qǐng)求的鎖授予該事務(wù),反之,如果兩者不兼容,該事務(wù)就要等待鎖釋放。


          意向鎖是表級(jí)鎖,但是卻表示事務(wù)正在讀或?qū)懩骋恍杏涗洠皇钦麄€(gè)表,所以意向鎖之間不會(huì)產(chǎn)生沖突,真正的沖突在加行鎖時(shí)檢查。


          加鎖方法



          意向鎖是InnoDB自動(dòng)加的,不需要用戶干預(yù)。

          隱式上鎖

          對(duì)于UPDATE,DELETE和INSERT語(yǔ)句,InnoDB會(huì)自動(dòng)給設(shè)計(jì)數(shù)據(jù)集加排他鎖;
          對(duì)于普通SELETE語(yǔ)句,INNODB不會(huì)加任何鎖;
          InnoDB會(huì)根據(jù)隔離級(jí)別在需要的時(shí)候自動(dòng)加鎖;


          顯式上鎖


          select * from tableName lock in share mode;//讀鎖
          select * from tableName for update;//寫(xiě)鎖


          解鎖


          • 提交事務(wù)(commit)

          • 回滾事務(wù)(rollback)

          • kill阻塞進(jìn)程


          上讀鎖實(shí)例



          上寫(xiě)鎖實(shí)例



          為什么上了寫(xiě)鎖,別的事務(wù)還可以讀操作?

          因?yàn)镮nnoDB有MVCC機(jī)制(多版本并發(fā)控制),可以使用快照讀,而不會(huì)被阻塞。


          InnoDB行鎖實(shí)現(xiàn)方式



          行鎖(Record Lock)


          行鎖總是會(huì)去鎖住索引記錄,如果InnoDB存儲(chǔ)引擎表建立的時(shí)候沒(méi)有設(shè)置任何一個(gè)索引,這時(shí)InnoDB存儲(chǔ)引擎會(huì)使用隱式的聚簇索引來(lái)進(jìn)行鎖定。

          間隙鎖(Gap Lock)


          當(dāng)我們用范圍條件而不是相等條件檢索數(shù)據(jù),并請(qǐng)求共享或排他鎖時(shí),InnoDB會(huì)給符合條件的已有數(shù)據(jù)記錄的索引項(xiàng)加鎖;對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”,InnoDB也會(huì)對(duì)這個(gè)“間隙”加鎖,這種鎖機(jī)制就是所謂的間隙鎖(Next-Key鎖)。

          優(yōu)點(diǎn):解決了事務(wù)并發(fā)的幻讀問(wèn)題

          不足:因?yàn)閝uery執(zhí)行過(guò)程中通過(guò)范圍查找的話,他會(huì)鎖定爭(zhēng)個(gè)范圍內(nèi)所有的索引鍵值,即使這個(gè)鍵值并不存在。

          間隙鎖有一個(gè)致命的弱點(diǎn),就是當(dāng)鎖定一個(gè)范圍鍵值之后,即使某些不存在的鍵值也會(huì)被無(wú)辜的鎖定,而造成鎖定的時(shí)候無(wú)法插入鎖定鍵值范圍內(nèi)任何數(shù)據(jù)。在某些場(chǎng)景下這可能會(huì)對(duì)性能造成很大的危害。


          Next-key Lock 鎖


          同時(shí)鎖住數(shù)據(jù)+間隙鎖

          在Repeatable Read隔離級(jí)別下,Next-key Lock 是默認(rèn)的行記錄鎖定算法。

          假如teacher表中只有101條記錄,其id值分別是1-101,SQL語(yǔ)句如下


          Select * from teacher where id  〉 100 for update;


          這是一個(gè)范圍條件檢索,InnoDB不僅會(huì)對(duì)符合條件的id值為101的記錄加鎖,也會(huì)對(duì)id大于101(不存在的記錄)的“間隙”加鎖。


          樂(lè)觀鎖與悲觀鎖



          樂(lè)觀鎖(Optimistic Lock):假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性。樂(lè)觀鎖不能解決臟讀的問(wèn)題。


          樂(lè)觀鎖, 顧名思義,就是很樂(lè)觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改,所以不會(huì)上鎖,但是在更新的時(shí)候會(huì)判斷一下在此期間別人有沒(méi)有去更新這個(gè)數(shù)據(jù),可以使用版本號(hào)等機(jī)制。樂(lè)觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫(kù)如果提供類似于write_condition機(jī)制的其實(shí)都是提供的樂(lè)觀鎖。

          悲觀鎖(Pessimistic Lock):假定會(huì)發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作。

          悲觀鎖,就是很悲觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)被阻塞直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)里邊就用到了很多這種鎖機(jī)制,比如行鎖,表鎖等,都是在做操作之前先上鎖。


          總結(jié)



          鎖和多版本數(shù)據(jù)(MVCC)是 InnoDB 實(shí)現(xiàn)一致性讀和四種隔離隔離級(jí)別的手段。


          因此,在不同的隔離級(jí)別下,InnoDB 處理 SQL 時(shí)需要的鎖是不同的。




          點(diǎn)擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開(kāi)更多互動(dòng)和交流,掃描下方”二維碼“或在“公眾號(hào)后臺(tái)回復(fù)“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 39
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  AⅤ在线观看| 国产三级高清视频 | 国产在线视频一区二区三区 | 亚洲AV人人澡人人爽人人乐 | 国产精品1000 |