一、Mysql鎖概述
1、鎖的分類
Mysql中鎖分爲3類:頁級鎖、表級鎖、行級鎖。
頁級鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。會發生在:BDB存儲引擎。
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。會發生在:MyISAM、memory、InnoDB、BDB等存儲引擎中。
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。會發生在:InnoDB存儲引擎。
存儲引擎 | 頁級鎖 | 表級鎖 | 行級鎖 |
---|---|---|---|
BDB | √ | √ | |
MyISAM | √ | ||
InnoDB | √ | √ |
2、表級鎖
表級鎖有2種類型:表共享讀鎖(Table Read Lock)和表獨佔寫鎖(Table Write Lock)。
鎖模式的兼容性:
- 對MyISAM表的讀操作,不會阻塞其他用戶對同一表的讀請求,但會阻塞對同一表的寫操作;
- 對MyISAM表的寫操作,則會阻塞其他用戶對同一表的讀和寫操作;
3、行級鎖
行級鎖包含2種:共享鎖(S)和排他鎖(X)。
- 共享鎖(s):又稱讀鎖。允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖
- 排他鎖(X):又稱寫鎖。允許獲取排他鎖的事務更新數據,阻止其他事務取得相同的數據集共享讀鎖和排他寫鎖。
二、InnoDB中的鎖
InnoDB中使用的鎖有表鎖和行鎖。
1、表鎖
1)意向鎖
爲了允許行鎖和表鎖共存,實現多粒度鎖機制,InnoDB還有兩種內部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。在加行鎖之前必須先獲得表級意向鎖,否則等待innodb_lock_wait_timeout超時後根據innodb_rollback_on_timeout決定是否回滾事務。
- 意向共享鎖(IS):事務打算給數據行加行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。
- 意向排他鎖(IX):事務打算給數據行加行排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。
InnoDB行鎖模式兼容性如下表:
X | IX | S | IS | |
---|---|---|---|---|
X | ||||
IX | √ | √ | ||
S | √ | √ | ||
IS | √ | √ | √ |
2)、自增鎖
在MySQL InnoDB存儲引擎中,我們在設計表結構的時候,通常會建議添加一列作爲自增主鍵。這裏就會涉及到一個特殊的鎖:自增鎖(即:AUTO-INC lock),它屬於表鎖的一種,在insert結束後立即釋放。我們可以執行show engine innodb status\G來查看自增鎖的狀態信息。
2、行鎖
InnoDB行鎖是通過對索引數據頁上的記錄(record)加鎖實現。所以,只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖。
主要實現算法有3種:
- record lock鎖:單個行記錄的鎖(鎖數據,不鎖Gap)
- gap lock鎖:間隙鎖,鎖定一個範圍,不包括記錄本身(不鎖數據,僅僅鎖數據前面的Gap)
- next-key lock鎖:同時鎖住數據,並且鎖住數據前面的Gap。所以:next-key lock = record lock + gap lock
3、InnoDB中鎖的使用及問題排查
4、InnoDB死鎖以及處理
InnoDB是逐行加鎖,極容易產生死鎖。
1)產生死鎖的的四個條件
- 互斥條件:一個資源每次只能被一個進程使用;
- 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放;
- 不剝奪條件:進程已獲得的資源,在沒使用完之前,不能強行剝奪;
- 循環等待條件:多個進程之間形成一種互相循環等待資源的關係。
在發生死鎖時,InnoDB存儲引擎會自動檢測,並且會自動回滾代價較小的事務來解決死鎖。但很多時候一旦死鎖發生,InnoDB存儲引擎的處理的效率是很低下的或者有時候根本解決不了,需要人爲手動去解決。
2)鎖問題排查
排查InnoDB鎖問題通常可以有2種方法:
- 第一種:打開innodb_lock_monitor表,注意使用後記得關閉,會影響性能。
- 第二種:在MySQL5.5之後,可以通過查看information_schema庫下面的innodb_locks,innodb_lock_waits,innodb_trx 三個視圖
3)避免死鎖的辦法
- 加鎖順序一致
- 儘量基於primary或unique key更新數據
- 單次操作數據量不宜過多,涉及表儘量少
- 減少表上索引,減少鎖定資源
- 相關工具:pt-deadlock-logger
參考文獻
1、https://zhuanlan.zhihu.com/p/76390004
2、https://www.cnblogs.com/leedaily/p/8378779.html
3、https://blog.csdn.net/zcl_love_wx/article/details/81977447
4、https://blog.csdn.net/zcl_love_wx/article/details/81983267