0.前言
MySQL按照加鎖的範圍,分爲全局鎖、表級鎖、行級鎖。
本文作爲上篇,主要介紹MySQL的全局鎖 和 表級鎖。
重要的實戰總結爲,如何安全地變更一個表的表結構。
1.全局鎖
定義:
全局鎖就是對整個數據庫實例加鎖。
全局鎖語法:
Flush tables with read lock (FTWRL)
當你使用這個命令後,整個庫處於只讀狀態,之後其他線程的數據更新語句(DML)、數據定義語句(DDL)都會被阻塞。
場景:
不支持事務的引擎(如MyISAM),做全庫的邏輯備份。
不過我們一般使用innodb,這個鎖不太會接觸,就不展開詳細介紹了。
2.表級鎖
表級鎖其實有兩種,一種叫表鎖,一種叫原數據鎖(meta data lock, MDL)
2.1 表鎖
表鎖的語法是:
鎖表:
lock tables … read/write
釋放鎖:
unlock tables 主動釋放鎖
表鎖也能夠在客戶端斷開的時候自動釋放。
值得注意的是,lock tables 除了會限制別的線程的讀寫外,當前線程接下來的操作也會被限制。
同樣的,對於innoDB這種支持行鎖的引擎,我們一般也不會去使用用表鎖,因此,這部分內容也只需要簡單瞭解下即可。
2.2 MDL鎖
原數據鎖meta data lock 也是一種表級鎖,在 MySQL 5.5 版本中引入。
當我們對一個表做CRUD操作的時候,會加 MDL 讀鎖;當要對錶做結構變更操作的時候,加 MDL 寫鎖。
讀鎖之間不互斥,所以我們可以有多個線程同時對一張表增刪改查。
讀鎖和寫鎖之間、寫鎖和寫鎖之間是互斥的,用來保證變更表結構操作的安全性。因此,只要有一個線程要對一個表加字段,那天其他線程必須等這個線程完成表結構變更以後才能執行。
看到這裏,不得不給大家舉例一個日常會踩的坑。
對於大表DDL,大家一般比較謹慎,而對於小表,就會比較隨意。但是小表DDL也能造成數據庫崩潰。
Session A第一個啓動,開啓事務,select後沒有立刻commit,模仿一個長事務,此時,session A對錶tt的MDL讀鎖還沒有釋放。
Session B之後執行一個select,由於MDL讀鎖之間不互斥,因此執行成功。
Session C之後想對錶tt 執行一個alter語句,需要獲得MDL寫鎖,但是由於Session A持有了MDL讀鎖,讀寫鎖互斥,因此Session C被阻塞。
Session D這時候也想執行一個select,由於Session C被阻塞,所以Session D也會被阻塞。
所以這個時候,後續的線程就都無法讀寫了。
如果接下來這個表上有頻繁的查詢,而且客戶端有重試機制,那麼超時後會再起一個新的session來查詢,很快數據庫的線程就溢出了。
這裏有幾個小問題需要稍微再解釋一下:
- 從Session A的情況我們得知,事務中 的MDL鎖,在語句開始時申請,但是並不是在語句結束後馬上釋放的,而是在整個事務提交後纔會釋放。
- SessionC(DDL操作)被前面的SessionA和B(查詢操作,獲取MDL 讀鎖)所阻塞,這裏實際上並沒有成功獲取MDL寫鎖,爲什麼Session D的讀操作會被sessionC所阻塞呢?這裏的原因是,MySQL Server端,對於Session C和Session D會有一個隊列來決定誰先執行。
看到這裏,我相信肯定有對MySQL比較熟悉的朋友會問了,MySQL 5.6不是號稱支持Online DDL嗎?怎麼這裏又會有各種阻塞呢?
首先,我們先明確下什麼叫做Online DDL。
Online DDL的過程中,對於鎖的獲取分爲五步(具體online DDL過程比較複雜,本文不展開說明):
1)拿到MDL寫鎖
2)降級成MDL讀鎖
3)真正做DDL
4)升級成MDL寫鎖
5)釋放MDL鎖
1、2、4、5如果沒有鎖衝突,執行時間都是非常短的。絕大部分時間是第三步佔用了,而這個期間,表可用正常讀寫,所以被稱爲Online DDL。
而我們上文的例子,實際上是在第一步就阻塞了。
3.So,如何做一次安全的表結構變更
其實,無論大表小表的表結構變更,都應用引起我們重視。
總結了上文,大家應該都知道了最關鍵的三點:
避免長事務!
避免長事務!
避免長事務!
尤其是在執行表結構變更前,可以在information_schema庫的innodb_trx表中,查看當前執行的事務。如果有長事務正在執行,要延遲等待執行變更,或者手動先kill長事務。
另外,儘量保證表結構變更在數據庫流量低峯期操作,比如夜間,這樣能更好地避免出現風險。
所以,如何做一次安全的表結構變更?
1)避免長事務
2)在流量低峯進行
就是這麼簡單。
下一期,我們就好好聊聊 行鎖,不見不散~
參考:
丁奇《MySQL 實戰45講》
【MySQL系列相關】
看到這裏了,原創不易,點個贊吧,你最好看了~
掃碼關注我的公衆號“阿丸筆記”,第一時間獲取最新更新。同時可以免費獲取海量Java技術棧電子書、各個大廠面試題。