譯文 InnoDB 的不同的SQL如何加鎖

2022-02-26 20:36:09 字數 2372 閱讀 5134

前置:檢索如果用不到索引,會掃瞄全表,並根據策略加鎖。所以,這就是我們合理建立索引的緣由。

鎖定讀、update、delete,在處理sql過程中, 一般會在每條掃瞄過的索引記錄上設定記錄鎖。語句中是否有where條件並沒有關係(會排除)。innodb不會記住實際上的where條件,但他知道被掃瞄過的索引範圍。使用的鎖通常是next-key鎖,也會鎖住記錄之前的「gap」。next-key鎖不僅僅鎖住掃瞄到的合法索引記錄,同時會阻塞插入gap間隙中,gap是指上一條合法索引記錄到當前掃瞄到的合法索引記錄的開區間。gap鎖可以被顯示的禁止,導致next-key不會被使用。

事物的隔離級別同樣會影響使用什麼鎖。

如果乙個二級索引被用來掃瞄,且索引記錄(二級索引,非唯一索引)將要加排他鎖,innodb會檢索相對應的聚簇索引記錄,並鎖住。

聚簇索引(clustered index)

1)  有主鍵時,根據主鍵建立聚簇索引

2)  沒有主鍵時,會用乙個唯一且不為空的索引列做為主鍵,成為此表的聚簇索引

3) 如果以上兩個都不滿足那innodb自己建立乙個虛擬的聚集索引

輔助索引(secondary index)

非聚簇索引都是輔助索引,像復合索引、字首索引、唯一索引

如果沒有合適的索引使用,mysql會掃面整張表,來處理語句,這樣表中的每一行都會被鎖住(合理建立索引,提高併發效率)。

對於select ... for updateorselect ... lock in share mode,掃瞄到的行都會鎖住,並且期望在有些row不會加入結果集中(例如不滿足where條件)釋放這些行的鎖。注:其實掃瞄了全表,只不過在掃瞄完成之後,判斷where條件時不滿足,則會釋放鎖然而對於某些情況下,不會立即釋放行鎖,因為在查詢執行期間乙個結果行和他的原始**之間的關係可能已經丟失,例如union,從表中掃瞄行,在計算他們是否加入結果集之前,這些行可能被插入臨時表中。此時,臨時表中的行和原始表中的行的關係已經丟失,原始表中的行不會解鎖知道查詢執行完成。

innodb按照如下設定具體的鎖:

在插入之前,一種叫插入意向鎖的gap型別鎖,被設定,這個鎖表示對事物插入同乙個gap中時,不需要相互等待,只要他們不是插入gap中相同的位置。

設定插入操作的排他鎖之前,現貨去gap的插入意向鎖,倆個事物可以在同乙個gap(重疊也可以)加插入意向鎖不會阻塞。

如果有重複衝突,乙個共享鎖在重複的索引記錄上設定。共享鎖的使用可能導致死鎖:當多個會話插入相同的行時,如果有某個會話已經持有了x鎖,此時會導致死鎖。舉個例子:如果有某個會話刪除該行,另外倆個插入行,則會死鎖。

session 1:

start transaction;

insert into t1 values(1);

session 2:

start transaction;

insert into t1 values(1);

session 3:

start transaction;

insert into t1 values(1);

session 1:

rollback;
上述情況是會話1已經獲取了x鎖在r行上,會話2和4都會引起重複鍵衝突,倆個會話都轉而去請求r行共享鎖,當會話1回滾時,它釋放他的排它鎖,會話2和3的共享鎖請求被授予,此時,會話2和3死鎖:沒有任何乙個會獲取排它鎖,因為他們都持有了共享鎖。

session 1:

start transaction;

delete from t1 where i = 1;

session 2:

start transaction;

insert into t1 values(1);

session 3:

start transaction;

insert into t1 values(1);

session 1:

commit;
上述情況和第一種類似。

create table ... select ...執行select使用共享的next-key鎖,或者一致性非鎖定讀,就像 insert ... select.一樣.

當乙個select在類似replace into t select ... from s where ...orupdate t ... where col in (select ... from s ...)的結果中,innodb設定共享且next-key鎖在表s上的行上。

myisam和innodb索引實現的不同

myisam引擎使用b tree作為索引結構,葉節點的data域存放的是資料記錄的位址。下圖是myisam索引的原理圖 這裡設表一共有三列,假設我們以col1為主鍵,則上圖是乙個myisam表的主索引 primary key 示意。可以看出myisam的索引檔案僅僅儲存資料記錄的位址。在myisam...

myisam和innodb索引實現的不同

myisam引擎使用b tree作為索引結構,葉節點的data域存放的是資料記錄的位址。下圖是myisam索引的原理圖 myisam的索引方式也叫做 非聚集 的,之所以這麼稱呼是為了與innodb的聚集索引區分。innodb索引實現 雖然innodb也使用b tree作為索引結構,但具體實現方式卻與...

Innodb中常見SQL語句設定的鎖型別

除了serializable隔離級別,這種sql都是一致性非鎖定讀,不加鎖 在serializable級別,這種sql加next key鎖。這種sql加s型別的next key鎖。例如,在會話1上開啟事務1,執行如下操作 num列上建有普通二級索引 mysql start transaction q...