鎖是計算機協調多個進程或線程併發訪問某一資源的機制。在數據庫中,數據也是一種供許多用戶共享的資源。如何保證數據訪問的一致性、有效性是所有數據庫的一個問題,鎖衝突也是影響數據庫併發訪問性能的一個重要的因素,從這個角度來說,鎖對數據庫而言顯得尤其重要,也更加複雜。
MySQL鎖概述
相對其他數據庫而言,MySQL的鎖機制比較簡單,其最顯著的特點是不同的存儲引擎支持不同的鎖機制。比如,MyISAM和MEMORY存儲引擎採用的是表級鎖(table-level locking);BDB存儲引擎採用的是頁面鎖(page-level locking),但也支持表級鎖,但在默認情況下是採用行級鎖。
可以通過檢查table_locks_waited和table_locks_immediate狀態變量來分析系統上的表鎖定爭奪:
show status like 'table%';
得出的結果如果Table_locks_waited的值比較高,則說明存在着較嚴重的表級鎖爭用情況。
MySQL這三種鎖的特徵:
開銷、加鎖速度、死鎖、粒度、併發性能
表級鎖:開銷小,加鎖快,不會出現死鎖,鎖定粒度大,發生衝突的概率最高,併發度最低;
行級鎖:開銷大,加鎖慢,會出現死鎖,鎖定粒度小,發生鎖衝突的概率最低,併發度最高;
頁面鎖:開銷介於前兩者之間,會出現死鎖,鎖定粒度介於前兩者之間,併發度一般;
僅從鎖的角度來說:表級鎖更適合於以查詢爲主,只有少量按索引條件更新數據的應用,如web應用;而行級鎖則更適合於有大量按索引條件併發更新少量不同數據,同時僅有併發查詢的應用,如一些在線事務處理(OLTP)系統。
MySQL的表級鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨佔寫鎖(Table Write LocK)。
給表加鎖
1、加共享讀鎖
lock table 表名 read
2、解鎖
unlock tables;
3、表獨佔寫鎖
lock table 表名 write;
說明:
對MyISAM表的讀操作,不會阻塞其他用戶對同一張表的讀請求,但會阻塞對同一表的請求;對MyISAM表的寫操作,則會阻塞其他用戶對同一張表的讀和寫操作;MyISAM表的讀操作與寫的操作之間,以及寫操作之間是串行的!當一個線程獲得對一個表的寫鎖後,只有持有鎖的線程可以對錶進行更新操作。其他線程的讀、寫操作都會等待,直到鎖被釋放爲止。
一個SESSION使用Lock table 命令給表加鎖,這個SESSION可以查詢鎖定表中的記錄,但更新或訪問其他表都會提示錯誤;同時,另一個SESSION可以查詢表中的記錄,但更新就會出現鎖等待。