mysql資料庫由於其自身架構的特點,存在多種資料儲存引擎,每種儲存引擎所針對的應用場景特點都不太一樣,為了滿足各自特定應用場景的需求,每種儲存引擎的鎖定機制都是為各自所面對的特定場景而優化設計,所以各儲存引擎的鎖定機制也有較大區別。mysql各儲存引擎使用了三種型別(級別)的鎖定機制:表級鎖定,行級鎖定和頁級鎖定。
表級,直接鎖定整張表,在你鎖定期間,其它程序無法對該錶進行寫操作。如果你是寫鎖,則其它程序則讀也不允許
行級,,僅對指定的記錄進行加鎖,這樣其它程序還是可以對同乙個表中的其它記錄進行操作。
頁級,表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低;
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高;
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。
innodb的行級鎖定同樣分為兩種型別,共享鎖和排他鎖,而在鎖定機制的實現過程中為了讓行級鎖定和表級鎖定共存,innodb也同樣使用了意向鎖(表級鎖定)的概念,也就有了意向共享鎖和意向排他鎖這兩種。
當乙個事務需要給自己需要的某個資源加鎖的時候,如果遇到乙個共享鎖正鎖定著自己需要的資源的時候,自己可以再加乙個共享鎖,不過不能加排他鎖。但是,如果遇到自己需要鎖定的資源已經被乙個排他鎖占有之後,則只能等待該鎖定釋放資源之後自己才能獲取鎖定資源並新增自己的鎖定。而意向鎖的作用就是當乙個事務在需要獲取資源鎖定的時候,如果遇到自己需要的資源已經被排他鎖占用的時候,該事務可以需要鎖定行的表上面新增乙個合適的意向鎖。如果自己需要乙個共享鎖,那麼就在表上面新增乙個意向共享鎖。而如果自己需要的是某行(或者某些行)上面新增乙個排他鎖的話,則先在表上面新增乙個意向排他鎖。意向共享鎖可以同時並存多個,但是意向排他鎖同時只能有乙個存在。
所以,可以說innodb的鎖定模式實際上可以分為四種:共享鎖(s),排他鎖(x),意向共享鎖(is)和意向排他鎖(ix),我們可以通過以下**來總結上面這四種所的共存邏輯關係:
如果乙個事務請求的鎖模式與當前的鎖相容,innodb就將請求的鎖授予該事務;反之,如果兩者不相容,該事務就要等待鎖釋放。
意向鎖是innodb自動加的,不需使用者干預。對於update、delete和insert語句,innodb會自動給涉及資料集加排他鎖(x);對於普通select語句,innodb不會加任何鎖;事務可以通過以下語句顯示給記錄集加共享鎖或排他鎖。
共享鎖(s):selectinnodb行鎖是通過給索引上的索引項加鎖來實現的,只有通過索引條件檢索資料,innodb才使用行級鎖,否則,innodb將使用表鎖*from table_name where ... lock in
share mode
排他鎖(x):
select
*from table_name where ... for
update
在實際應用中,要特別注意innodb行鎖的這一特性,不然的話,可能導致大量的鎖衝突,從而影響併發效能。下面通過一些實際例子來加以說明。
(1)在不通過索引條件查詢的時候,innodb確實使用的是表鎖,而不是行鎖。
(2)由於mysql的行鎖是針對索引加的鎖,不是針對記錄加的鎖,所以雖然是訪問不同行的記錄,但是如果是使用相同的索引鍵,是會出現鎖衝突的。
(3)當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,另外,不論是使用主鍵索引、唯一索引或普通索引,innodb都會使用行鎖來對資料加鎖。
(4)即便在條件中使用了索引字段,但是否使用索引來檢索資料是由mysql通過判斷不同執行計畫的代價來決定的,如果mysql認為全表掃瞄效率更高,比如對一些很小的表,它就不會使用索引,這種情況下innodb將使用表鎖,而不是行鎖。因此,在分析鎖衝突時,別忘了檢查sql的執行計畫,以確認是否真正使用了索引。
3.間隙鎖(next-key鎖)
當我們用範圍條件而不是相等條件檢索資料,並請求共享或排他鎖時,innodb會給符合條件的已有資料記錄的索引項加鎖;
對於鍵值在條件範圍內但並不存在的記錄,叫做「間隙(gap)」,innodb也會對這個「間隙」加鎖,這種鎖機制就是所謂的間隙鎖(next-key鎖)。
例:假如emp表中只有101條記錄,其empid的值分別是 1,2,...,100,101,下面的sql:
mysql>是乙個範圍條件的檢索,innodb不僅會對符合條件的empid值為101的記錄加鎖,也會對empid大於101(這些記錄並不存在)的「間隙」加鎖。select
*from emp where empid >
100for
update;
innodb使用間隙鎖的目的:
(1)防止幻讀,以滿足相關隔離級別的要求。對於上面的例子,要是不使用間隙鎖,如果其他事務插入了empid大於100的任何記錄,那麼本事務如果再次執行上述語句,就會發生幻讀;
(2)為了滿足其恢復和複製的需要。
mysql行級鎖 頁級鎖和表級鎖
mysql的鎖是由具體的儲存引擎實現的。所以像mysql的預設引擎myisam和第三方外掛程式引擎 innodb的鎖實現機制是有區別的。1.表級鎖定 table level 表級別的鎖定是mysql各儲存引擎中最大顆粒度的鎖定機制。該鎖定機制最大的特點是實現邏輯非常簡單,帶來的系統負面影響最小。所以...
mysql的行級鎖 表級鎖 頁級鎖
鎖是在執行多執行緒時用於強行限制資源訪問的同步機制,即用於在併發控制中保證對互斥要求的滿足 行級鎖 是mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖和排他鎖 特點 開銷大,加鎖慢,會出現死鎖 鎖...
MySQL中的行級鎖,表級鎖,頁級鎖
在電腦科學中,鎖是在執行多執行緒時用於強行限制資源訪問的同步機制,即用於在併發控制中保證對互斥要求的滿足。在資料庫的dbms中,可以按照鎖的粒度把資料庫鎖分為行級鎖 innodb引擎 表級鎖 myisam引擎 和頁級鎖 bdb引擎 行級鎖是mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行...