MySQL數據庫 鎖機制簡介web
數據庫鎖定機制簡單來講就是數據庫爲了保證數據的一致性而使各類共享資源在被併發訪問訪問變得有序所設計的一種規則。對於任何一種數據庫來講都須要有相應的鎖定機制,因此MySQL天然也不能例外。MySQL數據庫因爲其自身架構的特色,存在多種數據存儲引擎,每種存儲引擎所針對的應用場景特色都不太同樣,爲了知足各自特定應用場景的需求,每種存儲引擎的鎖定機制都是爲各自所面對的特定場景而優化設計,因此各存儲引擎的鎖定機制也有較大區別。數據庫
1、MySQL有三種鎖的級別:頁級、表級、行級。 架構
MyISAM和MEMORY存儲引擎採用的是表級鎖;併發
BDB存儲引擎採用的是頁面鎖,但也支持表級鎖;優化
InnoDB存儲引擎既支持行級鎖,也支持表級鎖,但默認狀況下是採用行級鎖。 spa
MySQL這3種鎖的特性可大體概括以下:線程
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的機率最高,併發度最低。 設計
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。索引
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度通常。事務
2、死鎖
死鎖是指兩個或者兩個以上的事務在執行過程當中,因爭奪資源而形成的一種相互等待的現象。解決死鎖最簡單的一種方式是超時,即當兩個事務相互等待是,當一個等待時間超過設置的某一閥值時,其中一個事務進行回滾,另一個等待的事務就能繼續進行。在InnoDB存儲引擎中,參數innodb_lock_wait_timeout用來設置超時時間。
3、MyISAM表級的讀寫鎖
MySQL的表級鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨佔寫鎖(Table Write Lock)
在執行查詢語句(SELECT)前,會自動給涉及的全部表加讀鎖,在執行更新操做(UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖,這個過程並不須要用戶干預。
讀鎖:容許另外一個線程對錶的數據進行查詢,不容許增刪改
寫鎖:不容許另外一個線程對標數據的增刪改查。
4、InnoDB的鎖(行級別和表級別)
InnoDB行鎖是經過給索引上的索引項加鎖來實現的,這一點MySQL與Oracle不一樣,後者是經過在數據塊中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特色意味着:只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖!
InnoDB實現瞭如下兩種類型的行鎖。
1、 共享鎖(S):容許一個事務去讀一行,阻止其餘事務得到相同數據集的排他鎖。
2、 排他鎖(X):容許得到排他鎖的事務更新數據,阻止其餘事務取得相同數據集的共享讀鎖和排他寫鎖。
另外,爲了容許行鎖和表鎖共存,實現多粒度鎖機制,InnoDB還有兩種內部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。
1、 意向共享鎖(IS):事務打算給數據行加行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。
2、 意向排他鎖(IX):事務打算給數據行加行排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。
意向鎖是InnoDB自動加的,不需用戶干預。對於UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及數據集加排他鎖(X);對於普通SELECT語句,InnoDB不會加任何鎖;事務能夠經過如下語句顯示給記錄集加共享鎖或排他鎖。
共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。
排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE。
共享鎖 Shared (S) Locks
共享鎖容許多個transaction同時對一個資源進行讀(SELECT)操做,可是不容許其它transaction對 加鎖的資源進行修改。讀操做完成後,共享鎖會被當即釋放(除非隔離級別是Read Repeatable或者更高, 或者顯式地經過locking hint要求在transaction期間保持這個共享鎖)。
排它鎖 Exclusive (X) Locks
當一個transaction在一個資源上加上排它鎖以後,其它的transaction不能對這個資源進行修改操做以及 讀操做(除非隔離級別是Read Uncommitted或者使用了NOLOCK hint,才容許讀操做)。