1. mysql的存儲引擎負責數(shù)據(jù)的存儲和提取砸逊,存儲引擎不會去解析SQL吱型,不同的存儲引擎之間也不會相互通信笼平,而是簡單的相應上層服務器的請求园骆。
2. 優(yōu)化器不關心表使用的是什么存儲引擎,但是存儲引擎對于優(yōu)化查詢是有影響的寓调,優(yōu)化器會請求存儲引擎提供容量或某個具體操作的開銷信息锌唾,以及表數(shù)據(jù)的統(tǒng)計信息等。
3. 共享鎖(簡稱S鎖夺英,又叫讀鎖)和排它鎖(簡稱X鎖晌涕,又叫寫鎖):
- InnoDB引擎默認的修改數(shù)據(jù)語句,update,delete,insert都會自動給涉及到的數(shù)據(jù)加上排他鎖
- select語句默認不會加任何鎖類型
- 共享鎖就是多個事務對于同一數(shù)據(jù)可以共享一把鎖秋麸,都能訪問到數(shù)據(jù)渐排,但是只能讀不能修改,即被加了共享鎖的數(shù)據(jù)記錄灸蟆,在無法進行更新操作驯耻。
- 加排他鎖可以使用select ...for update語句亲族,加共享鎖可以使用select ... lock in share mode語句。
- 加過排他鎖的數(shù)據(jù)行在其他事務中是不能修改數(shù)據(jù)的可缚,也不能通過for update和lock in share mode鎖的方式查詢數(shù)據(jù)霎迫,但可以直接通過select ...from...查詢數(shù)據(jù),因為普通查詢沒有任何鎖機制
- 排他鎖指的是一個事務在一行數(shù)據(jù)加上排他鎖后帘靡,其他事務不能再在其上加其他的鎖知给。
4. 鎖粒度:
- 表鎖:鎖定整張表,此時會阻塞其他用戶對該表的所有讀寫操作描姚,讀鎖之間是不會相互阻塞的涩赢。盡管存儲引擎可以管理自己的鎖,MySQL本身還是會使用各種有效的表鎖來實現(xiàn)不同的目的轩勘。例如筒扒,服務器會為如ALTER TABLE之類的語句使用表鎖,而忽略存儲引擎的鎖機制绊寻。
- 行級鎖:只在存儲引擎層實現(xiàn)花墩。
5. 事務:
- 原子性(Atomicity):整個事務的操作要么全部成功,要么全部失敗回滾澄步。
- 一致性(Consistency):數(shù)據(jù)庫總是從一個一致狀態(tài)轉換到另一個一致狀態(tài)冰蘑。【一致性和原子性的區(qū)別:https://www.cnblogs.com/loren-Yang/p/7466132.html】
原子性和一致性不是一樣的嗎村缸?
提交事務祠肥,原子性保證要么成功,要么失敗王凑,這樣不就是很好的保證數(shù)據(jù)庫的一致性了嗎搪柑。當時我看見大多數(shù)人舉的一致性例子就是轉賬問題:假設用戶A和用戶B兩者的錢加起來一共是5000聋丝,那么不管A和B之間如何轉賬索烹,轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是5000弱睦,這就是事務的一致性百姓。當我我就想難道原子性不就保證了轉賬成功和失敗嗎?
其實况木,我上述想法是錯的垒拢,但是部分錯,因為火惊,原子性確實代表一致性的部分求类,但不是全部。下面是我在知乎上看到的答案左輕候屹耐,感覺可以很好的解釋原子性和一致性區(qū)別尸疆。
原子性其實并不能保證一致性的。再多個事務并行進行的情況下,即使保證每一個事務的原子性寿弱,任然可能導致數(shù)據(jù)不一致的結果犯眠。
舉例:事務1需要將100元轉入帳號A:先讀取帳號A的值,然后在這個值上加上100症革。但是筐咧,在這兩個操作之間,另一個事務2修改了帳號A的值噪矛,為它增加了100元量蕊。那么最后的結果應該是A增加了200元。但事實上艇挨,事務1最終完成后危融,帳號A只增加了100元,因為事務2的修改結果被事務1覆蓋掉了雷袋。
如上吉殃,保證了原子性,但是數(shù)據(jù)庫的一致性沒有得到保證楷怒,上述這種情況就需要數(shù)據(jù)庫隔離性的保證了蛋勺。
- 隔離性(Isolation):一個事務所做的修改在事務提交以前,對其他事務來說是不可見的鸠删。
- 持久性(Durability):事務一旦提交抱完,其所做的修改就會永久保存到數(shù)據(jù)庫中。
6. 事務隔離級別
讀未提交(READ UNCOMMITTED)
讀已提交(READ COMMITTED)
可重復度(REPEATABLE READ)
-
序列化(SERIALIZE)
臟讀:讀同一條記錄刃泡,每次查詢結果不一致巧娱;
幻讀:指的是當前某個事務在讀取某個范圍內(nèi)的記錄時,另一個事務又在該范圍內(nèi)插入了新的記錄烘贴,當之前的事務再次讀取改范圍內(nèi)的數(shù)據(jù)記錄時禁添,會產(chǎn)生幻讀。
7. 死鎖:數(shù)據(jù)庫系統(tǒng)實現(xiàn)類各種死鎖檢測和死鎖超時機制桨踪。InnoDB目前處理死鎖的方法是老翘,將持有最少行級排他鎖的事務進行回滾。
8. 事務日志:使用事務日志锻离,存儲引擎在修改表的數(shù)據(jù)時只需要修改其內(nèi)存拷貝铺峭,再把該修改行為記錄到持久在硬盤上的事務日志中(而不是每次將修改的數(shù)據(jù)本身持久到磁盤),事務日志持久后汽纠,內(nèi)存中被修改的數(shù)據(jù)在后臺可以慢慢的刷回到磁盤卫键。
9. 多版本并發(fā)控制(MVCC),https://juejin.im/post/5c68a4056fb9a049e063e0ab
10. InnoDB概覽:
- InnoDB采用MVCC來支持高并發(fā)虱朵,并且實現(xiàn)了四個標準的隔離級別莉炉。其默認級別是RR啤呼,并且通過間隙鎖策略防止幻讀的出現(xiàn),間隙鎖使得InnoDB不僅僅鎖定查詢涉及的行呢袱,還會對索引中的間隙進行鎖定官扣,以防止幻影行的出現(xiàn)。
- 其二級索引的中會包含主鍵列(葉子節(jié)點)羞福,所以如果主鍵列很大的話惕蹄,其他的所有索引都會很大,因此若表上的索引較多的話治专,主鍵應當盡可能的小卖陵。
11. 轉換表的引擎:
- 可以通過ALTER TABLE語句對表引擎進行轉換,但是該方法執(zhí)行需要很長時間张峰。MySQL會按行將數(shù)據(jù)從原表復制到一張新的表泪蔫,在復制期間可能會消耗系統(tǒng)所有的IO能力,同時會在原表上加鎖喘批。
- 書中推薦的方法是撩荣,新建一個表,然后通過過INSERT INTO ... SELECT 語句來進行原表數(shù)據(jù)遷移饶深,此時要注意餐曹,SELECT條件中一定要使用索引字段,并逐步批量遷移敌厘,否則依然會造成原表鎖表台猴。
12. 當兩個事務在對同一個數(shù)據(jù)同時進行更新的時候,先開始的事務會將數(shù)據(jù)加鎖俱两,后開始的事務需要等待前一個事務提交后才能獲取鎖饱狂,而后才能執(zhí)行更新操作。
?