文章目錄
- 1 InnoDB存盤引擎中的鎖
- 1.1 鎖的型別
- 1.1.1 行級鎖
- 1.1.2 意向鎖(表級鎖)
- 1.1.3 鎖型別的總結
- 1.2 查看鎖、事務及阻塞事務
- 1.3 一致性非鎖定讀
- 1.4 一致性鎖定讀
- 2 鎖的演算法
- 2.1 行鎖的3種演算法
- 2.2 解決幻讀問題
- 3 阻塞
- 4 死鎖
- 5 鎖升級
1 InnoDB存盤引擎中的鎖
1.1 鎖的型別
1.1.1 行級鎖
- 共享鎖(S Lock),允許事務讀一行資料
- 排它鎖(X Lock),允許事務洗掉或更新一行資料

1.1.2 意向鎖(表級鎖)
使事務可以在更細粒度上進行加鎖,使多粒度(行鎖和表鎖)的鎖并存,
-
意向共享鎖(IS Lock),事務想要獲得一張表中某幾行的共享鎖
-
意向排他鎖(IX Lock),事務想要獲得一張表中某幾行的排他鎖

1.1.3 鎖型別的總結
- X鎖對任何所不兼容,排他鎖嘛,
- 各意向鎖相互兼容,
- IX鎖對S鎖不兼容,
若將上鎖的物件看成一棵樹,那么對最下層的物件上鎖,也就是對最細粒度的物件進行上鎖,那么首先需要對粗粒度的物件上鎖,

舉個例子,當事務A需要對某行記錄加X鎖,發現該表已被另一個事務B上了S鎖,那么事務A需要對表上IX鎖,但是IX和S鎖不兼容,所以事務A需要等事務B釋放表的S鎖后才能上IX鎖,進而再上行的X鎖,
再舉個例子,當事務A需要對行記錄加S/X鎖,發現該行已被另一個事務B上了IX鎖,那么事務A可以對表上IS/IX鎖,又發現該行被事務B上了行X鎖,這時需要等事務B釋放了行X鎖后,事務A才能對行上S/X鎖,
上行鎖前,會檢查其表鎖情況,檢查兼容性,進而再根據情況選擇上意向鎖還是等待,最后根據行鎖兼容性進行加鎖還是等待,
1.2 查看鎖、事務及阻塞事務
在INFORMATION_ SCHEMA 架構下添加了表INNODB_ TRX、INNODB LOCKS、INNODB_ LOCK_ WAITS,通過這三張表,用戶可以更簡單地監控當前事務并分析可能存在的鎖問題,
1.3 一致性非鎖定讀
指InnoDB通過行多版本控制的方式讀取資料庫中的資料,讀取一個快照資料庫資料,
之所以稱其為非鎖定讀,因為不需要等待訪問的行上X鎖的釋放,
一個行記錄可能不止一個快照資料,稱這種技術為行多版本技術,由此帶來的并發控制,稱之為多版本并發控制(Multi Version Concurrency Control, MVCC),
該實作是通過undo段來完成,而undo用來在事務中回滾資料,因此快照資料本身是沒有額外的開銷,
通常不帶任何鎖陳述句的select,都是一致性非鎖定讀,
不同隔離級別對MVCC的定義不同:
-
在RC級別下,事務中讀取最新的一份快照資料,會被其他事務的提交所影響,
例如,當另一個事務提交事務后,當前事務在另一個事務提交前后兩次查詢資料不一致,即存在不可重復讀現象,
-
在RR級別下,讀取事務開啟前的快照資料,不隨被其他事務影響,
1.4 一致性鎖定讀
即對讀(select)操作加鎖,包括兩種方式:
- select for update,對行加X鎖
- select lock in share mode,對行加S鎖
一致性鎖定讀必須在一個事務中進行,當事務提交或回滾時才釋放,
因此在使用上述兩句SELECT鎖定陳述句時,務必加上
BEGIN, START TRANSACTION或者SET AUTOCOMMIT=0,
2 鎖的演算法
2.1 行鎖的3種演算法
- Record Lock,單行上鎖
- Gap Lock,間隙鎖,鎖定一個范圍
- Next-Key Lock,為Record Lock+Gap Lock,鎖定一個范圍,并且鎖定記錄本身,其設計的目的是為了解決幻讀問題,后面介紹,
**InnoDB在RR級別對于行的查詢都是采用Next-Key Lock鎖定演算法,**而在RC下,僅使用Record Lock,
Next-Key Lock鎖定演算法根據where條件選擇鎖定的是范圍還是單行,
對于二級索引的鎖定讀查詢陳述句,會使用Gap鎖鎖定該索引的當前記錄、上一個范圍和下一個范圍,
如果不鎖定當前where條件索引的行記錄,當另一個事務插入一個相同條件的記錄時,該事務再次通過相同條件查詢出的行記錄數不一致,導致的幻讀現象,
2.2 解決幻讀問題
RR級別下,InnoDB同樣會有幻讀的問題,但是可以采用Next-Key Lock機制來避免幻讀問題;不同于Oracle資料庫,需要在Searializable級別來才能解決幻讀問題,
幻讀問題是指在同一事務下,連續執行兩次同樣的SQL陳述句可能導致不同的結果,第二次的SQL陳述句可能會回傳之前不存在的行,
與不可重復讀不同,不可重復讀的問題,是指兩次SQL陳述句的結果中行記錄數相同,但是欄位值不一致,
InnoDB中RR級別避免幻讀問題的原理:事務中使用一致性鎖定讀的方式,在Next-Key Lock加持下,對范圍行加上Gap Lock的X鎖,保證其他事務無法在該范圍內插入,從而避免幻讀,
如果不使用一致性鎖定讀的方式,依然會存在事務中幻讀的現象,
3 阻塞
InnoDB中,innodb_lock_wait_timeout用來控制等待的時間,默認是50s,innodb_rollback_on_timeout是否對等待超時的事務進行回滾操作,默認是OFF,代表不回滾,
注意,在一個事務中,因為等待另一個事務而導致的阻塞,當阻塞超時時拋出例外,而該事務阻塞前的所有陳述句,默認將被提交,
4 死鎖
死鎖是指兩個或兩個以上的事務在執行程序中,因爭奪鎖資源而造成的-種互相等待的現象,
InnoDB使用wait-for Graph等待圖來進行死鎖檢測,等待圖采用勝讀優先泛實作,InnoDB1.2采用非遞回方式取代遞回實作,進一步提高了InnoDB的性能,
在事務中,包含兩個以上的如下SQL陳述句select for update、update和delete,則可能存在死鎖問題,
5 鎖升級
在Microsoft SQL Server資料庫中,由于鎖是一種稀有的資源,因此鎖升級會帶來一定的效率提高,但是鎖升級帶來的一個問題卻是因為鎖粒度變大而導致并發性能的降低,
InnoDB不存在鎖升級,其不是根據每個記錄來產生行鎖的,其根據每個事務訪問的每個頁對鎖進行管理的,采用的是位圖的方式,
參考
《MySQL技術內幕 InnoDB存盤引擎》第2版 姜承堯
原創文章轉載請注明出處
MySQL中的鎖
作者:壞蛋damn
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/273213.html
標籤:其他
上一篇:專案實戰:Qt+OSG三維點云引擎(支持原點,縮放,單獨軸或者組合多軸拽拖旋轉,支持匯入點云檔案)
下一篇:硬體設計——外圍電路(電源電路)
