無論何時,只要有多個查詢需要在同一時刻修改資料,都會產生併發控制的問題。
在處理併發讀或者寫時,可以通過實現乙個由兩種型別的鎖組成的鎖系統來解決問題。這兩種型別的鎖通常被稱為共享鎖(shared lock)和排他鎖(exclusive lock),也叫讀鎖(read lock)和寫鎖(write lock)。
鎖的概念如下:
讀鎖是共享的,或者說是相互不阻塞的。多個客戶在同一時刻可以同時讀取同乙個資源,而互不干擾。
寫鎖則是排他的,也就是說乙個寫鎖會阻塞其他的寫鎖和讀鎖,這是出於安全策略的考慮,只有這樣,才能確保在給定的時間裡,只有乙個使用者能執行寫入,並防止其他使用者讀取正在寫入的同一資源。
在實際的資料庫系統中,每時每刻都在發生鎖定,當某個使用者在修改某一部分資料時,mysql會通過鎖定防止其他使用者讀取同一資料。大多數時候,mysql鎖的內部管理都是透明的(自動加鎖)。
一種提高共享資源併發性的方式就是讓鎖定物件更有選擇性。盡量只鎖定需要修改的部分資料,而不是所有的資源。更理想的方式是,只對會修改的資料片進行精確的鎖定。任何時候,在給定的資源上,鎖定的資料量越少,則系統的併發程度越高,只要相互之間不發生衝突即可。
mysql則提供了多種選擇。每種mysql儲存引擎都可以實現自己的鎖策略和鎖粒度。
表鎖(table lock)
表鎖是mysql中最基本的鎖策略,並且是開銷最小的策略。它會鎖定整張表,乙個使用者在對錶進行寫操作(插入、刪除、更新等)前,需要先獲得寫鎖,這會阻塞其他使用者對該錶的所有讀寫操作。只有沒有寫鎖時,其他讀取的使用者才能獲得讀鎖,讀鎖之間是不相互阻塞的。
在特定的場景中,表鎖也可能有良好的效能。例如,read local表鎖支援某些型別的併發寫操作。另外,寫鎖也比讀鎖有更高的優先順序,因此乙個寫鎖請求可能會被插入到讀鎖佇列的前面(寫鎖可以插入到鎖佇列中讀鎖的前面,反之讀鎖則不能插入到寫鎖的前面)。
儘管儲存引擎可以管理自己的鎖,mysql本身還是會使用各種有效的表鎖來實現不同的目的。例如,伺服器會為諸如alter table之類的語句使用表鎖,而忽略儲存引擎的鎖機制。
表鎖的優勢:開銷小;加鎖快;無死鎖行級鎖(row lock)表鎖的劣勢:鎖粒度大,發生鎖衝突的概率高,併發處理能力低
加鎖的方式:自動加鎖。查詢操作(select),會自動給涉及的所有表加讀鎖,更新操作(update、delete、insert),會自動給涉及的表加寫鎖。也可以顯示加鎖:
共享讀鎖:lock table tablename read;
獨佔寫鎖:lock table tablename write;
批量解鎖:unlock tables;
行級鎖可以最大程度地支援併發處理(同時也帶來了最大的鎖開銷)。在innodb和xtradb,以及其他一些儲存引擎中實現了行級鎖。行級鎖只在儲存引擎層實現,而mysql伺服器層沒有實現。伺服器層完全不了解儲存引擎中的鎖實現,所有的儲存引擎都以自己的方式顯現了鎖機制。
行鎖的劣勢:開銷大;加鎖慢;會出現死鎖innodb的行鎖是針對索引加的鎖,不是針對記錄加的鎖。並且該索引不能失效,否則都會從行鎖公升級為表鎖。行鎖的優勢:鎖的粒度小,發生鎖衝突的概率低;處理併發的能力強
加鎖的方式:自動加鎖。對於update、delete和insert語句,innodb會自動給涉及資料集加排他鎖;對於普通select語句,innodb不會加任何鎖;當然我們也可以顯示的加鎖:
共享鎖:select * from tablename where ... + lock in share mode
排他鎖:select * from tablename where ... + for update
間隙鎖在行級鎖的基礎上,當用範圍條件檢索資料,並請求共享或排他鎖時,innodb會給符合條件的已有資料記錄的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫做"間隙(gap)"。innodb也會對這個"間隙"加鎖,這種鎖機制就是所謂的間隙鎖(next-key鎖)。
# 事務1mysql> update innodb_lock set k=66 where id >=6;query ok,
1 row affected (0.33
sec)
mysql>commit;
# 事務2
mysql> insert into innodb_lock (id,k,v) values(8,'
8','
8000');
query ok,
1 row affected (12.99 sec)
第乙個事務鎖住了不存在的id,導致第二個事務執行插入時阻塞。
危害(坑):若執行的條件是範圍過大,則innodb會將整個範圍內所有的索引鍵值全部鎖定,很容易對效能造成影響。
高效能MySql之併發控制
剛買了一本高效能mysql這本書,順便做個筆記記錄學習的足跡。一 共享鎖和排它鎖 mysql的鎖系統 shared lock和exclusive lock 共享鎖和排他鎖,也叫讀鎖和寫鎖,即write lock和read lock 讀鎖是共享的,或者說是相互不阻塞的 寫鎖是排他的,乙個寫鎖會阻塞其他...
高效能MySQL(第3版)筆記 1 2 併發控制
在處理併發讀或者寫時,可以通過實現乙個由兩種型別的鎖組成鎖系統來解決問題 共享鎖 shared lock 也叫讀鎖 read lock 排他鎖 exclusive lock 也叫寫鎖 write lock 讀鎖 共享,互不阻塞,多個客戶在同一時刻可以同時讀取同乙個資源而互不干擾 寫鎖 排他,會阻塞其...
《高效能MySQL》讀書筆記 多版本併發控制演算法
mysql採用預設自動提交,可以通過如下命令檢視和修改 mysql show variables like autocommit variable name value autocommit on 1 row in set 0.00 sec mysql set autocommit 1 innodb...