<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 的三種鎖

          共 2452字,需瀏覽 5分鐘

           ·

          2020-12-20 15:52

          聽說99%的同學(xué)都來這里充電吖


          正文約:?2200字?

          預(yù)計(jì)閱讀時(shí)間:?6分鐘




          ?1
          前言



          鎖的重要性想必不用多說了吧,作為面試造火箭中最重要的一個(gè)點(diǎn)之一,可謂是不得不會(huì),說出來都是一把辛酸淚,什么悲觀鎖,樂觀鎖,自旋鎖,偏向鎖等等等等,雖然說在我們平常寫代碼的時(shí)候很少會(huì)用到它們,但是實(shí)現(xiàn)的思想是很需要我們?nèi)パ芯康摹?/span>


          之前和大家聊過分布式鎖的實(shí)現(xiàn)方式以及其解決的問題(鎖┃你們要的分布式鎖,moon給你們肝出來了!!)。


          那么今天moon就和大家聊聊mysql中的,讀完這篇文章你將會(huì)學(xué)到:


          什么是全局鎖?

          全局鎖的使用場(chǎng)景?

          表級(jí)鎖有哪些?

          為什么給一個(gè)小表加個(gè)字段,導(dǎo)致整個(gè)庫掛了?

          InnoDB加鎖方法有哪些?

          ...........? ?



          ?2
          正文



          全局鎖


          全局鎖就是說對(duì)整個(gè)數(shù)據(jù)庫實(shí)例進(jìn)行加鎖


          mysql也對(duì)于該行為有具體代碼的調(diào)用:


          flush?tables?with?read?lock(FTWRl)??


          這行命令的意義就是讓數(shù)據(jù)庫變?yōu)?/span>只能讀數(shù)據(jù),不能寫數(shù)據(jù)


          一些表的增刪改語句,建表改表語句,包括更新相關(guān)的事務(wù)提交語句,全部都會(huì)被阻塞。


          說到這里大家可能都明白了,全劇鎖典型的是請(qǐng)我們?cè)谶M(jìn)行全局備份的時(shí)候會(huì)用到,但是使用全局鎖可能會(huì)出現(xiàn)一些問題:

          ●如果使用全局鎖對(duì)主數(shù)據(jù)庫備份,因?yàn)槲覀償?shù)據(jù)庫是讀寫分離的,只有主數(shù)據(jù)庫可以讀數(shù)據(jù),那么就相當(dāng)于在開啟全局鎖的期間,整個(gè)數(shù)據(jù)庫都無法寫數(shù)據(jù)
          ●如果使用全局鎖對(duì)從數(shù)據(jù)庫備份,會(huì)導(dǎo)致備份期間無法同步主數(shù)據(jù)同步過來的binlog數(shù)據(jù),實(shí)際來看就是主庫能讀到新數(shù)據(jù)從庫讀不到。

          所以我們?yōu)榱藴p少全局鎖對(duì)于性能的影響,通常在開啟全局鎖的時(shí)候使用快照的方式將數(shù)據(jù)打下來,創(chuàng)建一個(gè)快照卷后,就釋放全局鎖,之后使用這個(gè)快照卷來完成數(shù)據(jù)庫的備份工作。


          表級(jí)鎖


          表級(jí)別的鎖又分為兩種:


          ●一種是元數(shù)據(jù)鎖(lock tables … read/write),在客戶端斷開連接時(shí)或使用unlock tables 可以釋放鎖。

          ●一種是表鎖(DML),在訪問表的時(shí)候會(huì)自動(dòng)加上,不需要我們手動(dòng)添加。


          在MySQL 5.5版本中引入了MDL,當(dāng)對(duì)一個(gè)表做增刪改查操作的時(shí)候,加MDL讀鎖;當(dāng)要對(duì)表做結(jié)構(gòu)變更操作的時(shí)候,加MDL寫鎖。

          讀寫鎖:


          ●寫鎖被占用時(shí),所有申請(qǐng)讀鎖和寫鎖的進(jìn)線程都會(huì)被阻塞
          ●讀鎖被占用時(shí),申請(qǐng)寫鎖的進(jìn)線程被阻塞,其他申請(qǐng)讀鎖的進(jìn)線程不會(huì)。

          為什么給一個(gè)小表加個(gè)字段,導(dǎo)致整個(gè)庫掛了?


          我們看下下面的圖:



          當(dāng)session a啟動(dòng),會(huì)加一個(gè)MDL讀鎖,由于session b也是讀語句,所以可以和session a 一起執(zhí)行,但是之后的session c 是一個(gè) alter語句,會(huì)修改數(shù)據(jù)庫的表結(jié)構(gòu),所以,會(huì)加一個(gè)MDL寫鎖,我們前面也說了,寫鎖被占用時(shí),所有申請(qǐng)讀鎖和寫鎖的進(jìn)線程都會(huì)被阻塞,所以后面所有的session都會(huì)被阻塞,當(dāng)請(qǐng)求越來越多,資源飽滿,所以整個(gè)庫就可能會(huì)掛掉。


          當(dāng)我們了解清楚原因后,自然就明白了怎么給數(shù)據(jù)庫表安全的加字段了,我們可以考慮先暫停DDL或者kill掉這個(gè)長(zhǎng)事務(wù),去完成表的alter操作。


          行鎖


          MySQL的行鎖是在引擎層由各個(gè)引擎自己實(shí)現(xiàn)的,今天我們就來聊聊innodb的行鎖。


          顧名思義,行鎖就是針對(duì)數(shù)據(jù)表中行記錄的鎖。這很好理解,比如事務(wù)A更新了一行,而這時(shí)候事務(wù)B也要更新同一行,則必須等事務(wù)A的操作完成后才能進(jìn)行更新。


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

          ●共享鎖(S):允許一個(gè)事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。
          ●排他鎖(X):允許獲得排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同數(shù)據(jù)集的共享讀鎖和排他寫鎖。


          InnoDB加鎖方法:


          對(duì)于 UPDATE、 DELETE 和 INSERT 語句,InnoDB
          會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖(X)。

          對(duì)于普通 SELECT 語句,InnoDB 不會(huì)加任何鎖。

          事務(wù)可以通過以下語句顯式給記錄集加共享鎖或排他鎖:

          ●共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。其他 session 仍然可以查詢記錄,并也可以對(duì)該記錄加 share mode 的共享鎖。但是如果當(dāng)前事務(wù)需要對(duì)該記錄進(jìn)行更新操作,則很有可能造成死鎖
          ●排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE。其他 session 可以查詢?cè)撚涗洠遣荒軐?duì)該記錄加共享鎖或排他鎖,而是等待獲得鎖。

          我們上面說了死鎖,那么什么情況下會(huì)造成死鎖呢?

          比如:事務(wù)a在等待事務(wù)b釋放資源,而事務(wù)b也在等待事務(wù)a釋放資源,這樣就會(huì)形成死鎖。

          死鎖的解決方案
          一種策略是,直接進(jìn)入等待,直到超時(shí)
          另一種策略是,發(fā)起死鎖檢測(cè),發(fā)現(xiàn)死鎖后,主動(dòng)回滾死鎖鏈條中的某一個(gè)事務(wù),讓其他事務(wù)得以繼續(xù)執(zhí)行。

          在InnoDB事務(wù)中,行鎖是在需要的時(shí)候才加上的,但并不是不需要了就立刻釋放,而是要等到事務(wù)結(jié)束時(shí)才釋放。這個(gè)就是兩階段鎖協(xié)議。

          當(dāng)然Innodb是既支持表鎖也支持行鎖的,默認(rèn)情況下使用的是行鎖。


          3
          結(jié)語



          看完這篇文章,相信大家對(duì)于mysql的鎖也有了更多的了解,當(dāng)然,這些都只是一個(gè)概念,初步的了解,還有很多深入的內(nèi)容沒有講到,想要更深層次了解的朋友可以下去查閱下相關(guān)書籍。


          學(xué)海無涯,下期見~



          往期推薦



          mysql|聊完了mysql索引,面試官直接給我漲了2000!

          mysql┃一條更新語句是怎么執(zhí)行的???

          mysql┃送命題!!一條查詢語句是怎么執(zhí)行的???

          鎖┃你們要的分布式鎖,moon給你們肝出來了!!!



          END




          關(guān)注moon

          我們一起吊打面試官!

          回復(fù)666 ?免費(fèi)獲得一線大廠面試資料!

          好文!必須在看
          瀏覽 56
          點(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>
                  亚洲日韩视频 | 黄色级级级级级级级级级级级级 | 蜜芽国产精品AV | 欧美成人手机视频 | 黄页网站在线观看视频 |