MySQL5.5后,,默認(rèn)存儲(chǔ)引擎是InnoDB,5.5之前默認(rèn)是MyISAM,。
InnoDB(事務(wù)性數(shù)據(jù)庫引擎)和MyISAM的區(qū)別補(bǔ)充:
- InnoDB是聚集索引,,數(shù)據(jù)結(jié)構(gòu)是B+樹,葉子節(jié)點(diǎn)存K-V,,V存的是數(shù)據(jù)頁,。MyISAM是非聚集索引,V上存的是主鍵值,,查到主鍵后還需要從聚集索引上再查一次,。
- InnoDB是具有事務(wù)(commit)、回滾(rollback)和崩潰修復(fù)能力(crash recovery capabilities)的事務(wù)安全(transaction-safe (ACID compliant))型表,。適合存在大量insert,、update場(chǎng)景。
- MyISAM強(qiáng)調(diào)的是性能,,不支持事務(wù),,最大缺陷就是崩潰后無法安全恢復(fù),更適合讀密集的小型應(yīng)用,。
- InnoDB支持MVCC(多版本控制),。應(yīng)對(duì)高并發(fā)事務(wù), MVCC比單純的加鎖更高效,所以InnoDB更適合高并發(fā)場(chǎng)景,。
- InnoDB支持外鍵
- MyISAM支持?jǐn)?shù)據(jù)壓縮
常用命令
//查所有引擎
mysql> show engines;
//查當(dāng)前引擎
mysql> show variables like '%storage_engine%';
InnoDB的行級(jí)鎖
InnoDB支持的行級(jí)鎖,,包括如下幾種:
-
Record Lock:對(duì)索引項(xiàng)加鎖,,鎖定符合條件的行,其他事務(wù)不能修改和刪除加鎖項(xiàng),。
-
Gap Lock:對(duì)索引項(xiàng)之間的“間隙”加鎖,,鎖定記錄的范圍(對(duì)第一條記錄前的間隙或最后一條將記錄后的間隙加鎖),不包含索引項(xiàng)本身,。其他事務(wù)不能在鎖范圍內(nèi)插入數(shù)據(jù),,這樣就防止了別的事務(wù)新增幻影行。
-
Next-key Lock:鎖定索引項(xiàng)本身和索引范圍,。即Record Lock和Gap Lock的結(jié)合,。可解決幻讀問題,。
-
innodb對(duì)于行的查詢使用next-key lock
-
Next-locking keying為了解決Phantom Problem幻讀問題
-
當(dāng)查詢的索引含有唯一屬性時(shí),,將next-key lock降級(jí)為record key
-
Gap鎖設(shè)計(jì)的目的是為了阻止多個(gè)事務(wù)將記錄插入到同一范圍內(nèi),而這會(huì)導(dǎo)致幻讀問題的產(chǎn)生
-
有兩種方式顯式關(guān)閉gap鎖(除了外鍵約束和唯一性檢查外,,其余情況僅使用record lock):
-- 將事務(wù)隔離級(jí)別設(shè)置為RC
-- 將參數(shù)innodb_locks_unsafe_for_binlog設(shè)置為1
InnoDB的行級(jí)鎖是基于索引實(shí)現(xiàn)的,,如果查詢語句未命中任何索引,那么InnoDB會(huì)使用表級(jí)鎖,。
不同于MyISAM總是一次性獲得所需的全部鎖,,InnoDB的鎖是逐步獲得的,當(dāng)兩個(gè)事務(wù)都需要獲得對(duì)方持有的鎖,,導(dǎo)致雙方都在等待,,這就產(chǎn)生了死鎖。發(fā)生死鎖后,,InnoDB一般都可以檢測(cè)到,,并使一個(gè)事務(wù)釋放鎖回退。
避免死鎖:
- 通過表級(jí)鎖來減少死鎖產(chǎn)生的概率,;
- 多個(gè)程序盡量約定以相同的順序訪問表(哲學(xué)家就餐問題),;
- 同一個(gè)事務(wù)盡可能做到一次鎖定所需要的所有資源。
表級(jí)鎖和行級(jí)鎖可以進(jìn)一步劃分為共享鎖(s)和排他鎖(X),。
參考
《MySQL應(yīng)知應(yīng)會(huì)》
《Java工程師修煉之道》
https://blog.csdn.net/qq_34337272/article/details/80611486
|