<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 啥時候用表鎖,啥時候用行鎖?

          共 2360字,需瀏覽 5分鐘

           ·

          2022-07-26 01:16

          Hollis的新書限時折扣中,一本深入講解Java基礎(chǔ)的干貨筆記!

          MySQL Innodb 的鎖可以說是執(zhí)行引擎的并發(fā)基礎(chǔ)了,有了鎖才能保證數(shù)據(jù)的一致性。眾所周知,我們都知道 Innodb 有全局鎖、表級鎖、行級鎖三種,但你知道什么時候會用表鎖,什么時候會用行鎖嗎?

          雖然對 MySQL 的知識點挺熟悉的,但一開始看到這個問題,樹哥也是有點懵,我還真沒從這個角度去思考過。大家可以暫時 1 分鐘思考下答案,后面我將帶大家弄清楚這個問題。

          對于這個問題,我只能粗略地想起一些片段,例如:

          1. 對于表級鎖而言,當(dāng)執(zhí)行 DDL 語句去修改表結(jié)構(gòu)時,會使用表級鎖。
          2. 對于行級鎖而言,一般情況下都會默認(rèn)使用行級鎖,貌似是需要有索引匹配到才行。

          上面就是我粗略想到的答案,不知道大家思考的答案是否和我一樣呢?下面就讓我?guī)е蠹襾頊亓?xí)下 MySQL 的鎖吧!

          文章思維導(dǎo)圖

          對于數(shù)據(jù)庫而言,其鎖范圍可以分為:

          • 全局鎖
          • 表級鎖
          • 行級鎖

          全局鎖

          全局鎖就是對整個數(shù)據(jù)庫實例加鎖。 MySQL 提供了一個加全局讀鎖的方法,命令是 Flush tables with read lock (FTWRL)。當(dāng)你需要讓整個庫處于只讀狀態(tài)的時候,可以使用這個命令,之后其他線程的以下語句會被阻塞:數(shù)據(jù)更新語句(數(shù)據(jù)的增刪改)、數(shù)據(jù)定義語句(包括建表、修改表結(jié)構(gòu)等)和更新類事務(wù)的提交語句。你可以理解為,全局鎖基本上把數(shù)據(jù)所所有的變更語句都鎖住了。

          全局鎖的典型場景應(yīng)用場景是全庫邏輯備份,也就是把整個庫每個表都 select 出來存起來。上面說到全局鎖會鎖住所有變更語句,但這只是對于 MyISAM 存儲引擎而言的。對于 Innodb 而言,其可以利用 MVCC 實現(xiàn)數(shù)據(jù)的一致性視圖,從而不需要鎖整個庫就可以實現(xiàn)全庫的數(shù)據(jù)備份。

          表級鎖

          表級鎖可以分為:表鎖、元數(shù)據(jù)鎖、意向鎖三種。

          表鎖

          表鎖,顧名思義就是對某個表加鎖。

          那什么時候會使用表鎖呢?

          一般情況是對應(yīng)的存儲引擎沒有行級鎖(例如:MyIASM),或者是對應(yīng)的 SQL 語句沒有匹配到索引。

          對于第一種情況而言,因為對應(yīng)存儲引擎不支持行鎖,所以只能是使用更粗粒度的鎖來實現(xiàn),這也比較好理解。

          對于第二種情況而言,如果存儲引擎支持行鎖,但對應(yīng)的 SQL 就沒有使用索引,那么此時也是會全表掃描,那此時也是會使用表鎖。例如下面的語句沒有指定查詢列,或者指定了查詢列但是并沒有用到索引,那么也是會直接鎖定整個表。

          // 沒有指定查詢列
          select * from user;
          // 指定查詢列,但是沒有用到索引
          select * from user where name = 'zhangsan';

          上面說的索引,可以說是判斷是否會用行級鎖的關(guān)鍵。但我想到一個問題:如果查詢或更新用到了索引,但是查詢或更新的數(shù)據(jù)特別多,占全表的 80% 甚至更多,這時候是會用表鎖,還是行鎖呢? 這是一個很有意思的問題,感興趣的朋友自行弄個測試表驗證一下,后續(xù)有機會我們再聊聊這個問題。

          元數(shù)據(jù)鎖

          元數(shù)據(jù),指的是我們的表結(jié)構(gòu)這些元數(shù)據(jù)。元數(shù)據(jù)鎖(Metadata Lock)自然是執(zhí)行 DDL 表結(jié)構(gòu)變更語句時,我們對表加上的一個鎖了。

          那什么時候會使用元數(shù)據(jù)鎖這個表級鎖呢?

          當(dāng)我們對一個表做增刪改查操作的時候,會加上 MDL 讀鎖;當(dāng)我們要對表結(jié)構(gòu)做變更時,就會加 MDL 寫鎖。

          意向鎖

          意向鎖,本質(zhì)上就是空間換時間的產(chǎn)物,是為了提高行鎖效率的一個東西。

          在 InnoDB 中,我們對某條記錄進(jìn)行鎖定時,為了提高并發(fā)度,通常都只是鎖定這一行記錄,而不是鎖定整個表。而當(dāng)我們需要為整個表加 X 鎖的時候,我們就需要遍歷整個表的記錄,如果每條記錄都沒有被加鎖,才可以給整個表加 X 鎖。而這個遍歷過程就很費時間,這時候就有了意向鎖的誕生。

          意向鎖其實就是標(biāo)記這個表有沒有被鎖,如果有某條記錄被鎖住了,那么就必須獲取該表的意向鎖。所以當(dāng)我們需要判斷這個表的記錄有沒有被加鎖時,直接判斷意向鎖就可以了,減少了遍歷的時間,提高了效率,是典型的用空間換時間的做法。

          那么什么時候會用到意向鎖呢?

          很簡單,就是在對表中的行記錄加鎖的時候,就會用到意向鎖。

          行級鎖

          千呼萬喚,終于來到了行級鎖。

          要知道的是,行級鎖是存儲引擎級別的鎖,需要存儲引擎支持才有效。目前 MyISAM 存儲引擎不支持行級鎖,而 Innodb 存儲引擎則支持行級鎖。而全局鎖、表級鎖,則是 MySQL 層面就支持的鎖。

          那么什么時候會使用行級鎖呢?

          當(dāng)增刪改查匹配到索引時,Innodb 會使用行級鎖。

          如果沒有匹配不到索引,那么就會直接使用表級鎖。

          總結(jié)

          文章最后,我們回顧一下開頭提出的問題:Innodb 啥時候用表鎖,啥時候用行鎖?

          表級鎖包括:表鎖、元數(shù)據(jù)鎖、意向鎖。

          對于表鎖而言,當(dāng)存儲引擎不支持行級鎖時,使用表鎖。SQL 語句沒有匹配到索引時,使用表鎖。

          對于元數(shù)據(jù)鎖而言,對表做增刪改查時,會加上 MDL 讀鎖。對表結(jié)構(gòu)做變更時,會加上 MDL 寫鎖。

          對于意向鎖而言,對表中的行記錄加鎖時,會用到意向鎖。

          而對于行級鎖而言,增刪改查匹配到索引時,會使用行級鎖。


          我的新書《深入理解Java核心技術(shù)》已經(jīng)上市了,上市后一直蟬聯(lián)京東暢銷榜中,目前正在6折優(yōu)惠中,想要入手的朋友千萬不要錯過哦~長按二維碼即可購買~


          長按掃碼享受6折優(yōu)惠


          往期推薦

          大廠干掉 OOM 的套路,你知道幾個 !


          前 3 名突然變了,揭秘 7 月編程語言最新排行榜


          一個程序員的水平能差到什么程度?




          有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)

          歡迎大家關(guān)注Java之道公眾號


          好文章,我在看??

          瀏覽 83
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  国产一级操逼视频片 | 国模三区 | 操逼图片视频免费看喷水高朝 | 苍井空肏屄乱伦 | 国产女人在线播放 |