mysql的併發處理機制_下篇 mysql的併發處理機制_上篇

    MySQL的併發處理機制,有MVCC及鎖機制來處理,上篇簡要說明了 MVCC及隔離級別:mysql的併發處理機制_上篇 ,這篇來講說mysql下的鎖。html

    舒適提示:下文有幾個表格長度較長,右下角的博文導航目錄會擋道,瀏覽時,能夠點擊 導航目錄的左下角按鈕收縮目錄:
 


 
    若是轉載,請註明博文來源:  www.cnblogs.com/xinysu/   ,版權歸 博客園 蘇家小蘿蔔 全部。望各位支持!
 


 1 Innodb的鎖

    在innodb中,有4種類型的鎖:IX、X、IS及S鎖,其說明以下:
 
類型 說明 場景
S 共享鎖 針對於RS隔離級別的查詢或者添加Lock in share mode的SELECT查詢而產生的鎖
X 排它鎖 針對於update、delete、insert操做而產生的鎖
IS 意向共享鎖 表級別的鎖,在添加S鎖以前對錶格添加IS鎖
IX 意向排他鎖 表級別的鎖,在添加X鎖以前對錶格添加IX鎖

1.1 鎖定兼容狀況

  四個鎖之間的兼容性,須要分紅兩種狀況來討論,鎖粒度小於表級別的鎖的兼容狀況,表級的鎖兼容狀況。
  1. 鎖粒度小於表級別的鎖的兼容狀況
    • 對於這兩行鎖的兼容說明以下:
      • 假設有一行數據,添加了行鎖S鎖,那麼這個行數據,能夠提供給其餘事務進行S鎖的申請和添加,可是不支持其餘事務對這一行進行X鎖的申請和添加。好比,事務A,對 pk100 這一行進行了 查詢操做並添加了S鎖,那麼其餘事務仍然能夠對這一行數據進行查詢,可是不能對這行數據進行 UPDATE 跟 DELETE 操做,會處於鎖等待狀況,直到該事務A結束並釋放S鎖;
      • 假設有一行數據,添加了X鎖,那麼這個行數據,不容許其餘事務對這一行數據進行加鎖。好比,事務A,對pk100這一行進行了UPDATE操做,那麼其餘事務在事務A沒有結束以前,都沒法對這一行數據申請 S鎖。
  2. 表級的鎖兼容狀況
    • 對於表級別的鎖兼容性以下:
      • 當一個表格持有S表鎖時,不須要其餘事務對該表格申請X鎖跟IX鎖,可是容許申請S跟IS鎖。好比,事務A對錶格tba全表讀,加了S表鎖,期間支持其餘事務對tba全表讀(申請S表鎖成功)、支持其餘事務對tba行數據查詢(申請IS表鎖成功),可是不支持對錶格全表的修改操做(申請X表鎖等待)跟不支持對錶格行數據修改操做(申請IX表鎖等待);
      • 當一個表格持有X表鎖時,持有鎖期間,不支持其餘全部鎖的申請;
      • 當一個表格持有IS表鎖時,容許申請 S表鎖、IS表鎖、IX表鎖,可是不支持X表鎖申請。
        • 好比,事務A對錶格tba 查詢了 id = 10(id爲主鍵)這一行數據,這個時候,表格tba持有IS表鎖,id = 10 這一行持有 S 行鎖,期間,支持其餘事務對 tba 全表查詢(申請表鎖S成功)或者 基於索引查找(申請表鎖IS成功)
        • 若是須要對行 id = 20 進行數據修改,則會先申請 tba 的表鎖 IX(申請成功),而後再申請id=20行鎖X (申請成功);若是須要對 id = 10 這一行數據進行修改,則會申請 tba的表鎖 IX(表鎖申請成功),而後申請 id = 10 的行鎖X(申請堵塞,由於 id = 10 正持有S鎖);
        • 若是須要對錶格進行全表修改,須要申請表鎖(X鎖),這個時候,IS鎖的優點來了,當查看錶格是否有其餘事務在訪問操做時,一看錶鎖IS就知道有其餘事務對錶格內部某些數據持有S鎖,而且尚未釋放,那麼這個時候,申請X鎖就會處於等待狀態,而不須要一行一行去查詢每一行數據有沒有被其餘事務持有鎖,能夠大規模的減小查詢 鎖申請狀況;
      • 當一個表格持有IX表鎖時,支持申請IS、IX表鎖,可是不兼容S、X表鎖。
        • 好比,事務A對錶格 tba 中 id=10 (id爲主鍵)進行進行 數據修改,這個時候,會對錶格 tba 先申請一個 IX 表鎖(申請成功),而後申請 id =10 的 X 行鎖,申請成功,則 事務A 持有 IX 表鎖、id=10的X 行鎖,此時事務B 查詢 id=20的行,申請表鎖 IS 成功,申請 id=20的 S 行鎖成功;事務C 修改 id=30的行數據,申請表鎖 IX 成功,申請 id=30的行鎖 X成功;可是,事務D中,對整個表格發起update或者全表SELECT操做,須要申請 X表鎖或者S表鎖,正常狀況下,應該要對錶格的每一行數據進行查看,確保每一行數據的行鎖狀況,可是由於有了意向鎖,事務D一看到 tba 持有 了IX鎖,則明白,tba 中某些行持有X鎖,則會不兼容其餘事務對tba 表鎖S ,表鎖X的申請。
    • 爲何要引入意向表鎖?
      • 在沒有意向鎖的時候,若是事務T 須要給表格 A 添加 一個S 表鎖,那麼就意味這這個表格內部的每一行數據,都不能有X鎖,纔可以申請 S 表鎖成功,若是表格數據不少,一行行查找很是浪費加鎖時間,這個時候,就出現了表格意向鎖,當表格內部某些行發生 UPATE DELETE INSERT操做,則會對錶格 加上 一個意向 IX 表鎖,這樣 事務T在申請 表格A的 S 表鎖時,只須要檢查 表格 A 是否有 IX表鎖,若是有,則意味內部有 部分行數據持有X鎖,則直接進入等待狀況,若是表格沒有 IX表鎖,則直接申請S表鎖成功,這是一個多麼節約加鎖時間的操做!

