1. 程式人生 > >Mysql研磨之InnoDB行鎖模式

Mysql研磨之InnoDB行鎖模式

事務併發帶來的一些問題

(1)更新丟失(LostUpdate):當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題最後的更新覆蓋了由其他事務所做的更新

(2)髒讀(Dirty Reads):一個事務正在對一條記錄做修改,在這個事務完成並且提交前,這條記錄的資料就處於不一致狀態;這時,另一個事務也來讀取這一條記錄,如果不加控制,第二個事務讀取了這些髒資料,並據此做進一步的處理,就會產生未提交的資料依賴關係,這種形象的叫做髒讀

(3)不可重複讀(Non-Respeatable Reads):一個事務在讀取某些資料後的某個時間,再次獨缺以前讀過的資料,卻發現其讀出的資料已經發生了改變或某些記錄已經被刪除了,這種現象就叫做不可重複讀

(4)幻讀(Phantom Reads):一個事務按相同的查詢條件重新讀取以前檢索過的資料,卻發現其他事務插入了滿足其查詢條件的新資料,這種現象就稱為幻讀

一、InnoDB的行鎖模式和加鎖方法

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖粒度大,發生鎖衝突的概率最高,併發度低

行級鎖:開銷大,加鎖慢;會出現死鎖;鎖粒度最小,發生鎖衝突的概率最低,併發度也最高

頁面鎖:開銷和枷鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖粒度界於表鎖和行鎖之間,併發度一般

InnoDB支援表鎖和行鎖,預設情況下是採用行級鎖

InnoDB實現了兩種型別的行鎖

  1、共享鎖(S):允許一個事物去讀一行,阻止其他事物獲得相同資料集的排他鎖

  2、排他鎖(X):允許獲得排他鎖的事物更新資料,阻止其他事物取得相同資料集的共享讀鎖和排他寫鎖

換一種說法

  共享鎖【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鎖。

如果一個事物請求的鎖模式和當前鎖相容,則InnoDB就將請求的鎖授予該事物,反之如果兩者不相容,該事物就要等待鎖釋放。

  意向鎖是InnoDB自動加的,不需使用者干預。對update、delete、insert語句,innoDB會自動給涉及資料集加排他鎖;對於普通的select語句,InnoDB不會加任何鎖;但是事物可以通過以下語句顯示給記錄集加共享鎖和排他鎖 

  顯示共享鎖 

select * from brand where brand_code = '00AG' LOCK IN SHARE MODE

   顯示排他鎖

select * from brand where brand_code = '00AG' FOR UPDATE

二、InnoDB行鎖實現方式

  Innodb行鎖是通過給索引上的索引項加鎖實現的,如果沒有索引,InnoDB將通過隱藏的聚簇索引來對記錄加鎖

  InnoDB行鎖分為三種方式:

  Record lock:對索引項加鎖

  Gap lock:對索引項之間的間隙、第一條記錄前的間隙或最後一條記錄後的間隙加鎖

  Next-key lock:前兩種的組合,對記錄及前面的間隙加鎖

InnoDB行鎖實現特點意味著:如果不通過索引條件檢索資料,那麼InnoDB將對錶中的所有記錄加鎖,實際效果根表鎖一樣

  1、在不通過索引條件查詢時,InnoDB會鎖定表中所有記錄

  2、由於Mysql行鎖是針對索引加的鎖,不是針對記錄加的鎖,所以雖然是訪問不同行的記錄,但是如果是使用相同的索引鍵,是會出現鎖衝突的

  3、當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,不論是使用主鍵索引、唯一索引或普通索引,InnoDB都會使用行鎖來對資料加鎖

  4、有時候雖然在條件中使用了索引欄位,但是是否使用索引來檢查資料是由Mysq通過判斷不同的執行計劃來決定的,如果Mysql認為全表掃描效率更高,比如對一些很小的表,它就不會使用索引。這個時候Mysql將會使用表鎖,不會使用行鎖。所以在分析鎖衝突的時候不要遺漏了用EXPLAIN觀察Mysql執行計劃,是否走了索引

三、Next-key鎖

  當我們用範圍條件而不是相等條件檢索資料,並請求共享鎖或排他鎖時候,InnoDB會給符合條件的已有資料的索引項加鎖;對於鍵值在條件範圍內但是並不存在的記錄,叫做間隙(GAP),InnoDB也會對間隙加鎖,這種機制就是Next-Key。除了對範圍條件加鎖時候加鎖使用Next-key鎖,對不存在的記錄加鎖,也會使用Next-key鎖

