1. 程式人生 > >mysql之innodb-鎖

mysql之innodb-鎖

本篇主要根據innodb儲存引擎的鎖進行闡述,包括分類,演算法,以及鎖的一些問題

一、鎖的概述

     為了保證最大程度的利用資料庫的併發訪問,又要確保每個使用者能以一致的方式讀取和修改資料,為此鎖就派上了用場,也就是鎖的機制。鎖機制也是用於區別資料庫系統和檔案系統的一個關節特性。

鎖是為了支援對共享資源進行訪問,提供資料的一致性和完整性。
innodb儲存引擎支援行級別的鎖,不過也可以在其他很多的地方上鎖,比如,LRU列,刪除,新增,移動LRU列中的元素。
innodb儲存引擎提供了一致性的非鎖定讀,行級鎖支撐,行級鎖沒有額外的開銷,並可以同時保證併發和一致性。

二、innodb鎖

2.1、lock和latch

 

雖然兩個都是“鎖”,但是兩者有著截然不同的意義。

      latch為輕量級鎖:要求鎖定的時間非常短,在innodb中,其又可以分為mutex(互斥量)和rwlock(讀寫鎖),其目的是用來保證併發執行緒操作臨界資源的正確性,沒有死鎖檢查機制。
檢視:show ENGINE innodb MUTEX

 

 

 

其中os_waits表示作業系統等待的次數,當不能獲得latch時,作業系統就會進入等待狀態,等待被喚醒。

     lock為事務級鎖:用來鎖定資料庫中的物件,比如,表、頁、行。並且一般lock的物件僅在事務commit或者rollback後進行釋放,有死鎖機制。

2.2、innodb儲存引擎中的鎖

2.2.1、鎖的型別

共享鎖(S Lock):允許事務讀一行資料,具有鎖相容性質,允許多個事務同時獲得該鎖。
排它鎖(X Lock):允許事務刪除或更新一行資料,具有排它性,某個事務要想獲得鎖,必須要等待其他事務釋放該物件的鎖。

X鎖和其他鎖都不相容,S鎖之和S鎖相容,S鎖和X鎖都是行級別鎖,相容是指對同一條記錄(row)鎖的相容性情況。

     此外,innodb支援多粒度鎖定,這種鎖允許事務在行級別和表級別上的鎖同時存在,稱之為意向鎖(Intention Lock),意向鎖將鎖定的物件分為多個層次,意味著事務在更細粒度上進行加鎖。意向鎖設計的目的主要是為了在一個事務中揭示下一行將被請求的鎖型別。
意向共享鎖(IS Lock):事務想要獲得一張表中的某幾行的共享鎖
意向排它鎖(IX Lock):事務想要獲得一張表中的某幾行的排它鎖

對資料庫中的物件加鎖,類似於這棵樹,如下圖所示:

 

       若將上鎖看成如上的這顆樹,那麼對最下層物件的上鎖,也就是最細粒度的上鎖,首先需要對粗粒度進行上鎖,如上圖所示,如果我們需要對最底層的記錄進行上X鎖,那麼需要對資料庫,表,頁上意向鎖IX Lock,最後對最底層的記錄上X鎖,若其中的任意一個部分導致等待,則該操作需要等待粗粒度鎖的完成。

      由於innodb的支援行級鎖,所以意向鎖不會阻塞全表掃描以外的任何請求,故表級意向鎖和行級鎖的相容如下表所示:

 

 檢視鎖的方式:

1、show engine innodb status

2、show full processlist

3、在information_schema庫中有三個表可以檢視,分別是innodb_locks, innodb_trx, innodb_lock_waits.

innodb_trx表的結構(該表只用來顯示當前執行innodb事務情況,不能判斷鎖的情況):

 

 innodb_locks表的結構(可以檢視鎖的情況,當事務較小時,使用者可以認為的只管判斷,如果事務很大,則認為判斷就不好判斷了):

 

 innodb_lock_waits表的結構:

 

 2.2.2、一致性非鎖定讀

    一致性非鎖定讀是innodb儲存引擎通過多版本控制的方式來讀取當前執行時間資料庫中行的資料,如果讀取到正在刪除或者修改的記錄,這時讀取的操作不會等待行鎖的釋放,而是直接去讀取快照中的資料。如下圖所示:

 

    一致性非鎖定讀,是因為不需要等待訪問行上的X鎖的釋放。

    快照資料只的是該行的以前版本的資料,通過undo段來實現,而undo用來事務中的回滾資料,因此快照資料沒有額外的開銷,此外,讀取資料不要上鎖,因為沒有事務對歷史資料修改。一致性非鎖定讀提高資料庫的併發性(這是innodb的預設讀取方式)。但是在不同的事務隔離級別下,讀取方式不同,並不是每個事務隔離級別下都採用一致性非鎖定讀,就算採用一致性非鎖定讀,那還有可能就是快照資料的定義各不相同,比如快照可以有多個版本,所以這種技術稱為多版本技術,由此帶來的併發控制,稱為多版本併發控制(MVCC)

例如在事務隔離級別

READ COMMITTED中:一致性非鎖定讀總是讀取被鎖定行的最新一份快照資料;

REPEATABLE READ中:一致性非鎖定讀總是讀取事務開始時的行資料版本;

2.2.3、一致性鎖定讀

雖然innodb在預設情況下會採用一致性非鎖定讀方式進行讀取,但是某些時候使用者也可以顯示對資料庫讀取操作進行加鎖以保證資料的邏輯的一致性。

innodb儲存引擎對select語句支援兩種一致性鎖定讀的操作:

select ... for update   #對讀取行加X鎖,其他事務不能對已鎖定的行加任何鎖
select ... lock in share mode  #對讀取行加S鎖,其他事務允許加S鎖,但是如果是X鎖,則會阻塞

未完待續。。。。

2.2.4、自增長與鎖

2.2.5、外來鍵與鎖

 

三、鎖帶來的三個問題

四、鎖的演算法

五、鎖的其他狀態(阻塞,死