一:概述
相對其他資料庫而言,mysql的鎖機制比較簡單,其最顯著的特點是不同的儲存引擎支援不同的鎖機制。比如,myisam和memory儲存引擎採用的是表級鎖(table-level locking);innodb儲存引擎既支援行級鎖( row-level locking),也支援表級鎖,但預設情況下是採用行級鎖。
mysql主要的兩種鎖的特性可大致歸納如下:
表級鎖: 開銷小,加鎖快;不會出現死鎖(因為myisam會一次性獲得sql所需的全部鎖);鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
行級鎖: 開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
二:myisam鎖細述
(1). 鎖模式
mysql的表級鎖有兩種模式: 表共享讀鎖(table read lock)和表獨佔寫鎖(table write lock)。
(2). 如何加鎖
當myisam在執行查詢語句時,會自動給涉及到表加讀鎖,在執行更新操作時,會加寫鎖。當然使用者也可以用lock table 去顯式的加鎖。顯式的加鎖一般是應用於:需要在乙個時間點實現多個表的一致性讀取,不然的話,可能讀第乙個表時,其他表由於還沒進行讀操作,沒有自動加鎖,可能資料會發生改變。並且顯示加鎖後只能訪問加鎖的表,不能訪問其他表。
(3). 併發插入
myisam儲存引擎有個系統變數 concurrent_insert,專門用來控制併發插入的行為,可以取 0 , 1 , 2。
0表示不允許併發插入,1表示表中間沒有刪除的行時可以在表末尾插入,2表示總是可以插入。
一般如果對併發要求比較高的情況下,可以設定為2,總是可以插入,然後定期在資料庫空閒時間對錶進行optimize。
(4). 鎖的排程
需要注意的是,其中讀操作不會阻塞其他使用者對同一表的讀請求,但會阻塞對同一表的寫請求;並且當寫鎖和讀鎖同時被申請時,優先獲得寫鎖,這也這正是表級鎖發生鎖衝突概率最高的原因,因為寫鎖可能會一直阻塞讀鎖,所以不適合有大量寫操作的環境下工作。這一問題可以通過設定low-priority-updates這一啟動引數來降低寫的優先順序。
雖然寫鎖優先於讀鎖獲取,但是長時間的查詢操作也可能會讓寫操作餓死,所以盡量避免一條sql語句執行所有的查詢,應該進行必要的分解。
三:innodb鎖細述
由於innodb支援事務,並預設是使用行級鎖,所以innodb的鎖問題和myisam鎖問題還是有蠻大差別的。
(1). 鎖模式
共享鎖(s)和排他鎖(x),分別類似於myisam的讀鎖和寫鎖。對於 update、 delete 和 insert 語句,innodb會自動給涉及資料集加排他鎖(x);對於普通 select 語句,innodb不會加任何鎖。
(2). 如何加鎖
可以顯式的加鎖,用lock in share mode 顯式的加共享鎖,用 for update 顯式的加排他鎖。
需要注意的是,如果執行緒a加了共享鎖後,執行緒b對同乙個表加了共享鎖,那麼兩個執行緒需要進行更新操作時會產生死鎖。所以,進行更新操作時最好加排他鎖。
(3). innodb行鎖的實現方式——索引加鎖
這一點與oracle不同,所以這也意味著(重要):1. 只有通過索引條件檢索資料時,innodb才會使用行級鎖,否則會使用表級鎖。 2. 即使是訪問不同行的記錄,如果使用的是相同的索引鍵,會發生鎖衝突。 3. 如果資料表建有多個索引時,可以通過不同的索引鎖定不同的行。
(4). 間隙鎖
innodb支援事務,為了滿足隔離級別的要求,innodb有個間隙鎖,當使用範圍查詢時,innodb會給滿足key範圍要求,但實際並不存在的記錄加鎖。例如:select * from user where id > 100 for updata 會給id>100的記錄加排他鎖,滿足這個範圍,但不存在的記錄,會加間隙鎖,這樣可以避免幻讀,避免讀取的時候插入滿足條件的記錄。
(5). 隔離級別與鎖
一般來說,隔離級別越高,加鎖就越嚴格。這樣,產生鎖衝突的概率就越大,一般實際應用中,通過優化應用邏輯,選用 可提交讀 級別就夠了。對於一些確實需要更高隔離級別的事務,再通過set session transaction isolation level+"級別" 來動態改變滿足需求。
四:死鎖
myisam是沒有死鎖問題的,因為他會一次性獲得所有的鎖。innodb發生死鎖後一般能自動檢測到,並使乙個事務釋放鎖並回退,另乙個事務獲得鎖,繼續完成事務。
在應用中,可以通過如下方式來盡可能的避免死鎖:
(1) 如果不同的程式會併發的訪問多個表,應盡量約定以相同的順序來訪問表,這樣可以大大降低產生死鎖的機會。
(2) 在程式以批量方式處理資料時,如果事先對資料排序,保證每個執行緒按固定的順序來處理記錄,也可以大大的降低出現死鎖的可能。
MySQL行級鎖和表級鎖
鎖定用於確保事務完整性和資料庫一致性。鎖定可以防止使用者讀取其他使用者正在更改的資料,並防止多個使用者同時更改相同的資料。如果不使用鎖定,資料庫中的資料可能在邏輯上變得不正確,而針對這些資料進行查詢可能會產生想不到的結果。在電腦科學中,鎖是在執行多執行緒時用於強行限制資源訪問的同步機制,即用於在併發...
MySQL表級鎖和行級鎖
一 概述 相對其他資料庫而言,mysql的鎖機制比較簡單,其最顯著的特點是不同的儲存引擎支援不同的鎖機制。比如,myisam和memory儲存引擎採用的是表級鎖 table level locking innodb儲存引擎既支援行級鎖 row level locking 也支援表級鎖,但預設情況下是...
MYSQL行級鎖和表級鎖
相對其他資料庫而言,mysql的鎖機制比較簡單,其最顯著的特點是不同的儲存引擎支援不同的鎖機制。比如,myisam和memory儲存引擎採用的是表級鎖 table level locking innodb儲存引擎既支援行級鎖 row level locking 也支援表級鎖,但預設情況下是採用行級鎖...