Mysql 中的MDL

本文能夠結合 MySQL中的事務原理和鎖機制 查看。html

首先簡單瞭解一下 mysql 的 sql 類型:mysql

一、數據定義語言 DDL:Create、Drop、Alter 操做。用於定義庫和表結構的。sql

二、數據查詢語言 DQL:select。用於查詢數據的。數據庫

三、數據操縱語言 DML:insert、update、delete。對行記錄進行增刪改操做。session

四、數據控制語言 DCL:grant、revoke、commit、rollback。控制數據庫的權限和事務。工具

MDL

MDL(MetaData Lock)就是針對於 DDL 與 DML、DQL 操做加鎖,執行 DDL 自動添加寫鎖,執行 DML、DQL 自動添加讀鎖,也就是說 DML 語句能夠同時執行(不考慮其餘鎖),而 DDL 間則會相互阻塞。優化

爲何在執行 DDL 時會添加寫鎖?

DDL 在執行會先建立一個臨時表,先將表的數據所有移到這個臨時表中,而後再將臨時表替換當前表。在這個過程當中若是出現讀寫操做就會影響最終結果出錯。這個過程耗時主要在將原表的數據移到臨時表的過程。spa

 

執行

不一樣事務的執行是按隊列順序進行的,若是兩個事務所執行的 MDL 添加的分別是讀、寫鎖,那麼就會互斥,後面的事務只有等到前面事務提交釋放鎖後才能執行。htm

例子:假設有四個會話:session一、session二、session三、session4 ,首先先依次開啓事務,而後session1,session2 先執行查詢操做(爲了不多是可串行化級別致使加的寫鎖衝突,因此就使用查詢操做),session1,session2 中的操做能夠正常執行,session3執行 Alter 修改表結構,此時 session3 的操做就會阻塞(由於 MDL 的讀寫鎖衝突),session4 再執行增刪改查也會被阻塞,由於是在隊列中,它位於 session3 後面,因此只有等到 session3 提交後其才能繼續執行。blog

Online DDL

經過上面的分析,進行實踐檢驗,卻出現了下面的狀況:

 

能夠看到執行和顯示順序是圖中標註的從1開始遞增按順序執行的。能夠看到 session4 在 session2 提交後就馬上會執行,而且在 session4 提交後 session3 才能執行成功,這個和前面所說的理論就會衝突。這個緣由是當前 mysql 版本是5.6,而在 mysql 5.6 支持 Online DDL。

Online DDL 是對 MDL 的一種優化,由於若是按照 MDL 的執行邏輯,像上面這種狀況,一旦一些簡單的讀寫操做比某一條 DDL 語句啓動慢一些,就會陷入阻塞,若是 DDL 修改的是大表且是高頻表,那麼在這條語句執行時會阻塞全部的讀寫操做,很容易使數據庫崩潰。而 Online DDL 優化思路就是在獲取到鎖以後先容許一段時間的讀寫操做,直到臨時表的數據轉移完成,再中止其餘讀寫操做,而具體實現就主要分爲下面幾步,

1. 拿MDL寫鎖

2. 降級成MDL讀鎖,接受讀寫操做,讀操做直接正常返回,寫操做會被記錄下來,等待後面更新到臨時表中。

3. 真正作DDL,在 DDL 表記錄向臨時錶轉移完成並執行完記錄的寫操做後開始阻塞讀寫操做。

4. 升級成MDL寫鎖,進行臨時表的替換

5. 釋放MDL鎖

應用於上面的例子就是:

一、session一、session2 由於是隊列的前兩個,先添加MDL讀鎖,正常執行,session3 由於是要添加 MDL 寫鎖因此阻塞,session4 在 session3 後面因此也阻塞,session一、session2執行完成提交釋放讀鎖。

二、session3 在獲取到 MDL 寫鎖後,會先進行降級降級成讀鎖

三、在 session3 降級後 session4 由於是 MDL 讀鎖,因此也會獲取到鎖,執行

四、session3 在完成向臨時表數據遷移以及執行完記錄的寫操做後想升級回寫鎖發現當前的讀鎖還被 session4 佔用,因此會阻塞,等待 session4 執行釋放。

五、session4 提交事務,釋放讀鎖,session3 成功升級鎖,輸出提示語句,最後提交。

注意:

一、若是前面的例子還有一個 session5,而且在一開始和 session4 一塊兒開啓事務、查詢,那麼在 session2 提交後 session5 也會隨着 session4 一塊兒執行,而 session3 則須要等待 session四、session5 提交後才能執行第四步。

  而若是 session5 開啓事務是在 session3 向臨時表數據遷移完成後,那麼 session5 的查詢操做就會被 session3 阻塞,直到 session3 提交事務。

二、Online DDL 整個過程是在 InnoDB 內部執行的,對於 Server 來講並無什麼操做,因此這個操做是 "inplace" 的,也就是說:

  Online 過程必定是 inplace 的,但 inplace 過程不必定是 Online 的。

三、5.6 開始由於支持 Online DDL,因此在向臨時表遷移數據時可能會積攢一些寫操做形成頁分裂,同時在建立新表時每一個數據頁還會留 1/16 的空間用於更新操做,因此執行DDL後的表結構不必定是最 "緊湊" 的。

 

 

MDL 引起的問題

在上線項目中,若是須要對某個大表的字段進行刪除,那麼必然會阻塞該表的全部增刪改查操做,若是該表存儲了熱點數據,那麼就會阻塞大量的操做,最終致使數據庫崩潰。

解決

一、查看當前是否存在長事務,若是存在,先儘快將其提交,防止長事務的MDL寫鎖阻塞
二、爲 DDL 的操做設置過時時間,若是時間內沒有成功執行就取消。可使用 Github 的開源工具 gh-ost。

相關文章
相關標籤/搜索