select * from brand where id>100 FOR UPDATE

  InnoDB對間隙加鎖的目的,是為了防止幻讀。比如說針對於上面的SQL,如果這個時候別的事務插入了大於100的任何記錄,那麼本次事務如果再次執行上述語句,就會發生幻讀。

  InnoDB這種機制會阻塞符合條件範圍內鍵值的併發插入,這往往會造成嚴重的鎖等待。

 四、InnoDB表鎖

  在InnoDB表,絕大多數情況都應該使用行級鎖,因為事務和行鎖往往是我們選擇InnoDB表的理由。但是在某些情況下也需要使用表級鎖

  1、事務需要更新大部分或全部資料,表又比較大,如果使用預設的行鎖,不僅這個事務執行效率低,而且可能造成其他事務長時間鎖等待和鎖衝突,這種情況下考慮使用表鎖來提高該事務的執行速度

  2、事務設計多個表,比較複雜,很可能引起死鎖,造成大量事務回滾。這種情況可以考慮一次性鎖定事務設計的表,從而避免死鎖,減少資料庫因事務回滾帶來的開銷

死鎖:

  1、在應用中,如果不同的程式會併發存取多個表,應儘量約定以相同的順序來訪問表,這樣可以大大降低產生死鎖的機會

  2、在程式以批量方式處理資料的時候,如果事先對資料排序,保證對每個執行緒按固定的順序來處理記錄,也可以大大降低出現死鎖的問題

  3、在事務中,如果要更新記錄,應該直接申請足夠級別的鎖,即排他鎖,而不應先申請共享鎖,更新時在申請排他鎖,因為當用於申請排他鎖時,其他事務可能又已經獲得了相同記錄的共享鎖,從而造成鎖衝突,甚至死鎖

  4、

相關推薦

Mysql研磨InnoDB模式

事務併發帶來的一些問題 (1)更新丟失(LostUpdate):當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題最後的更新覆蓋了由其他事務所做的更新 (2)髒讀(Dirty Reads):一個事務正在對一條記錄做修改,在這個事務完成並且提交前

MySQL探祕(七):InnoDB演算法

 在上一篇《InnoDB一致性非鎖定讀》中,我們瞭解到InnoDB使用一致性非鎖定讀來避免在一般的查詢操作(SELECT FOR UPDATE等除外)時使用鎖。然而鎖這個事情是無法避免的,資料的寫入,修改和刪除都需要加鎖。今天我們就繼續學習InnoDB鎖相關的知識。  由於文章涉及的概念比較多,害怕大家看完

mysqlInnoDB的一點反思

行鎖 解決 統計 發現 今天 int 運營 innodb 應用場景 剛參加工作時,遇到的mysql死鎖的問題。具體情況如下: 網頁有個統計訪問次數功能,然後這個次數num是int類型,網頁每次被訪問一次就增1,然後運營在跑批量任務的時候,造成數據量這個字段死鎖

Mysql MyISAM與InnoDB以及分庫分表優化

搜索 ash 能力 缺點 外部 加鎖 結構 create 主從 一、 兩種存儲引擎:MyISAM與InnoDB 區別與作用 1. count運算上的區別: 因為MyISAM緩存有表meta-data(行數等),因此在做COUNT(*)時對於一個結構很好的查詢是不需要消耗多少

Mysql InnoDB實現方式

Mysql InnoDB行鎖實現方式   InnoDB行鎖是通過給索引上的索引項加鎖來實現的,這一點MySQL與Oracle不同,後者是通過在資料塊中對相應資料行加鎖來實現的。InnoDB這種行鎖實現特點意味著:只有通過索引條件檢索資料,InnoDB

InnoDB模式及加方法

InnoDB 實現了以下兩種型別的行鎖。  共享鎖(S):允許一個事務去讀一行,阻止其他事務獲得相同資料集的排他鎖。  排他鎖(X):允許獲得排他鎖的事務更新資料,阻止其他事務取得相同資料集的共享 讀鎖和排他寫鎖。 另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制,InnoDB 還有兩種內部使用的

InnoDB模式及加方法

InnoDB實現了以下兩種型別的行鎖。 l  共享鎖(S):允許一個事務去讀一行,阻止其他事務獲得相同資料集的排他鎖。 l  排他鎖(X):允許獲得排他鎖的事務更新資料,阻止其他事務取得相同資料集的共享讀鎖和排他寫鎖。 另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制,Inno

