什麼是鎖
鎖是應對併發領域中常見的一種手段,比如在多執行緒程式設計中多個執行緒對同乙個資源進行讀寫,這時候鎖可以將並行化的訪問變成序列化,來保證資料的安全。所以鎖的主要作用是管理共享資源的併發時候的訪問。mysql中的鎖是用於實現事務中的隔離性(isolation)。
mysql中的鎖
mysql鎖的實現是由mysql各個儲存引擎來實現的,每個儲存引擎實現具體的鎖機制。比如innodb支援行鎖,而mysiam只支援表鎖。
mysql鎖的型別
共享鎖(也稱讀鎖):簡稱s鎖,多個執行緒可以在同一時間讀取同一資源而不相互干擾。
獨佔鎖(也稱寫鎖):簡稱x鎖,出於資料完整性的考慮,獨佔所是排他的會阻塞其他的寫鎖和讀鎖,這樣才能保證在同一時刻只有乙個執行緒能寫入資料,並防止其他執行緒讀取正在寫入的資料,這也是事務隔離性的體現。寫鎖和其他的鎖是不相容的。
注意:innode的鎖都是行鎖,相容性是指同一行記錄。
鎖的粒度
鎖的粒度是指鎖的策略,指的是被加鎖的最小資源單位,比如在行上加鎖,那麼加鎖的最小單位指的就是行,這樣的鎖就稱之為行級鎖。如果鎖的資源是資料頁,那麼久稱為頁級別鎖,同理如果鎖的最小單位是表,那麼就是表級鎖。為了能提高併發性,鎖定資源盡肯能的小,最理想的方式就是只需要對要修改的資料進行精確的鎖定。
mysql提供兩種鎖的粒度,一種是表級鎖(table-level),是mysql最基本的鎖策略,開銷小(併發性底),表鎖在加鎖時會鎖定整張表,乙個使用者在寫資料前要獲得表鎖去阻塞其他使用者對錶的操作,只有沒有寫鎖時其他讀取的使用者才能取得讀鎖。另一種是行級鎖(row-level),行級鎖可以最大程度支援併發,不過開銷比較大,而且是儲存引擎實現。
根據鎖的粒度鎖可分為:
1. 行級鎖
開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
2. 頁級鎖
開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。
3. 表級鎖
開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
mysql的表級鎖有兩種模式:表共享讀鎖(table read lock)和表獨佔寫鎖(table write lock)。
表級鎖和行級鎖對比:
表級鎖: mysql中鎖定 粒度最大 的一種鎖,對當前操作的整張表加鎖,實現簡單,資源消耗也比較少,加鎖快,不會出現死鎖。其鎖定粒度最大,觸發鎖衝突的概率最高,併發度最低,myisam和 innodb引擎都支援表級鎖。
行級鎖: mysql中鎖定 粒度最小 的一種鎖,只針對當前操作的行進行加鎖。 行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,併發度高,但加鎖的開銷也最大,加鎖慢,會出現死鎖。
頁級鎖: mysql中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。頁級進行了折衷,一次鎖定相鄰的一組記錄。bdb支援頁級鎖。開銷和加鎖時間界於表鎖和行鎖之間,會出現死鎖。鎖定粒度界於表鎖和行鎖之間,併發度一般。
鎖模式共享鎖(s):又稱讀鎖,若事務t對資料物件a加上s鎖,則事務t可以讀a但不能修改a,其他事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖。這保證了其他事務可以讀a,但在t釋放a上的s鎖之前不能對a做任何修改。
排他鎖(x):又稱寫鎖。若事務t對資料物件a加上x鎖,事務t可以讀a也可以修改a,其他事務不能再對a加任何鎖,直到t釋放a上的鎖。這保證了其他事務在t釋放a上的鎖之前不能再讀取和修改a。
另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制,innodb還有兩種內部使用的意向鎖(intention locks),這兩種意向鎖都是表鎖。
意向共享鎖(is):事務打算給資料行加行共享鎖,事務在給乙個資料行加共享鎖前必須先取得該錶的is鎖。
意向排他鎖(ix):事務打算給資料行加行排他鎖,事務在給乙個資料行加排他鎖前必須先取得該錶的ix鎖。
意向鎖僅僅用於表鎖和行鎖的共存使用。如果我們的操作僅僅涉及行鎖,那麼意向鎖不會對我們的操作產生任何影響。在任一操作給表a的一行記錄加鎖前,首先要給該錶加意向鎖,如果獲得了意向鎖,然後才會加行鎖,並在加行鎖時判斷是否衝突。如果現在有乙個操作要獲得表a的表鎖,由於意向鎖的存在,表鎖獲取會失敗(如果沒有意向鎖的存在,加表鎖之前可能要遍歷整個聚簇索引,判斷是否有行鎖存在,如果沒有行鎖才能加表鎖)。
同理,如果某一操作已經獲得了表a的表鎖,那麼另一操作獲得行鎖之前,首先會檢查是否可以獲得意向鎖,並在獲得意向鎖失敗後,等待表鎖操作的完成。也就是說:1.意向鎖是表級鎖,但是卻表示事務正在讀或寫某一行記錄;2.意向鎖之間不會衝突, 因為意向鎖僅僅代表要對某行記錄進行操作,在加行鎖時,會判斷是否衝突;3.意向鎖是innodb自動加的,不需使用者干預。
innodb儲存引擎中的鎖
1. 共享/排他鎖(shared and exclusive locks)
2. 意向鎖(intention locks)
3. 記錄鎖(record locks)
只鎖記錄。表現為僅僅鎖著單獨的一行記錄。
4. 間隙鎖(gap locks)
只鎖間隙。表現為鎖住乙個區間(注意這裡的區間都是開區間,也就是不包括邊界值)。
5. 臨鍵鎖(next-key locks)
同時鎖住記錄和間隙。從實現的角度為record lock+gap lock,而且兩種鎖有可能只成功乙個,所以next-key是半開半閉區間,且是下界開,上界閉。一張表中的next-key鎖包括:(負無窮大,最小的第一條記錄],(記錄之間],(最大的一條記錄,正無窮大)。
6. 插入意向鎖(insert intention locks)
插入操作時使用的鎖。在**中,插入意圖鎖實際上是gap鎖上加了乙個lock_insert_intention的標記。也就是說insert語句會對插入的行加乙個x記錄鎖,但是在插入這個行的過程之前,會設定乙個insert intention的gap鎖,叫做insert intention鎖。
7. 自增鎖(auto-inc locks)
針對自增列自增長的乙個特殊的表級別鎖。可以使用如下語句檢視 :
show variables like 'innodb_autoinc_lock_mode';
檢視innodb鎖情況
#有加鎖的情況這裡可以檢視到show full processlist;#可以檢視innodb引擎相關鎖的狀態,是否有死鎖等
show engine innodb status;
#檢視當前鎖的資訊select * frominformation_schema.innodb_locks;
#檢視鎖等待資訊select * from information_schema.innodb_locks_waits;
一致性非鎖定讀與一致性鎖定讀
一致性非鎖定讀(consistent nonlocking read):指的是如果一條記錄被加了x鎖,其他事務還能讀取這條記錄。
一致性鎖定讀(consistent locking read):指的是乙個事務可以通過select語句給某條記錄加x鎖或者x鎖。
#會對查詢的行及相關聯的索引記錄加x鎖,其他事務請求的s鎖或x鎖都會被阻塞。
select...for update
#對讀取的行新增s鎖,其他事物可以對這些行新增s鎖,若新增x鎖,則會被阻塞。
select...lock in share mode
mysql會話鎖 Mysql鎖機制 寫鎖
1 準備資料 1.1 建表 1.1.1 建立 employee表 drop table if existsemployee create table if not existsemployee idint primary keyauto increment,namevarchar 40 dept i...
mysql 查詢鎖 MySQL 鎖查詢
一 從檢視檢視 檢視程序 show processlist 檢視是否鎖表 show open tables where in use 0 1 檢視當前的事務 select from information schema.innodb trx 2 檢視當前鎖定的事務 select from infor...
mysql鎖機制 mysql 鎖機制
一 概述 mysql有三種鎖的級別 頁級 表級 行級。myisam和memory儲存引擎採用的是表級鎖 table level locking bdb儲存引擎採用的是頁面鎖 page level locking 但也支援表級鎖 innodb儲存引擎既支援行級鎖 row level locking 也...