按照鎖的力度分:
1.行級鎖
2.表級鎖
3.全局鎖
4.頁級鎖
innodb不支持頁鎖
全局鎖
全局鎖指的是對整個數據庫實例加鎖,一般用于數據庫的
表級鎖
表鎖 是對整張表進行加鎖。
表級鎖還有以下幾種:
意向鎖:
意向鎖是指,我們在事務請求表/行的意向鎖的時候,我們會對整個表加上意向鎖。
意向鎖解決了一個問題:
就是我們一個事務對行加上鎖的時候,另一個事務對表加上鎖。這種情況似乎可以發生,但是事務已經對行上鎖了,另外的一個事務也可以訪問并操作該表內的所有行,這就發生沖突了。
意向共享鎖:
多個事務可以同時加上共享鎖,但是不能修改
意向排他鎖:
表級鎖,多個事務可以對該表上面的數據進行修改
AUTO-INC鎖
AUTO-INC 鎖是一種特殊的表級鎖,由插入帶有 AUTO_INCREMENT 列的表的事務獲取。在最簡單的情況下,如果一個事務正在向表中插入值,任何其他事務都必須等待,以便執行它們自己的插入操作,這樣第一個事務插入的行就會接收到連續的主鍵值。
字典鎖
字典鎖,英文名叫做MetaData Lock,也叫做MDL鎖,它是一種用于管理元數據的鎖機制,而不是數據本身的鎖。
MDL鎖用于控制對數據庫對象的元數據的并發訪問,數據庫會在執行DDL(Data Defination Language)操作時加上字典鎖。字典鎖的主要目的是保護數據庫中的元數據對象,如表、列、索引、視圖等,以確保在DDL操作期間,不會出現數據一致性問題和競爭條件。
表級排他&共享鎖
InnoDB中,一般我們會做的就是兩種操作,即DDL和DML。
DML中。我們日常的對數據庫表結構的SELECT、INSERT、UPDATE以及DELETE都不會添加表級別的共享鎖及排他鎖。而是使用默認的并發控制方式——行級鎖。
那除了增刪改查以外,還有一些其他的操作,比如ALTER、DROP等對表機構改變的動作,他們加鎖的過程添加的是MDL鎖,即字典鎖。
所以,**InnoDB中的表級鎖并不是沒用,而是因為他劃分的太細了,意向鎖、AUTO-INC鎖、字典鎖等。而剩下的普通的排他鎖和共享鎖,確認很少才能用得上。**我找了很多資料,也沒有明確的看到具體是啥時候,在《MySQL是怎樣運行的》這本書中提到過一句:比如在崩潰恢復時。
當然,我們可以自己通過SQL語句來添加表級鎖。可以使用 LOCK TABLES
手動添加表級鎖,但這會阻塞其他所有訪問該表的操作,直到執行 UNLOCK TABLES
。
LOCK TABLES還可以分為排他和共享:
LOCK TABLES table READ:這就是添加表級別的共享鎖
LOCK TABLES table WRITE:這就是添加表級別的排他鎖
還有就是,Innodb會在傾向于選擇行級鎖來進行并發控制,但是如果在一些極端情況下, 比如說UPDATE操作需要掃描整個表且對表中許多行進行更新,InnoDB可能會評估行級鎖的成本過高,而采用更粗粒度的鎖定策略,比如表級鎖。然而,這種情況在InnoDB中是非常罕見的,因為InnoDB設計上是傾向于盡可能地使用行級鎖。
擴展知識
update時沒有用到索引,加什么鎖?
相信大家看到過的很多資料中都有過類似的描述“innodb 的 update語句中,如果where條件中沒有索引,就不是行級鎖了,而是鎖表了,就是表級鎖”。
我一直也都有這個印象,最開始是從哪看來的,也無從考究了,確實很長一段時間都是這么認為的。但是我發現并不對。
確實,mysql的行級鎖鎖的是索引,但是當update語句的where條件中沒有用到索引的話,他會做全表掃描,但是也不是全部都鎖定。而是把符合條件的記錄鎖住。
鎖啥呢?鎖主鍵索引。沒有主鍵呢?會自動創建隱式主鍵鎖住。
以上部分知識來源于網絡