1.2 鎖的級別

  • Table Lock
    • 表鎖,若是沒有where條件、無可用索引或者獲取的行記錄過多,則會使用 table full scan,添加表鎖
  • Record Lock
    • 記錄鎖,若是執行計劃使用了索引,則會根據索引的查找狀況添加行鎖
  • Gap Lock
    • 在RR、RS隔離級別,發生在索引值之間,在連續的兩個索引值之間添加鎖,加鎖後,這兩個索引值之間,沒法插入新的索引值,不包含行記錄
  • Next-Key Lock
    • Record Lock 跟Gap Lock的組合,合體成爲Next-KEY Lock
 
      表鎖、行鎖都相對好理解,這裏嘗試簡單說明下 GAP LOCK。
      假設當前隔離級別爲RR,表格 tbgap( id int auto_increment primary key not null , name varchar(50) , sort int , key ix_sort (sort)) engine=innodb; 
      表格數據以下:
      
      在索引ix_sort上,一共有7個間隙,分別爲(-∞,(1,6)),((1,6),(2,5)),((2,5),(3,2)),((3,2),(5,4)),((5,4),(6,1)),((6,1),(7,3)),((7,3),+∞),而根據實際的隔離級別及鎖申請狀況,加在這些間隙上的鎖,則成爲 GAP LOCK 。   

1.3 鎖與隔離級別(不考慮 lock in shar mode跟for update )

  • RU,讀未提交記錄,不加鎖讀,正常寫鎖;
  • RC,快照讀,無鎖;當前讀,加 Record Lock
  • RR,快照讀,無鎖;當前讀,對讀取到的記錄加 Record Lock,同時爲了確保where條件範圍內的數據無變化,會增長Next key lock
  • RS,讀寫均爲當前讀,不支持快照讀。包括select 在內,對讀取到的記錄加 Record Lock,同時爲了確保where條件範圍內的數據無變化,會增長Next key lock。

2 鎖的申請與釋放過程

      看SQL語句的鎖狀況,須要結合隔離級別、執行計劃、表結構等,同一個SQL,不一樣的隔離級別、表結構、執行計劃,其鎖狀況不必定是同樣的!
      本次模擬這3個表格,age列分別:無索引、有通常索引、有惟一索引。表結構結束及數據以下:
 
CREATE TABLE tb_no_index ( id int primary key not null auto_increment, age int not null, name varchar(100) );
CREATE TABLE tb_index ( id int primary key not null auto_increment, age int not null, name varchar(100) KEY ix_age(age) );
CREATE TABLE tb_unique_index ( id int primary key not null auto_increment, age int not null,name varchar(100) UNIQUE KEY ix_age(age) );
 
INSERT INTO tb_no_index(age) values(2),(9),(21),(4),(7),(25);
INSERT INTO tb_index(age) values(2),(9),(21),(4),(7),(25);
INSERT INTO tb_unique_index(age) values(2),(9),(21),(4),(7),(25);
  
每一個表格IX_age的索引行數就據以下圖展現:
age
2
4
7
9
21
25
id
1
4
5
2
3
6
 
每一個表格主鍵上面的行數就據以下圖展現:
id
1
2
3
4
5
6
age
2
9
21
4
7
25
name
null
null
null
null
null
null
 

2.1 Read Uncommitted

     全部事務隔離級別設置: set session transaction isolation level read Uncommitted ;
     RU是讀未提交,不添加 LOCK IN SHARE MODE 跟 FOR UPDATE 的 SELECT 語句,均爲讀未提交,不加鎖,存在髒讀、不可重複讀及幻讀。
     全部UPDATE、DELETE、INSERT獲取當前讀記錄,加鎖。
  表格     SQL
select * from tbname
where age/id ...
update tbname set name=...
where id = 4
update tbname set name=...
where age = 21
update tbname set name=...
where age between 5 and 15
tb_no_index
讀不加鎖,讀未提交數據
可能有髒讀、不可重複讀及幻讀
當前讀,根據主鍵修改數據
tbname 加意向表鎖 IX
id=4 加 行鎖 X

 

 
 
表格的age列無索引,因此update過程當中,全表加X鎖
支持semi-constent-read,若是有其餘update語句修改其餘行不堵塞,可是不支持 select ... for update
同左
tb_index
表格的age列有索引,update過程當中
tb_index 加 表格意向鎖 IX
age索引上面,age=21 行添加行鎖 X
再在主鍵上,給id=3 這一行數據,添加行數 X
 

 

 
表格的age列有索引,update過程涉及age=7,9 兩行數據
tb_index 加表格意向鎖 IX
age索引上面,age=7,age=9 行添加行鎖 X
再在主鍵上,給id=2,id=5 這一行數據,添加行數 X
 

 

tb_unique_index
同上
同上
      

2.2 Read Committed

全部事務隔離級別設置: set session transaction isolation level read committed ;
     
     RC是讀已提交,不添加 LOCK IN SHARE MODE 跟 FOR UPDATE 的 SELECT 語句,均爲 快照讀,不加鎖,同個事務內讀取同一個版本的數據,可能非最新數據,可是不存在髒讀、不可重複讀及幻讀狀況。
     全部UPDATE、DELETE、INSERT獲取當前讀記錄,加鎖。
 
     下表中,黃綠色 字體 是RC與RU隔離級別不一樣的地方,仔細閱讀分析結果能夠知道,在 RU 跟 RC 間,最大的區別在於 SELECT 的查詢模式,RU 爲 讀未提交,而 RC 爲快照讀。UPATE/DELETE/INSERT的加鎖模式類同。
   表格
             SQL
select * from tbname
where age/id ...
update tbname set name=...
where id = 4
update tbname set name=...
where age = 21
update tbname set name=...
where age between 5 and 15
tb_no_index
快照讀,不加鎖
讀取的數據不必定是最新版本,可是事務內的全部查詢讀取數據都是同一版本的行數據,不存在髒讀、不可重複讀及幻讀的狀況
當前讀,根據主鍵修改數據
tbname 加意向表鎖 IX
id=4 加 行鎖 X

 

 

表格的age列無索引,因此update過程當中,全表加X鎖
支持semi-constent-read,若是有其餘update語句修改其餘行不堵塞,可是不支持 select ... for update
同左
tb_index
表格的age列有索引,update過程當中
tb_index 加 表格意向鎖 IX
age索引上面,age=21 行添加行鎖 X
再在主鍵上,給id=3 這一行數據,添加行數 X
 
表格的age列有索引,update過程涉及age=7,9 兩行數據
tb_index 加表格意向鎖 IX
age索引上面,age=7,age=9 行添加行鎖 X
再在主鍵上,給id=2,id=5 這一行數據,添加行數 X
 
 
tb_unique_index
同上
同上
 
 

2.3 Read Repeatable

全部事務隔離級別設置: set session transaction isolation level repeatable read ;
 
       RR隔離級別中,SELECT操做支持快照讀,全部的UPDATE/DELETE/INSERT加鎖,鎖類型會新增一個GAP LOCK。
   表格     SQL
