MySQL加鎖分析 (轉)

參考:MySQL 加鎖處理分析。該文已經講的很詳盡了,也易懂,下面僅僅是我的作的總結。mysql

 

1、 背景

1.1 隔離級別

1.2 加鎖過程

  逐條處理,逐條加鎖。sql

update 執行流程

 

1.3 兩階段鎖2PL

1.4 gap鎖

  gap鎖是間隙鎖,即相鄰兩條有效記錄間隙的鎖(鎖的是間隙),它是針對insert的,用來解決幻讀的發生。它會阻塞insert,但不會阻塞delete/update等(記錄原本也不存在)。session

  RC與RR的重要區別就是幻讀。因此RR才須要引入gap鎖。post

 

2、加鎖組合分析

  說加什麼鎖,首先要了解兩個前提:1)隔離級別;2)用到的索引。不一樣的隔離級別,不一樣的索引都會影響加鎖。優化

2.1 可提交讀RC

 

  主鍵/惟一鍵 二級索引 無索引
select
insert 行鎖 行鎖 行鎖
select...for update/update/delete 行鎖 有效行的行鎖 全表鎖聚簇索引

2.2 可重複讀RR

 

  主鍵/惟一鍵 二級索引 無索引
select
insert 行鎖 行鎖 行鎖
select...for update/update/delete 行鎖 有效行的行鎖+gap鎖 全表鎖聚簇索引

2.3 可序列化S

  主鍵/惟一鍵 二級索引 無索引
select(快照讀) S S S
其餘(當前讀) X X X

 

  注意:無索引時,select...for update/update/delete是須要鎖全表的,但mysql_server能夠作優化,在逐條加鎖時,若是發現不是目標記錄,能夠釋放掉鎖。但這會違背2PL的原則。spa

2.4 結論

  死鎖的發生與否,並不在於事務中有多少條SQL語句,死鎖的關鍵在於:兩個(或以上)的Session加鎖的順序不一致。server

  加鎖過程是逐條處理,逐條加鎖(最終都反映在聚簇索引上)的。blog

  • 主鍵,加在聚簇索引上;
  • 二級索引,加在二級索引+聚簇索引上;
  • 無索引,加在聚簇索引上。

因此若是兩個session用到不一樣的二級索引,那麼對聚簇索引的加鎖順序是不一致的,從而致使session間鎖的持有與競爭,很容易產生死鎖。索引

 

  • 做者:水巖
  • 出處:http://www.cnblogs.com/waterystone
  • 本博客中未標明轉載的文章歸做者水巖和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索