鎖(locking)的機制是區分資料庫系統和檔案系統的一個關鍵特征。
鎖機制用于管理對共享資源的并發通路。InnoDB存儲引擎會在行級别上對表資料上鎖,這固然不錯。不過InnoDB存儲引擎也會在資料庫内部其他多個地方使用鎖,進而允許對多種不同資源提供并發通路。例如:操作緩沖池中的LRU(Least Recently Used的縮寫,即最近最少使用)清單,删除,添加,移動LRU清單中的元素,為了保證一緻性,必須有鎖的介入。資料庫系統使用鎖是為了對共享資源進行并發通路。保證資料的完整性和一緻性。
一、各資料庫不同或存儲引擎不同,鎖實作也不同
對于MyISAM引擎,其鎖是表鎖設計,并發情況下讀沒有問題,但是并發插入時的性能就要差一些了。
對于Microsoft SQL Server資料庫,在Microsoft SQL Server2005版之前其都是頁鎖的,相對表鎖的MyISAM引擎來說,并發性能有所提升。頁鎖容易實作,然而對于熱點資料頁的并發問題依然不能為例。
到了2005版本,Microsoft SQL Server開始支援樂觀并發和悲觀并發,在樂觀并發下開始支援行級鎖,但是其實作方式與InnoDB存儲引擎的實作方式完全不同。在Microsoft SQL Server下,鎖是一種稀有的資源,鎖越多開銷就越大,是以它會有鎖更新,這種情況下,行鎖會更新到表鎖,這時并發的性能又回到了從前。
Oracle和InnoDB存儲引擎鎖的實作類似,提供一緻性的非鎖定讀、行級鎖支援。行鎖沒有額外相關開銷,并可以同時得到并發性和一緻性。
二、lock 與 latch
在資料庫中,lock與latch都可以被成為“鎖”,但是二者有着截然不同的含義。
latch一般稱為闩(shuan)鎖(輕量級的鎖),因為其要求鎖定的時間必須非常短,若持續的時間長,則應用的性能會非常差。在InnoDB存儲引擎中,latch又可以被分為mutex(互斥鎖)和rwlock(讀寫鎖)。其目的是用來保證并發線程操作臨界資源的正确性,并且通常沒有死鎖檢測的機制。
lock的對象是事務,用來鎖定的是資料庫中的對象,如 表、頁、行。并且一般lock的對象僅在事務commit或rollback後進行釋放(不同僚務隔離界别釋放的時間可能不同)。此外,lock正如大多數資料庫中一樣,是有死鎖機制的。
(
當出現死鎖以後,有兩種政策:
一種政策是,直接進入等待,直到逾時。這個逾時時間可以通過參數 innodb_lock_wait_timeout 來設定。
另一種政策是,發起死鎖檢測,發現死鎖後,主動復原死鎖鍊條中的某一個事務,讓其他事務得以繼續執行。将參數 innodb_deadlock_detect 設定為 on,表示開啟這個邏輯。
)
lock 與latch的對比
lock
latch
對象
事務
線程
保護
資料庫内容
記憶體資料結構
持續時間
整個事務過程
臨界資源
模式
行鎖、表鎖、意向鎖
讀寫鎖,互斥鎖
死鎖
通過waits-for graph、time out等機制進行死鎖檢測與處理
無死鎖檢測與處理機制,僅通過應用程式加鎖的順序(lock leveling)保證無死鎖的情況發生
存在于
lock Manager的哈希表中
每個資料結構的對象中
show engineinnodb mutex; 檢視latch資訊
三、InnoDB引擎中的鎖
3.1 鎖的類型
InnoDB存儲引擎實作了如下兩種标準的行級鎖:
共享鎖(S Lock),允許事務讀一行資料。 select.....lock in share mode
排他鎖(X Lock),允許事務删除或更新一行資料 select .......for update
鎖相容:如果一個事務T1已經獲得了行r的共享鎖,那麼另外的事務T2可以立即執行擷取行r的共享鎖,因為讀取并沒有改變行r的資料。
鎖不相容:但若有其他事務T3想獲得r的排他鎖,則其必須等待事務T1 T2釋放行r上的共享鎖。
排他鎖和共享鎖的相容性
X
S
X
不相容
不相容
S
不相容
相容
可以發現,X鎖與任何的鎖都不相容,而S鎖僅與S鎖相容。
此外,InnoDB存儲引擎支援多粒度(granular)鎖定,這種鎖定允許事務在行級上和表級上的鎖同時存在。為了支援在不同粒度上進行加鎖操作,InnoDB存儲引擎支援一種額外的鎖方式,稱之為意向鎖(Intention Lock)。意向鎖是将鎖定的對象分為多個層次,意向鎖意味着事務希望在更細粒度(fine granularity)上進行加鎖。
若将上鎖的對象堪稱一棵樹,那麼對最下層的對象上鎖,也就是對最細粒度的對象進行上鎖,那麼首先需要對粗粒度的對象上鎖。如下圖:如果需要對頁上的記錄r上X鎖,那麼需要分别對資料庫A、表、頁上意向鎖IX,最後對記錄r上X鎖。若其中任何一個部分導緻等待,那麼該操作需要等待粗粒度鎖的完成。
InnoDB存儲引擎支援意向鎖設計比較簡練,其意向鎖即為表級别的鎖。設計目的的主要是為了在一個事務中揭示下一行将被請求的鎖類型。
1)意向共享鎖(IS Lock),事務想要獲得一張表中某幾行的共享鎖
2)意向排他鎖(IX Lock),事務想要獲得一張表中某幾行的排他鎖
IS
IX
S
X
IS
相容
相容
相容
不相容
IX
相容
相容
不相容
不相容
S
相容
不相容
相容
不相容
X
不相容
不相容
不相容
不相容
檢查MySQL鎖請求狀态 show engine innodb status
information_schema.INNODB_TAX 描述目前事務狀态
information_schema.INNODB_LOCKS 描述目前鎖狀态
information_schema.INNODB_LOCK_WAITS 描述事務和鎖的對應關系
3.3 一緻性鎖定讀
3.4 自增長與鎖
3.5 外鍵和鎖
4.1 行鎖的三種算法
4.2 解決 Phantom Problem (幻讀問題)
5.1 髒讀
5.2 不可重複度
5.3 幻讀
六、阻塞
七、死鎖