select * from tbname
where age/id ...
update tbname set name=...
where id = 4
update tbname set name=...
where age = 21
update tbname set name=...
where age between 5 and 15
tb_no_index
快照讀,不加鎖
讀取的數據不必定是最新版本,可是事務內的全部查詢讀取數據都是同一版本的行數據,不存在髒讀、不可重複讀及幻讀的狀況
當前讀,根據主鍵修改數據
tbname 加意向表鎖 IX
id=4 加 行鎖 X

 

 

表格的age列無索引,因此update過程當中
全表加X鎖,期間全表堵塞UPDATE\DELETE\INSERT
同左
tb_index
表格的age列有索引,update過程當中
tb_index 加 表格意向鎖 IX
age索引上面,age=21 行添加行鎖 X
再在主鍵上,給id=3 這一行數據,添加行數 X
 
你覺得結束了!並無,這裏有趣了!
還會添加兩個gap lock ((9,2) ,(21,3)),((21,3), (21,25))
 
這裏咱們單獨拎出小表格來分析。

 

表格的age列有索引,update過程涉及age=7,9 兩行數據
tb_index 加表格意向鎖 IX
age索引上面,age=7,age=9 行添加行鎖 X
再在主鍵上,給id=2,id=5 這一行數據,添加行數 X
同時會在索引 age的值上添加 3個 gap lock,分別爲 
((4,4),(7,5))、((7,5),(9,2))、((9,2),(21,3))
 

 

tb_unique_index
覺得跟上面的加鎖範圍同樣,no no no
惟一索引列上 每個age都是惟一的,也就是age=21只有一個,不會再INSERT一個新的 age =21進來,故在這裏不須要加gap lock,加鎖狀況以下:
tb_index 加 表格意向鎖 IX
age=21 行添加行鎖 X 
age索引上面,age=21 行添加行鎖 X
再在主鍵上,給id=3 這一行數據,添加行數 X
表格的age列有索引,update過程涉及age=7,9 兩行數據
tb_index 加表格意向鎖 IX
age索引上面,age=7,age=9 行添加行鎖 X
再在主鍵上,給id=2,id=5 這一行數據,添加行數 X
同時會在索引 age的值上添加 3個 gap lock,分別爲 
((4,4),(7,5))、((7,5),(9,2))、((9,2),(21,3))
可是,範圍查詢添加到gap lock在其餘狀況下跟非惟一索引會有一些差異,能夠看下錶的例子。
 
這裏作亮點補充說明:
 

2.3.1 RR下的非惟一索引加鎖狀況

       update tbname set name=...  where age = 21
        
      還記得上篇文章說過 RR隔離級別能夠防止 幻讀嗎?由於在RR隔離級別中,加多了next-key = record lock + gap lock,gap lock是加在索引值之間的鎖。也就是 當修改 age=21 的行數據時,除了 在 age=21 這一行添加 X record lock , 還在 ((9,2) ,(21,3)),((21,3), (21,25))這兩個age值得範圍內添加 gap lock。加鎖的狀況是:tb_index添加 IX意向鎖,age索引上添加age=21的 x record lock,再在主鍵上的行記錄 id=5 添加 X record lock,同時在 age 值上添加兩個 gap lock,分別爲((9,2) ,(21,3)),((21,3), (21,25))。
     注意這裏有個誤區,不少小夥伴會認爲,那麼這麼加gap鎖,則意味着,當update age=21這一列時, 9<age<25 ,這個範圍內,是不容許進行 UPATE/DELETE/INSERT的。這種推測其實是不完整的,由於它沒考慮到跟主鍵!!!
 
     注意,每次寫gap lock的時候,都是有加上主鍵值的。好比這裏,當更新 age=21這列時,加了 ((9,2) ,(21,3)),((21,3), (21,25)) 這兩個範圍的 GAP LOCK,那麼在當前update age=21的事務尚未結束的狀況下,假設有兩條修改SQL的語句:
update tbname set age=9 where id = 1;
update tbname set age=9 where age = 4;
 
    這兩條SQL,是可以正常執行,仍是堵塞呢?
    innodb中,索引按照二叉樹排列順序,而這兩條SQL修改後在IX_AGE上的索引值分別爲:(9,1)、(9,4),能夠發現(9,1)在鍵值(9,2)的左邊,不在GAP LOCK的範圍內,因此,能夠正常執行;而(9,4)在鍵值的右邊,恰好在GAP LOCK的範圍內,會被堵塞!總結:第一條UPDATE SQL,正常秩序;第二條UPDATE SQL會被堵塞。
 
    因此,考慮GAP LOCK的時候,必定要注意結合整個索引鍵值來分析,而索引鍵值=索引值+主鍵。

