前置:檢索如果用不到索引,會掃瞄全表,並根據策略加鎖。所以,這就是我們合理建立索引的緣由。
鎖定讀、update、delete,在處理sql過程中, 一般會在每條掃瞄過的索引記錄上設定記錄鎖。語句中是否有where條件並沒有關係(會排除)。innodb不會記住實際上的where條件,但他知道被掃瞄過的索引範圍。使用的鎖通常是next-key鎖,也會鎖住記錄之前的「gap」。next-key鎖不僅僅鎖住掃瞄到的合法索引記錄,同時會阻塞插入gap間隙中,gap是指上一條合法索引記錄到當前掃瞄到的合法索引記錄的開區間。gap鎖可以被顯示的禁止,導致next-key不會被使用。
事物的隔離級別同樣會影響使用什麼鎖。
如果乙個二級索引被用來掃瞄,且索引記錄(二級索引,非唯一索引)將要加排他鎖,innodb會檢索相對應的聚簇索引記錄,並鎖住。
聚簇索引(clustered index)如果沒有合適的索引使用,mysql會掃面整張表,來處理語句,這樣表中的每一行都會被鎖住(合理建立索引,提高併發效率)。1) 有主鍵時,根據主鍵建立聚簇索引
2) 沒有主鍵時,會用乙個唯一且不為空的索引列做為主鍵,成為此表的聚簇索引
3) 如果以上兩個都不滿足那innodb自己建立乙個虛擬的聚集索引
輔助索引(secondary index)
非聚簇索引都是輔助索引,像復合索引、字首索引、唯一索引
對於select ... for update
orselect ... lock in share mode,掃瞄到的行都會鎖住,並且期望在有些row不會加入結果集中(例如不滿足where條件)釋放這些行的鎖。注:其實掃瞄了全表,只不過在掃瞄完成之後,判斷where條件時不滿足,則會釋放鎖。
然而對於某些情況下,不會立即釋放行鎖,因為在查詢執行期間乙個結果行和他的原始**之間的關係可能已經丟失,例如union,從表中掃瞄行,在計算他們是否加入結果集之前,這些行可能被插入臨時表中。此時,臨時表中的行和原始表中的行的關係已經丟失,原始表中的行不會解鎖知道查詢執行完成。
innodb按照如下設定具體的鎖:
在插入之前,一種叫插入意向鎖的gap型別鎖,被設定,這個鎖表示對事物插入同乙個gap中時,不需要相互等待,只要他們不是插入gap中相同的位置。
設定插入操作的排他鎖之前,現貨去gap的插入意向鎖,倆個事物可以在同乙個gap(重疊也可以)加插入意向鎖不會阻塞。
如果有重複衝突,乙個共享鎖在重複的索引記錄上設定。共享鎖的使用可能導致死鎖:當多個會話插入相同的行時,如果有某個會話已經持有了x鎖,此時會導致死鎖。舉個例子:如果有某個會話刪除該行,另外倆個插入行,則會死鎖。
session 1:上述情況是會話1已經獲取了x鎖在r行上,會話2和4都會引起重複鍵衝突,倆個會話都轉而去請求r行共享鎖,當會話1回滾時,它釋放他的排它鎖,會話2和3的共享鎖請求被授予,此時,會話2和3死鎖:沒有任何乙個會獲取排它鎖,因為他們都持有了共享鎖。start transaction;session 2:insert into t1 values(1);
start transaction;session 3:insert into t1 values(1);
start transaction;session 1:insert into t1 values(1);
rollback;
session 1:上述情況和第一種類似。start transaction;session 2:delete from t1 where i = 1;
start transaction;session 3:insert into t1 values(1);
start transaction;session 1:insert into t1 values(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...