[mysql] 鎖機制

前言

  在計算機的世界裏鎖(lock)是爲了協調多個進程或者多個線程併發的訪問同一資源而被創造出來的。而在咱們的mysql數據庫中的鎖也是爲了解決併發訪問同一資源的問題,下面我就來介紹下mysql中的鎖的一些知識,若是有什麼說的不對的地方,還但願各位大神指正。mysql

 

 鎖的種類

  在mysql數據庫中,能夠將鎖分爲3個種類: 表級鎖 、 行級鎖 、 頁級鎖 。sql

表級鎖

定義:對整個表進行加鎖處理,在你鎖按期間,若是你是讀鎖,其餘進程寫操做沒法對這張表進行操做。若是你是寫鎖,則其餘進程沒法對這張表進行操做。數據庫

引擎: MyISAM , InnoDB 併發

優勢: 加鎖快 、 開銷小 、 不會出現死鎖 spa

缺點: 鎖定面積大 、 發生衝突的機率高 、 併發度低 線程

表級鎖模式

  •  表共享讀鎖 :當一個進程對一張表加了讀鎖,那麼其餘的進程也能夠同時對這張表加讀鎖,可是不能加寫鎖。(即多個用戶能夠同時讀取同一張表的數據)
  •  表獨佔寫鎖 :當一個進程對一張表加了寫鎖,那麼其餘任何進程都不能夠加任何鎖。

如何添加表級鎖

lock tables table_name1 read local,table_name2 read local;
select * from table_name1;
select * from table_name2;
lock tables;

 

注意:code

  •  local 選項,做用是在知足MyISAM表併發插入條件的狀況下,容許其餘用戶在表尾插入記錄。
  • 在使用 lock tables 給表顯示加鎖後,你只能訪問顯示加鎖的那幾張表,不能訪問未加鎖的表。
  • 在使用 lock tables 給表顯示加鎖後,mysql是一次性加上你想加鎖表的全部表的鎖,這就保證了不會產生死鎖。

MyISAM的鎖

併發鎖

MyISAM存儲引擎中有一個系統變量 concurrent_insert ,這個變量能夠控制併發插入的行爲,容許的值爲(0、一、2)。blog

  • 當 concurrent_insert=0 時,不容許併發插入。
  • 當 concurrent_insert=1 時,當一個進程在讀一張表時,通知能夠容許一個進程向該表中插入數據。(默認設置)
  • 當 concurrent_insert=2 時,不管MyISAM表中有沒有空洞,都容許在表尾併發插入記錄。

MyISAM鎖調度

對於MyISAM的鎖調度,咱們須要注意的是:索引

  • 寫進程老是幣讀進程先得到鎖,即便是讀進程先到達等待隊列,寫進程後到達,以後mysql也會先調度寫進程。

優勢:由於MyISAM是共享讀鎖的,先執行寫進程,可讓讀進程積累到必定程度,一塊兒讀取數據,能夠增長併發度隊列

缺點:若是寫進程過多,那麼會形成讀進程一致沒法執行,致使等待時間過長

能夠經過如下幾種方法解決讀進程等待時間過長的問題:

  • 修改優先級
SET LOW_PRIORITY_UPDATES=1;
SET LOW_PRIORITY_INSERT=1;
SET LOW_PRIORITY_DELETE=1;
  • 設置 max_write_lock_count 參數,當一個表的讀鎖達到這個值後,MySQL變暫時將寫請求的優先級下降,給讀進程必定得到鎖的機會。
set max_write_lock_count=10;

 

 

 行級鎖

定義:對錶中的一行進行加鎖,其餘進程還能夠操做這張表的其餘行。

引擎: InnoDB 

優勢: 鎖定面積小 、 發生衝突的機率低 、 併發度高 

缺點: 加鎖慢 、 開銷大 、 會發生死鎖 

行級鎖模式

  •  共享鎖(s) :容許多個事務去讀同一行,當某個事務對該行加共享行鎖,則不容許其餘事務去加排它鎖。
  •  排它鎖(X) :當某個事務給某一行加了排它鎖,則不容許其餘事務給該行加任何鎖。
  •  意向共享鎖(IS :在加共享鎖前,首先須要在表上加該鎖。
  •  意向排他鎖(IX) :在加排它鎖前,首先須要在表上加該鎖。

注意如下幾點:

  • 意向鎖是InnoDB自動加的。
  • 對於 UPDATE 、 DELETE 、 INSERT 語句,InnoDB會自動加排它鎖。
  • 對於 SELECT 語句,InnoDB不會加任何鎖。能夠經過如下語句給記錄加共享鎖:
select * from table_name where id = xxx lock in share mode;

 

InnoDB的鎖

 行鎖實現方式

  InnoDB行鎖是經過索引上的索引項來實現的,只有經過索引條件檢索數據,InnoDB纔會使用行級鎖,不然,InnoDB將使用表鎖。

間隙鎖

  當咱們用範圍條件而不是相等條件檢索數據,並請求共享或排他鎖時,InnoDB會給符合條件的已有數據的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫作「間隙(GAP)」,InnoDB也會對這個「間隙」加鎖,這種鎖機制不是所謂的間隙鎖(Next-Key鎖)。

何時使用表級鎖

  1. 更新的行數是表的大部分數據或整張表時
  2. 事務涉及多個表,比較複雜,極可能引發死鎖,形成事務大量回滾。

在InnoDB下,使用表鎖要注意如下幾點:

  1. 可使用 lock tables 給InnoDB加表級鎖,可是這個表級鎖不是由InnoDB存儲引擎管理的,而是上一層的MySQL Server管理,而且只有知足 autocommit=0 和 innodb_table_lock=1 時,InnoDB層才能知道MySQL加的表鎖,MySQL Server才能感知InnoDB加的行鎖,這種狀況下,InnoDB才能自動識別涉及表級鎖的死鎖;不然,InnoDB將沒法自動檢測而且處理這種死鎖。
  2. 在用 lock tables 對InnoDB鎖時要注意,要將 autocommit 設置爲0,不然MySQL不會給表加鎖。

頁級鎖

定義:對錶中某行和相鄰行進行加鎖。這種作法是對錶級鎖和行級鎖的一中折中方案。

引擎:BDB

相關文章
相關標籤/搜索