2.3.2 RR下的惟一索引加鎖狀況

       update tbname set name=...  where age between .. and ... 
 
      由於惟一索引上面的索引鍵值都是惟一的,故不會出現重複值的插入的狀況,下表羅列了一樣的 範圍查詢修改語句,在惟一索引及非惟一索引上加 GAP_LOCK的狀況。
      表格數據以下:
 
      
 
      加GAP_LOCK的狀況以下(注意注意,方便查看,省略了主鍵值,其實是須要添加上主鍵鍵值的):      
 
update tbname set name=...
where age between 1 and 7
update tbname set name=...
where age between 2 and 7
update tbname set name=...
where age between 5 and 10
update tbname set name=...
where age between 15 and 50
tb_index
(-∞,2),(2,4),(4,7),(7,9)
(-∞,2),(2,4),(4,7),(7,9)
(4,7),(7,9),(9,21)
(9,21),(21,25),(25,+∞)
tb_unique_index
(-∞,2),(2,4),(4,7)
(2,4),(4,7)
(4,7),(7,9),(9,21)
(9,21),(21,25),(25,+∞)
 

2.4 Read Serializable

全部事務隔離級別設置: set session transaction isolation level  Serializable   ;
   表格     SQL
select * from tbname
where age/id ...
update tbname set name=...
where id = 4
update tbname set name=...
where age = 21
update tbname set name=...
where age between 5 and 15
tb_no_index
不支持快照讀,全部SELECT都是當前讀,全部SELECT操做都須要加S鎖,除主鍵定值查找\惟一索引定值查找外,其餘基於索引或者主鍵的範圍查找都會添加 S GAP LOCK。併發度是四個隔離級別中性能最差的。
當前讀,根據主鍵修改數據
tbname 加意向表鎖 IX
id=4 加 行鎖 X
表格的age列無索引,因此update過程當中
全表加X鎖,期間全表堵塞UPDATE\DELETE\INSERT
同左
tb_index
表格的age列有索引,update過程當中
tb_index 加 表格意向鎖 IX
age索引上面,age=21 行添加行鎖 X
再在主鍵上,給id=3 這一行數據,添加行數 X
在age索引上 添加兩個gap lock ((9,2) ,(21,3)),((21,3), (21,25))
表格的age列有索引,update過程涉及age=7,9 兩行數據
tb_index 加表格意向鎖 IX
age索引上面,age=7,age=9 行添加行鎖 X
再在主鍵上,給id=2,id=5 這一行數據,添加行數 X
同時會在索引 age的值上添加 3個 gap lock,分別爲
((4,4),(7,5))、((7,5),(9,2))、((9,2),(21,3))
tb_unique_index
惟一索引列上 每個age都是惟一的,也就是age=21只有一個,不會再INSERT一個新的 age =21進來,故在這裏不須要加gap lock,加鎖狀況以下:
tb_index 加 表格意向鎖 IX
age=21 行添加行鎖 X 
表格的age列有索引,update過程涉及age=7,9 兩行數據
tb_index 加表格意向鎖 IX
age索引上面,age=7,age=9 行添加行鎖 X
再在主鍵上,給id=2,id=5 這一行數據,添加行數 X
同時會在索引 age的值上添加 3個 gap lock,分別爲 
((4,4),(7,5))、((7,5),(9,2))、((9,2),(21,3))
可是,範圍查詢添加到gap lock在其餘狀況下跟非惟一索引會有一些差異,能夠看下錶的例子。
 
 
    這裏詳細的來分析下 RS 隔離級別下的SELECT操做加的鎖:
     

 

