相對於其他的資料庫而言,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....