1. 程式人生 > >MySQL- InnoDB鎖機制

MySQL- InnoDB鎖機制

MySQL的鎖機制比較簡單,最顯著的特點是不同的儲存引擎支援不同的鎖機制。InnoDB支援行鎖,有時也會升級為表鎖;myisam只支援表鎖。

表鎖的特點就是開銷小、加鎖快;不會出現死鎖;鎖粒度大,發生鎖衝突的概率高,併發度相對低。

行鎖的特點就是開銷大、加鎖慢;會出現死鎖;鎖粒度小,發生鎖衝突的概率低,併發度也相對較高。

1、InnoDB的鎖型別:

主要有:讀鎖(共享鎖)、寫鎖(排他鎖)、意向鎖和MDL鎖。

①:讀鎖:

讀鎖,簡稱S鎖,一個事務獲取了一個數據行的讀鎖,其他事務能獲得改行對應的讀鎖,但不能獲得寫鎖,即一個事務在讀取一個數據行時,其他事務也可以讀,但不能對該資料行進行行增刪改的操作。

讀鎖有兩種select方式的應用,第一種是自動提交模式下的select查詢語句,不需要加任何鎖,直接返回查詢結果,這就是一致性非鎖定讀。第二種就是通過select...lock in share mode在被讀取的行記錄或行記錄範圍上加一個讀鎖,讓其他事務可以讀,但是要想申請加寫鎖,那就會被阻塞。

②:寫鎖:

寫鎖,簡稱X鎖,一個事務獲取了一個數據行的寫鎖,其他事務就不能再獲取改行的其他鎖,寫鎖優先順序最高。

寫鎖的應用就很簡單了,一些DML語句的操作都會對行記錄加寫鎖。

比較特殊的是select  for  update,它會對讀取的行記錄加上一個寫鎖,那麼其他任何事務就不能對鎖定的行加上任何鎖了,要不然會被阻塞。

③:MDL鎖

MySQL5.5引入了meta data lock,簡稱MDL鎖,用於保證表中元資料的資訊。在會話A中,表開啟了查詢事務後,會自動獲得一個MDL鎖,會話B就不可以執行任何DDL語句的操作。

不能執行為表中新增欄位的操作,會用DML鎖來保證資料之間的一致性。

④:意向鎖

在MySQL  InnoDB儲存引擎中,意向鎖就是表級鎖。而且有兩種意向鎖的型別,分別是意向共享鎖 和 意向排他鎖。

意向共享鎖(IS)是指在給一個數據行加共享鎖前必須先取得該表的IS鎖。

意向排他鎖(IX)是指在給一個數據行加排他鎖前必須先取得該表的IX鎖。

其實意向鎖的作用跟MDL類似,都是防止在事務進行過程中,執行DDL語句的操作而導致資料的不一致。

2、InnoDB行鎖種類:

InnoDB的行鎖是通過給索引項加鎖實現的(也就是說:通過以點陣圖方式對index page加鎖機制來實現的。),這就意味著只有通過索引條件檢索資料時,InnoDB才使用行鎖,否則使用表鎖。也就是說,如果批量update,如果條件的欄位沒有索引,將會鎖表!!!!!如果有索引 只會出現行鎖!

InnoDB在預設的事務隔離級別為RR,並且引數InnoDB_locks_unsafe_for_binlog=0的模式下,行鎖的種類有三種。

①:單個行記錄的鎖(record lock);注:主鍵和唯一索引都是行記錄的鎖模式。在RC隔離級別下,只有record lock記錄鎖模式;

②:間隙鎖(GAP lock)

③:記錄鎖和間隙鎖的組合叫作next-key lock。(當InnoDB掃描索引記錄時,會先對選中的索引記錄加上記錄鎖,在對索引記錄兩邊的間隙上加上間隙鎖)

注意:

InnoDB的行鎖其實是載入索引項上面的。

RC隔離級別下是允許出現幻讀現象的。

3、鎖等待和死鎖:

鎖等待:是指一個事務過程中產生的鎖,其他事務需要等待上一個事務釋放它的鎖,才能佔用該資源。如果該事務一直不釋放,就需要持續等待下去,直到超過了鎖等待時間,會報一個等待超時的錯誤。MySQL中通過InnoDB_lock_wait_timeout引數控制,單位是秒。

show variables like '%InnoDB_lock_wait%';  ---檢視鎖等待超時時間

死鎖:是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,就是所謂的鎖資源請求產生了迴路現象,即死迴圈。常見的錯誤時deadlock found when trying to get lock;try restarting transaction.

InnoDB儲存引擎可以自動檢測死鎖,並自動回滾該事務。

避免死鎖的方法:

①:如果不同程式會併發存取多個表,或者涉及多行記錄時,儘量約定以相同的順序訪問表,可以大大降低死鎖的機會。

②:業務中儘量採用小事務,避免使用大事務,要及時提交或者回滾事務,可減少死鎖發生的概率。

③:在同一個事務中,儘可能做到一次鎖定所需要的所有資源,減少死鎖產生的概率。

④:對於非常容易產生死鎖的業務部分,可以嘗試使用升級鎖粒度,通過表鎖定來減少死鎖產生的概率。

4、鎖監控的方法:

可以使用:show full processlist 或者 show  engine InnoDB status命令來判斷事務中鎖的問題的情況。

還可以檢視3張表:information_schema下的:InnoDB_trx、innodb_locks、InnoDB_lock_waits