mysql innodb

共享鎖 S 允許一個事務去讀取一個行,阻止其他事務獲取相同資料集的排它鎖 排它鎖 X 允許獲得排它鎖的事務更新資料,阻止其他事務獲取相同資料集的共享鎖和排他鎖 mysql InnoDB引擎預設的修改資料語句,update,delete,insert都會自動給涉及到的資料加上

MySQL系列-innoDB詳解

一直都很想討論一下innoDB的行鎖,但是看到了何登成大神的部落格之後發現他的研究更深入說的更好,是一篇非常優秀的部落格,但是需要對索引有比較深入的瞭解,因此看他的部落格之前可以先看看我的一篇關於索引的文章MySQL系列-B+Tree索引詳解。同時也深感資料庫易學難精,一條S

Mysql InnoDB 和表介紹

  mysql 的 InnoDB引擎支援行鎖,與Oracle不同,mysql的行鎖是通過索引載入的,即是行鎖是

MySQLInnoDB需要避免的坑

  前言   換了工作之後,接近半年沒有發部落格了(一直加班),emmmm.....今天好不容易有時間,記錄下工作中遇到的一些問題,接下來應該重拾知識點了。因為新公司工作中MySQL庫經常出現查詢慢,鎖等待,節點掛掉........等一系列問題。導致每個程式設計師頭都很大,一味抱怨“為什麼我就查一

MySQL:03.InnoDB

[ 傳送門:MySQL鎖:01.總覽 ](https://www.cnblogs.com/konggg/p/14133916.html) [ 傳送門:MySQL鎖:02.InnoDB鎖 ](https://www.cnblogs.com/konggg/p/14134036.html) [ 傳送門:MySQL鎖

SQLServer資料庫

行鎖使用注意事項 1、ROWLOCK行級鎖確保在使用者取得被更新的行,到該行進行更新,這段時間內不被其它使用者所修改。因而行級鎖即可保證資料的一致性,又能提高資料操作的併發性。 2、ROWLOCK告訴SQL Server只使用行級鎖,ROWLOCK語法可以使用在SELECT,UPDATE和DELETE語句

MySQL · 引擎特性 · InnoDB 事務系統簡介(下)

 一 序    本文接上一篇介紹鎖型別之後。主要分為 兩部分。第一部分介紹表鎖行鎖加鎖流程。第二部分常見的死鎖檢測。    InnoDB 所有的事務鎖物件都是掛在全域性物件lock_sys上,同時每個事務物件上也維持了其擁有的事務鎖,每個表物件(dict_table_t)

Mysql研磨設計索引原則

1、搜尋的索引列:最適合索引的列是出現在where子句中的列,或連結子句中指定的列,而不是出現在select關鍵詞後的選擇列表中的列 2、使用唯一索引:考慮列中值的分佈。索引的列基礎越大,索引的效果越好。列如記錄性別的列,不管搜尋那個性別,都會得出大約一般的行,因此對此列索引沒有太大的作用 3、使用短索引:如

InnoDB機制(gap是如何阻塞插入操作的)

文章目錄 InnoDB行鎖機制(gap鎖是如何阻塞插入操作的) 一、假設場景 二、加鎖過程分析 InnoDB行鎖機制(gap鎖是如何阻塞插入操作的) InnoDB 在執行insert操作時,並不會顯示加鎖,如果是

Mysql中那些機制InnoDB

插入記錄 都在 讀一行 利用 分數 .net new 第二版 delet 我們知道mysql在曾經。存儲引擎默認是MyISAM。可是隨著對事務和並發的要求越來越高,便引入了InnoDB引擎。它具有支持事務安全等一系列特性。 InnoDB鎖模式 InnoDB實現了兩種

mysqlInnoDB存儲引擎的和表

nbsp 大於 依然 自帶 打折 一個 系統 指定 任務 Mysql的InnoDB存儲引擎支持事務,默認是行鎖。因為這個特性,所以數據庫支持高並發,但是如果InnoDB更新數據的時候不是行鎖,而是表鎖的話,那麽其並發性會大打折扣,而且也可能導致你的程序出錯。 而導致行鎖變為

InnoDB事務-delete的update階段加流程圖

事務 技術分享 image 流程圖 fff shadow text src pro InnoDB事務鎖之行鎖-delete的update階段加鎖流程圖