有了MDL鎖視圖,業務死鎖從此一目了然


摘要:MDL鎖視圖讓一線運維人員清晰地查看數據庫各session持有和等待的元數據鎖信息,從而找出數據庫MDL鎖等待的根因,准確地進行下一步決策。

當多用戶共同存取數據時,數據庫中就會產生多個事務同時存取同一數據的情況。若不控制這種並發操作,數據庫的一致性就會被破壞。這種情況下,加鎖是實現數據庫並發控制的關鍵技術。

舉個例子,加鎖后事務就對該數據對象有了一定的控制,在事務釋放鎖之前,其他的事務不能對此數據對象進行更新操作。

MySQL從 5.5版本開始引入MDL鎖(即元數據鎖),MDL鎖主要為了保證元數據的一致性(主要是保證DDL操作與DML操作之間的一致性),用於處理不同線程操作同一元數據對象的同步與互斥問題,在各個業務場景中會十分頻繁地使用到。

具體而言,MySQL引入MDL鎖可以解決如下問題:一是事務隔離問題,比如在可重復讀隔離級別下,會話A在2次查詢期間,會話B對表結構做了修改,2次查詢結果就會不一致,無法滿足可重復讀的要求。二是數據復制問題,比如會話A執行了多條更新語句期間,另外一個會話B做了表結構變更並且先提交,就會導致slave在重做時,先重做alter,再重做update時就會出現復制錯誤的現象。

MDL鎖視圖,一目了然元數據鎖問題

社區版MySQL無法獲取表MDL鎖的詳細信息,當客戶遇到類似“Waiting for metadata lock”的問題而阻塞DML或DDL后,由於無法確定各session之間的關聯,往往無從下手,復雜情況下,只能重啟實例,從而增加解決問題的成本,對業務產生較大影響。

而且在業務場景較復雜的情況下,一旦涉及對數據庫元數據的互斥操作(如DDL、LOCK Table等),此類問題便會頻繁發生,給一線運維和客戶帶來很大的困擾。

針對以上痛點,華為雲數據庫MySQL在充分調研內核的基礎上,推出了MDL鎖視圖特性,可以清晰查看數據庫各session持有和等待的元數據鎖信息,方便現網運維進行問題定位,有效進行系統診斷,幫助客戶更好地優化自身業務。

MDL鎖視圖以系統表的形式呈現,該表位於INFORMATION_SCHEMA,表名:METADATA_LOCK_INFO,表結構如下:

MDL鎖視圖主要由7個字段組成,各字段詳情為:

  • THREAD_ID:session的ID,即會話ID
  • LOCK_STATUS:MDL鎖的狀態,主要分為PENDING和GRANTED兩種,分別表示session正在等待該MDL鎖和session已獲得該MDL鎖
  • LOCK_MODE:加鎖的模式,如MDL_SHARED 、MDL_EXCLUSIVE 、MDL_SHARED_READ、MDL_SHARED_WRITE等
  • LOCK_TYPE:MDL鎖的類型,如Table metadata lock、Schema metadata lock、Global read lock、Tablespace lock等
  • LOCK_DURATION:MDL鎖的范圍,有三種取值:MDL_STATEMENT、MDL_TRANSACTION、MDL_EXPLICIT,分別表示語句級別、事務級別、global級別
  • TABLE_SCHEMA:數據庫名,對於部分global級別的MDL鎖,該值為空
  • TABLE_NAME:表名,對於部分global級別的MDL鎖,該值為空

MDL鎖視圖好在哪?

下面通過兩則案例來對MDL鎖視圖進行進一步的說明。

場景一:長時間未提交事務,阻塞DDL,繼而阻塞所有同表的操作

客戶發現表t2的truncate一直被阻塞后,業務流程中對表t2的select操作也全部被阻塞。DDL被阻塞后,客戶立刻執行show processlist:

但是通過processlist信息,只能看到session 4執行truncate操作時被其他session持有的table metadata lock阻塞,session 5執行select操作時也同樣被阻塞,無法確定哪個session阻塞了session 4和session 5。此時,如果盲目的去kill其他session(2或3)會給線上業務帶來很大風險,因此只能等待其他session釋放該MDL鎖。

而當客戶引入MDL鎖視圖后,執行SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO:

結合show processlist的結果,從元數據鎖視圖中可以明顯看出,session 4 pending在表t2的metadata lock,session 3持有表t2的metadata lock,該MDL鎖為事務級別,只要session 3的事務不提交,session 4便會一直阻塞。因此,客戶只需要在session 3中執行commit或kill session 3,便可以讓業務繼續運行。

場景二:長時間持有MDL鎖,導致全備失敗

客戶實例最近幾次全備均失敗,但是業務表現似乎正常,而且最近系統業務量不高,未出現明顯問題。運維團隊發現全備被阻塞后,立刻show processlist,發現有多個活躍的用戶session:

全備是基於xtrabackup,在執行真正的備份之前需要執行lock tables for backup,但從show processlist中只能看到:lock tables for backup時一直被某個MDL鎖阻塞,全備超時失敗;客戶的多個session業務量很小,都處於sleep狀態,於是客戶繼續執行show open tables where in_use >=1:

發現有個表t1始終處於in use狀態,所以猜測是用戶某個session持有了該表t1的MDL鎖未釋放,導致lock tables for backup等待超時。但是結合show processlist仍然無法確定是哪個session持有表t1的MDL鎖,想讓全備執行成功,只能通知客戶逐一斷連session或者重啟實例。

引入MDL鎖視圖后,客戶執行SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO:

結合show processlist的結果,從元數據鎖視圖中可以明顯看出,session 4 pending在全局backup lock上;session 2持有全局的backup lock,該MDL鎖類型為MDL_EXPLICIT,global級別。因此,客戶只需要在session 2顯式調用unlock tables釋放鎖或者kill session 2即可讓業務繼續運行。

通過以上兩個案例,MDL鎖視圖的重要性不言而喻,它可以讓客戶和一線運維人員清晰地查看數據庫各session持有和等待的元數據鎖信息,從而找出數據庫MDL鎖等待的根因,准確地進行下一步決策,有效降低對業務的影響。

華為雲數據庫MySQL在828企業上雲節期間,還有眾多優惠活動,體驗MDL鎖視圖的最佳時機。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM