MySQL中鎖詳解

2021-09-27 06:08:12 字數 2564 閱讀 7213

相對於其他的資料庫而言,mysql的鎖機制比較簡單,最顯著的特點就是不同的儲存引擎支援不同的鎖機制。根據不同的儲存引擎,mysql中鎖的特性可以大致歸納如下:

行鎖表鎖

頁鎖myisam

√bdb√√

innodb√√

開銷、加鎖速度、死鎖、粒度、併發效能

表鎖更適用於以查詢為主,只有少量按索引條件更新資料的應用;行鎖更適用於有大量按索引條件併發更新少量不同資料,同時又有併發查詢的應用。ps:由於bdb已經被innodb所取代,我們只討論myisam表鎖和innodb行鎖的問題)

mysql的表級鎖有兩種模式:表共享讀鎖(table read lock)和表獨佔寫鎖(table write lock)。

對myisam表的讀操作,不會阻塞其他使用者對同一表的讀請求,但會阻塞對同一表的寫請求;對 myisam表的寫操作,則會阻塞其他使用者對同一表的讀和寫操作;myisam表的讀操作與寫操作之間,以及寫操作之間是序列的!

如何加表鎖

myisam在執行查詢語句(select)前,會自動給涉及的所有表加讀鎖

在執行更新操作(update、delete、insert等)前,會自動給涉及的表加寫鎖

這個過程並不需要使用者干預,因此,使用者一般不需要直接用lock table命令給myisam表顯式加鎖。

顯示加鎖

lock tables orders read local, order_detail read local;  

select sum(total) from orders;

select sum(subtotal) from order_detail;

unlock tables;

1.在用lock tables給表顯式加表鎖時,必須同時取得所有涉及到表的鎖,並且mysql不支援鎖公升級。也就是說,在執行lock tables後,只能訪問顯式加鎖的這些表,不能訪問未加鎖的表;

2.同時,如果加的是讀鎖,那麼只能執行查詢操作,而不能執行更新操作。

3.其實,在自動加鎖的情況下也基本如此,myisam總是一次獲得sql語句所需要的全部鎖。這也正是myisam表不會出現死鎖(deadlock free)的原因。

innodb與myisam的最大不同有兩點:一是支援事務(transaction);二是採用了行級鎖。

innodb的行鎖模式及加鎖方法

innodb實現了以下兩種型別的行鎖。

意向鎖是innodb自動加的,不需使用者干預。對於update、delete和insert語句,innodb會自動給涉及資料集加排他鎖(x);對於普通select語句,innodb不會加任何鎖;

事務可以通過以下語句顯示給記錄集加共享鎖或排他鎖。

innodb行鎖實現方式

innodb行鎖是通過給索引上的索引項加鎖來實現的,這一點mysql與oracle不同,後者是通過在資料塊中對相應資料行加鎖來實現的。innodb這種行鎖實現特點意味著:只有通過索引條件檢索資料,innodb才使用行級鎖,否則,innodb將使用表鎖!

(1)在不通過索引條件查詢的時候,innodb確實使用的是表鎖,而不是行鎖。

(2)由於mysql的行鎖是針對索引加的鎖,不是針對記錄加的鎖,所以雖然是訪問不同行的記錄,但是如果是使用相同的索引鍵,是會出現鎖衝突的。應用設計的時候要注意這一點。

(3)當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,另外,不論是使用主鍵索引、唯一索引或普通索引,innodb都會使用行鎖來對資料加鎖。

(4)即便在條件中使用了索引字段,但是否使用索引來檢索資料是由mysql通過判斷不同執行計畫的代價來決定的,如果mysql認為全表掃瞄效率更高,比如對一些很小的表,它就不會使用索引,這種情況下innodb將使用表鎖,而不是行鎖。因此,在分析鎖衝突時,別忘了檢查sql的執行計畫,以確認是否真正使用了索引。

間隙鎖(next-key鎖)

當我們用範圍條件而不是相等條件檢索資料,並請求共享或排他鎖時,innodb會給符合條件的已有資料記錄的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫做「間隙(gap)」,innodb也會對這個「間隙」加鎖,這種鎖機制就是所謂的間隙鎖(next-key鎖)。

舉例來說,假如emp表中只有101條記錄,其empid的值分別是 1,2,…,100,101,下面的sql:

select * from emp where empid > 100 for update;

是乙個範圍條件的檢索,innodb不僅會對符合條件的empid值為101的記錄加鎖,也會對empid大於101(這些記錄並不存在)的「間隙」加鎖。

innodb使用間隙鎖的目的,一方面是為了防止幻讀,以滿足相關隔離級別的要求

另外一方面,是為了滿足其恢復和複製的需要。

關於死鎖

上文講過,myisam表鎖是deadlock free的,這是因為myisam總是一次獲得所需的全部鎖,要麼全部滿足,要麼等待,因此不會出現死鎖。但在innodb中,除單個sql組成的事務外,鎖是逐步獲得的,這就決定了在innodb中發生死鎖是可能的。如下所示的就是乙個發生死鎖的例子。

MySQL中鎖的詳解

myisam支援表鎖,同時也支援列所,表鎖加鎖方式 lock tables 表名 read lock tables 表名 write unlock tables 鎖名 鎖級別英文名稱 共享鎖行鎖 shared locks 排它鎖行鎖 exclusive locks 意向共享鎖 表鎖intention...

mysql行鎖詳解 詳解MySQL行鎖

鎖是計算機協調多個程序或執行緒併發訪問某一資源的機制。鎖保證資料併發訪問的一致性 有效性 鎖衝突也是影響資料庫併發訪問效能的乙個重要因素。鎖是mysql在伺服器層和儲存引擎層的的併發控制。mysql中從對資料操作的粒度分為表鎖和行鎖。表鎖是指對一整張表加鎖,一般是 ddl 處理時使用 而行鎖則是鎖定...

詳解mysql間隙鎖

1.什麼是間隙鎖?1 對於鍵值在條件範圍內但並不存在的記錄 在相等條件下請求給乙個不存在的記錄也會加鎖 叫做 間隙 gap innodb也會對這個 間隙 加鎖,這種鎖機制就是所謂的間隙鎖 next key鎖 2 查詢使用的範圍條件不是相等條件,innodb會給符合條件的已有資料記錄的索引項加鎖 2....