MySQL 的鎖按照範圍能夠分爲全局鎖、表鎖、行鎖,其中行鎖是由數據庫引擎實現的,並非全部的引擎都提供行鎖,MyISAM 就不支持行鎖,因此文章介紹行鎖會以InnoDB引擎爲例來介紹行鎖。html
MySQL 提供全局鎖來對整個數據庫實例加鎖。mysql
語法:sql
FLUSH TABLES WITH READ LOCK
這條語句通常都是用來備份的,當執行這條語句後,數據庫全部打開的表都會被關閉,而且使用全局讀鎖鎖定數據庫的全部表,同時,其餘線程的更新語句(增刪改),數據定義語句(建表,修改表結構)和更新類的事務提交都會被阻塞。數據庫
在mysql 8.0 之後,對於備份,mysql能夠直接使用備份鎖。安全
語句:session
LOCK INSTANCE FOR BACKUP UNLOCK INSTANCE
這個鎖的做用範圍更廣,這個鎖會阻止文件的建立,重命名,刪除,包括 REPAIR TABLE TRUNCATE TABLE, OPTIMIZE TABLE
操做以及帳戶的管理都會被阻塞。固然這些操做對於內存臨時表來講是能夠執行的,爲何內存表不受這些限制呢?由於內存表不須要備份,因此也就不必知足這些條件。多線程
Mysql的表級別鎖分爲兩類,一類是元數據鎖(Metadata Lock,MDL),一種是表鎖。線程
元數據鎖(MDL) 不須要顯式使用,在訪問一個表的時候會被自動加上。這個特性須要MySQL5.5版本以上纔會支持,當對一個表作增刪改查的時候,該表會被加MDL讀鎖;當對錶作結構變動的時候,加MDL寫鎖。MDL鎖有一些規則:code
因此咱們在操做數據庫表結構時候必需要注意不要使用長事務,這裏具體是什麼意思呢?我舉個例子說明下:htm
,它主要的目的就是表示將要鎖定表中的行或者正在鎖定表中的行。
意向鎖根據和行鎖的組合能夠分爲:
意向排他鎖:代表將要在表中的某些行獲取排他鎖
意向共享鎖:代表將要在表中的某些行獲取共享鎖
意向鎖的獲取必須在行鎖獲取以前,也就是說獲取共享鎖以前必須先要獲取共享意向鎖,對於排他鎖也是同樣的道理。
那麼這個意向鎖到底有什麼做用呢?
解釋這個以前,咱們先看看意向鎖和行鎖以前的兼容關係:
--- | 排他鎖(X) | 意向排他鎖(IX) | 共享鎖(S) | 意向共享鎖(IS) |
---|---|---|---|---|
排他鎖(X) | 衝突 | 衝突 | 衝突 | 衝突 |
意向排他鎖(IX) | 衝突 | 兼容 | 衝突 | 兼容 |
共享鎖(S) | 衝突 | 衝突 | 兼容 | 兼容 |
意向共享鎖(IS) | 衝突 | 兼容 | 兼容 | 兼容 |
咱們假設有2個事務A和事務B,事務獲取到了共享鎖,鎖住了表中的某一行,這一行只能讀,不能寫,如今事務B要申請整個表的寫鎖。若是事務B申請成功,那麼確定是能夠對錶中全部的行進行寫操做的,那麼確定與A獲取的行鎖衝突。數據庫爲了不這種衝突,就會進行衝突檢測,那麼如何去檢測呢?有兩種方式:
判斷表中的每一行須要遍歷全部記錄,效率太差,因此數據庫就用第一種方式去作衝突檢測,也就是用到了意向鎖。
本文主要從MySQL的加鎖範圍來分析了MySQL的鎖,MySQL根據加鎖範圍能夠分爲全局鎖、表鎖、行鎖。全局鎖和表鎖是MySQL本身實現,行鎖都是由引擎層面去實現。InnoDB下的行鎖主要分爲共享鎖和排他鎖。共享鎖請求後,行只能讀,共享鎖之間不互斥。排他鎖獲取後能更新和刪除行,排他鎖與其餘鎖都互斥。最後我在行鎖的基礎上提到了意向鎖,意向鎖主要表示正在鎖住行或者即將鎖住行,爲了在鎖衝突檢測中提升效率。固然InnoDB下還有其餘鎖,好比間隙鎖,記錄鎖,Next-Key鎖等,這些都不在本文的探討範圍以內,若有興趣的同窗能夠自行研究。
《MySQL實戰45講》