表格     SQL
select * from tbname
where id=5
select * from tbname
where id betwee 5 and 15
select * from tbname
where age=21
select * from tbname
where age betwee 5 and 9
tb_no_index
主鍵定值查找
表格tbname 添加 IS 意向鎖
id=5 添加 S鎖
主鍵範圍查找
表格tbname 添加 IS 意向鎖
id=5,id=6 兩行數據 添加 S鎖
同時添加2個 S GAP LOCK ,分別爲 ((5,7),(6,25))跟((6,25),+∞)
全表查找
表格 tbname 添加 IS 意向鎖
因爲全表查找,整個表格 再次添加 S 表鎖
全表查找
表格 tbname 添加 IS 意向鎖
因爲全表查找,整個表格 再次添加S 表鎖
tb_index
ix_age索引查找
表格tbname 添加 IS 意向鎖
索引上 age = 21 添加 S 行鎖
主鍵上 id=3 添加 S 行鎖
同時添加 2個  S GAP LOCK ,分別爲 ((9,2) ,(21,3)),((21,3), (21,25))
ix_age索引查找
表格tbname 添加 IS 意向鎖
age索引上面,age=7,age=9 行添加行鎖 S
再在主鍵上,給id=2,id=5 這一行數據,添加行數 S
同時會在索引 age的值上添加 3個 S gap lock,分別爲
((4,4),(7,5))、((7,5),(9,2))、((9,2),(21,3))
tb_unique_index
ix_age索引查找
表格tbname 添加 IS 意向鎖
索引上 age = 21 添加 S 行鎖
主鍵上 id=3 添加 S 行鎖
因爲age列惟一,故不須要添加GAP LOCK
ix_age索引查找
表格tbname 添加 IS 意向鎖
age索引上面,age=7,age=9 行添加行鎖 S
再在主鍵上,給id=2,id=5 這一行數據,添加行數 S
同時會在索引 age的值上添加  2 個 S gap lock,分別爲
((4,4),(7,5))、((7,5),(9,2))
 
   至此,已說明了四個隔離級別是如何加鎖,那麼,釋放鎖呢?
 
   在MySQL INNODB中,遵循的是 strong strict 2-PL,也就是全部的write lock 跟read lock 都是在 事務 commit後才釋放。

3 SQL分析

     考慮到下文的例子,這裏補充兩個概念。
     ICP:
     MRR:
      
     假設表格 tb_lock ( id int primary key not null, age int,score int,name varchar(10), key ix_age_score ( age, score ) ) 數據修改以下 :
      
 
      假設MySQL當前的隔離級別爲 RR,執行 UPDATE tb_index WHERE age between 5 and 22 and score between 1 and 10 and name is not null,其執行計劃以下:
      
      那麼,是如何加鎖的呢?
      首先,能夠看到是根據索引 ix_age_score 查找,那麼分爲兩種狀況來分析,第一種,數據庫支持ICP;第二種,數據不支持ICP。

3.1 支持ICP狀況

       當數據庫支持ICP的時候,根據複合索引第一列 age 查找 age between 5 and 22,而後在索引內部過濾 score between 1 and 10後,取得索引值後,若是數據庫支持 MRR,則會把取得的索引值放到buffer中,對主鍵進行排序,而後能夠根據順序的主鍵值去 主鍵中查找行數據,若是不支持,則跳過這一步排序步驟,直接根據索引值內部的主鍵值,查找主鍵行數,最後過濾 name is not null 。
    
      加鎖過程以下,tb_lock添加 IX 意向鎖,在索引  ix_age_score 給索引值(7,10,5),(21,4,3)添加上 X record lock,並添加4個 X GAP LOCK,如圖片紅色素箭頭展現,分別爲((4,7,4), (7,10,5)),((7,10,5), (9,15,2)),((9,15,2),(21,4,3)),((21,4,3),(25,1,6)),最後在主鍵上給id=3及id=5 兩行數就添加X record lock。

3.2 不支持ICP狀況

      當數據庫不支持ICP的時候,根據複合索引第一列 age 選擇 age between 5 and 22,而後根據篩選的索引值 (7,10,5),(9,15,2),(21,4,3)中的主鍵 五、二、3,找到對應的行數據,再在行數據中 過濾 score between 1 and 10 and name is not null。
    
      加鎖過程以下,tb_lock添加 IX 意向鎖,在索引  ix_age_score 給索引值(7,10,5),(9,15,2),(21,4,3)添加上 X record lock,並添加4個 X GAP LOCK,如圖片紅色素箭頭展現,分別爲((4,7,4), (7,10,5)),((7,10,5), (9,15,2)),((9,15,2),(21,4,3)),((21,4,3),(25,1,6)),最後在主鍵上給id=二、id=三、id=5 兩行數就添加X record lock。
 
參考文檔:http://hedengcheng.com/?p=771#_Toc374698321
相關文章
相關標籤/搜索