MySQL之InnoDB中的鎖用法
1、背景
為了滿足數據庫對數據的一致性、事務隔離性、高并發(fā)性能需求,就有了鎖機制,InnoDB的鎖機制是實現事務隔離性和并發(fā)控制的核心組件,接下來就來講一下鎖機制相關知識。
2、事務并發(fā)問題的三種場景
【1】讀讀場景
并發(fā)讀不會有啥問題,這種場景不會對數據有啥影響。
【2】寫寫場景
并發(fā)寫會產生臟寫,也就是一個事務會修改另一個未提交事務修改過的結果,所以需要鎖來進行并發(fā)控制,鎖的結構如下:
其字段含義為:
字段 | 含義 |
---|---|
事務信息 | 代表這個鎖結構屬于哪個事務 |
is_waiting | false-成功獲取到鎖,可以修改數據;true-需要等待鎖釋放 |
【3】讀寫或寫讀場景
這種場景會帶來臟讀、幻讀、不可重復讀問題,不同隔離級別可能帶來的問題如下:
隔離級別 | 可能帶來的問題 |
---|---|
READ UNCOMMITTED | 臟讀、不可重復讀、幻讀 |
READ COMMIT | 不可重復讀、幻讀 |
REPEATABLE READ | 幻讀 |
SERIALIZABLE | 無問題 |
為了解決臟讀、幻讀、不可重復讀的問題有兩種方案:
- 方案一:讀操作使用MVCC,寫操作加鎖。
- 方案二:讀、寫操作都加鎖。
3、一致性讀
事務利用MVCC進行的讀取操作稱為一致性讀,所有普通的SELECT語句在讀已提交、可重復讀的隔離級別下都算是一致性讀,一致性讀不會對記錄做加鎖操作,其它事務可以修改記錄。
4、鎖定讀
【1】共享鎖和獨占鎖
在使用加鎖方式解決并發(fā)問題時,要保證讀讀操作不受影響,寫寫、讀寫、寫讀操作相互阻塞,所以將鎖分為了兩類,共享鎖和獨占鎖,其含義為:
名稱 | 含義 |
---|---|
共享鎖 | 簡稱S鎖,事務讀取一條記錄時,需要先獲取該記錄的鎖 |
獨占鎖 | 也叫排他鎖,簡稱X鎖,在事務改動一條記錄時,需要先獲取該記錄的X鎖 |
【2】鎖定讀的兩種語句
對讀取的記錄加s鎖:
SELECT … LOCK IN SHARE MODE;
對讀取的記錄加x鎖:
SELECT … FOR UPDATE;
5、寫操作
DELETE:
對一條記錄做DELETE操作的過程是先獲取該記錄在B+樹中的位置,然后獲取這條記錄的x鎖,再執(zhí)行delete mark操作。我們可以把在B+樹中找這條記錄的過程看成一個獲取x鎖的鎖定讀。
UPDATE:
1、如果未修改該記錄的鍵值并且被更新的列占用的存儲空間在修改前后未發(fā)生變化,就先在B+樹中定位這條記錄的位置,然后再獲取一下記錄的x鎖,最后在原位置進行修改操作??梢园堰@個在B+樹中定位修改記錄的過程看出有個獲取x鎖的鎖定讀。
2、如果未修改該記錄的鍵值并且至少有一個被更新的列占用的存儲空間在修改前后發(fā)生了變化,就先在B+樹中獲取這條記錄的位置,然后獲取這條記錄的x鎖,將該記錄徹底刪掉也就是移入垃圾鏈表,最后再插入一條新記錄,這個在B+樹中找到要刪除的記錄的過程可以看成一個獲取x鎖的鎖定讀,新插入的記錄由INSERT操作提供的隱式鎖進行保護。
3、如果修改了該記錄的鍵值,相當于在原記錄上做DELETE操作再來一次INSERT操作,加鎖規(guī)則就按照DELETE和INSERT的規(guī)則進行。
INSERT:
通過隱式鎖來保護插入的這條記錄不被其它事務訪問。
6、InnoDB中的表級鎖
【1】表級別的S鎖、X鎖
在對某個表執(zhí)行SELECT、INSERT、DELETE、UPDATE語句時,InnoDB存儲引擎是不會為這個表添加表級別的s鎖或x鎖的。
對某個表執(zhí)行ALTER TABLE、DROP TABLE這類DDL語句時和SELECT、INSERT、DELETE、UPDATE語句是相互阻塞的,這個阻塞是通過server層中的元數據鎖(簡稱MDL)來實現的。
【2】表級別的IS鎖、IX鎖
IS鎖和IX鎖的含義如下:
名稱 | 含義 |
---|---|
IS鎖 | 意向共享鎖,當事務準備在某條記錄上加S鎖時,需先在表級別加一個IS鎖 |
IX鎖 | 意向獨占鎖,當事務準備在某條記錄上加X鎖時,需先在表級別加一個IX鎖 |
【3】表級別的AUTO-INC鎖
主鍵自增id,也就是帶AUTO_INCREMENT屬性的列就使用AUTO-INC鎖。
7、InnoDB中的行級鎖
【1】LOCK_REC_NOT_GAP行鎖類型
這個類型鎖分為s鎖和x鎖,和我們前面講的共享鎖和獨占鎖一樣。
【2】LOCK_GAP行鎖類型
這個類型的鎖會阻塞當前加鎖的這條記錄和上一條記錄之間的間隙插入。
【3】LOCK_ORDINARY行鎖類型
這個類型的鎖會保護當前被鎖住的記錄,并且阻塞這條記錄和上一條記錄的間隙插入。
【4】Insert Intention Locks行鎖類型
被間隙阻塞插入的記錄就會有有這樣一個類型的鎖結構。
【5】隱式鎖
保護事務插入時的并發(fā)問題。
8、總結
InnoDB鎖機制的背景是在保護事務隔離性的前提下最大化并發(fā)性,通過MVCC、行鎖、表鎖的協同,滿足高并發(fā)場景需求。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
MySQL的Replace into 與Insert into on duplicate key update真正的不同
今天聽同事介紹oracle到mysql的數據migration,他用了Insert into ..... on duplicate key update ...,我當時就想怎么不用Replace呢,于是回來就仔細查了下,它們果然還是有區(qū)別的2014-02-02MySQL索引查詢limit?offset及排序order?by用法
這篇文章主要介紹了MySQL限制數據返回條數limit?offset及排序order?by用法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05使用Mysql5.x以上版本出現報錯#1929 Incorrect datetime value: '''''''' f
我的MySQL安裝后,保存刪除表數據總是出現#1929 Incorrect datetime value: '' for column 'createtime' 的報錯提醒,導致不能刪除表里數據。下面小編給大家分析原因及解決辦法,需要的朋友可以參考下2017-01-01