1. 程式人生 > >[mysql掃盲]---()鎖相關

[mysql掃盲]---()鎖相關

Author:趙志乾
Date:2018-10-20
Declaration:All Right Reserved!!!

1、鎖機制

鎖機制主要用於併發操作,來保證資料的一致性,即使的共享資源在被併發訪問時,變得有序而強加的一種約束規則。mysql的鎖機制亦是如此,只不過它的鎖機制是由儲存引擎提供的。選擇不同的儲存引擎,其支援的鎖機制也不相同。比如:Innodb儲存引擎支援表級鎖和行級鎖,而MyISAM則只支援表級鎖。

表級鎖和行級鎖各有優缺點,要根據具體的應用場景進行選擇。其特點如下:
    表級鎖:其施加於資料庫表上,操作快、開銷小,但由於粒度較大,導致鎖衝突概率高,併發度相對較低。
    行級鎖:其施加於資料庫表的行記錄上,操作慢,開銷大,但由於粒度小,導致鎖衝突概率低,併發度相對較高。

2、鎖型別

Innodb作為mysql最常用的儲存引擎,其支援4種類型的鎖,包括:讀鎖(共享鎖)、寫鎖(排他鎖)、意向鎖和MDL鎖。

讀鎖又可成為共享鎖或者S鎖,其內含的約束規則為:如果事務A獲取了資料行IL的讀鎖,則事務B獲取資料行IL的讀鎖時,可以順利進行,即讀鎖可以被連續多次獲取,但如果事務B要獲取資料行IL的寫鎖時,將會被阻塞,直到資料行IL的寫鎖被釋放。共享鎖的優點就是能夠在保證資料併發訪問一致性的前提下,提升併發訪問效率。該優點在讀多寫少的場景下尤為突出。

讀鎖有兩種型別:
    1、自動提交模式下的select查詢語句,其本身是不加鎖的,屬於一致性非鎖定讀。
        select * from tbl_usr_info where usr_id=123;
    2、顯示加鎖,即通過下面的sql語句對被讀取的行記錄或行記錄集合加一個讀鎖。
        select * from tbl_usr_info where usr_id=123 lock in share mode;

寫鎖又可稱為排他鎖或者X鎖,其內含的約束規則為:如果事務A獲取了資料行IL的寫鎖,則事務B獲取資料行IL的其他鎖時,將會被阻塞。

寫鎖有兩種新增方式:
    1、對於增刪改的sql語句,其本身會自動對所操作的資料行新增寫鎖;
        update tbl_usr_info set usr_name="zhaozhiqian" where usr_id=1;
    2、對於select讀取的行記錄也可以新增讀鎖,其方式如下:
        select * from tbl_usr_info where usr_id=1 for update;

MDL鎖的全稱為meta data lock,其內含的約束規則為:會話A中,如果表T上開啟了查詢事務,其便會自動獲得該表的MDL鎖,則會話B中的事務在執行DDL語句操作時,便會被阻塞。該鎖型別主要是用於保證表中的元資料資訊的一致性。

意向鎖是一種表級鎖,其作用和MDL鎖類似,都是為了防止在事務執行過程中,其他事務因執行DDL語句而造成的資料不一致問題,且MDL鎖和意向鎖多是自動新增的,不需要手動控制。

意向鎖又可分為兩類:
    意向共享鎖(IS):在給一個數據行加共享鎖前必須先獲取該表的IS鎖;
    意向排他鎖(IX):在給一個數據行加排他鎖前必須先獲取該表的IX鎖;

3、鎖等待和死鎖

鎖等待是指事務A要獲取的鎖已經被事務B佔用,此時事務A的執行流程將阻塞,直至事務B釋放事務A所需的鎖或者出現鎖等待超時。其中鎖等待超時主要是為了避免事務長時間等待,其等待超時時間可在innodb_lock_wait_timeout中進行控制,單位為秒。

死鎖則是鎖等待中比較特殊的一種場景,即事務A和事務B相互等待被彼此佔用的鎖資源。Innodb儲存引擎能夠自動檢測死鎖,並在發生死鎖時,自動回滾事務。

實際應用中,通常採用以下4中方式來儘可能避免死鎖的發生:
    1、如果不同的應用程式會併發存取多個表,或者涉及多個行記錄時,應儘量約定以相同的順序訪問表,從而降低死鎖產生的機率。
    2、業務中儘量採用小事務、避免大事務,使得事務得以及時提交或回滾,從而降低死鎖機率。
    3、同一事務中,儘量做到一次鎖定所需要的所有資源,從而降低死鎖機率。
    4、對於極易產生死鎖的部分,可以嘗試提升鎖粒度,即通過表級鎖來降低死鎖機率。