一、前言
MYSQL中MDL鎖一直是一個比較讓人比較頭疼的問題,我們談起鎖一般更加傾向于INNODB下層的gap lock、next key lock、row lock等,因為它很好理解,也很好觀察,而對于MDL LOCK卻了解得很少,因為它實在不好觀察,只有出現(xiàn)問題查看show processlist勉強可以看到
簡單的所謂的Waiting for table metadata lock之類的狀態(tài),其實MDL LOCK是MYSQL上層一個非常復(fù)雜的子系統(tǒng),有自己的死鎖檢測機制
(無向圖?)而大家一般口中的是不是鎖表了其實就是指的它,可見的它的關(guān)鍵性和嚴(yán)重性,筆者也是根據(jù)自己的需求學(xué)習(xí)了一些(冰山一角),而沒有能力閱讀全部的代碼,但是筆者通過增加一個TICKET的打印函數(shù)讓語句的MDL LOCK加鎖流程全部打印出來方便學(xué)習(xí)研究,下面從一些基礎(chǔ)說起然后告訴大家修改了哪些東西,最后對每種MDL TYPE進行測試和分析,如果大家對基本概念和增加打印函數(shù)不感興趣可直接參考第五部分加鎖測試,但是如果不了解基礎(chǔ)知識可能看起來有點困難。
剛好最近遇到一次MDL LOCK出現(xiàn)死鎖的情況會在下篇文章中給出案例,這里只看理論
----處于層次:MYSQL SERVER層次,實際上早在open_table函數(shù)中MDL LOCK就開始獲取了,可以說他是最早獲取的LOCK結(jié)構(gòu)
----最早獲取階段: THD::enter_stage: 'Opening tables'
調(diào)用棧幀
| #0 open_table_get_mdl_lock (thd=0x7fffd0000df0, ot_ctx=0x7fffec06fb00, table_list=0x7fffd00067d8, flags=0, mdl_ticket=0x7fffec06f950) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_base.cc:2789#1 0x0000000001516e17 in open_table (thd=0x7fffd0000df0, table_list=0x7fffd00067d8, ot_ctx=0x7fffec06fb00) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_base.cc:3237 |
----死鎖檢測出錯碼:
| { "ER_LOCK_DEADLOCK", 1213, "Deadlock found when trying to get lock; try restarting transaction" },ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction |
MDL LOCK的死鎖拋錯和INNODB死鎖一模一樣不同的只是SHOW ENGINE INNODB 沒有死鎖信息。
----涉及代碼:mdl.h mdl.cc
二、基礎(chǔ)重要的數(shù)據(jù)結(jié)構(gòu)(類)和概念
1、MDL TYPE
MDL_INTENTION_EXCLUSIVE(IX)
MDL_SHARED(S)
MDL_SHARED_HIGH_PRIO(SH)
MDL_SHARED_READ(SR)
MDL_SHARED_WRITE(SW)
MDL_SHARED_WRITE_LOW_PRIO(SWL)
MDL_SHARED_UPGRADABLE(SU)
MDL_SHARED_READ_ONLY(SRO)
MDL_SHARED_NO_WRITE(SNW)
MDL_SHARED_NO_READ_WRITE(SNRW)
MDL_EXCLUSIVE(X)
后面會對每種TYPE進行詳細的測試,最后也會給出源碼中解釋
2、MDL NAMESPACE
在MDL中MDL_KEY按照NAMESPACE+DB+OBJECT_NAME的方式進行表示,所謂的namespace也不叫重要
新聞熱點
疑難解答
圖片精選