這篇筆記主要目的是梳理清楚嗤朴,一條數(shù)據(jù)的落地须肆,中間會在哪些組件中有寫入
已知的有redo log, undo log, 索引,數(shù)據(jù)文件合敦,寫入的順序是怎么樣初橘,完成到哪個步驟,就可認(rèn)為事務(wù)算是結(jié)束了充岛。數(shù)據(jù)恢復(fù)保檐,當(dāng)數(shù)據(jù)庫意外down機后,重啟后怎么恢復(fù)數(shù)據(jù)崔梗,有哪些場景會導(dǎo)致數(shù)據(jù)丟失(恢復(fù)不了)
主要是對這篇文章https://www.slideshare.net/MariaDB/m18-deep-dive-innodb-transactions-and-write-paths的翻譯整理
A Detailed Look at a Single-ROW AUTOCOMMIT Trasaction:
UPDATE talk SET attendees =25 WHERE conference='M|18' AND name = 'Deep Dive';
Step 1:SQL 層
- 構(gòu)建語法樹
- 檢查權(quán)限
- 獲取MDL(防止有DDL對更改表)并打開表
- 獲取索引統(tǒng)計夜只?
- 生成執(zhí)行計劃
Step 2a:通過引擎接口讀取數(shù)據(jù)
- 根據(jù)where條件匹配所有rows(根據(jù)索引或者遍歷主鍵索引)
- <font color="#0000CD">在第一次讀的時候,InnoDB才會開啟事務(wù)</font>
- 分配一個新的DB_TRX_ID(InnoDB 全局遞增)
- 因為這是一個互斥操作蒜魄,需要獲取鎖扔亥,所以不需要read view。
Step 2b: 過濾行
-
如果WHERE條件只能通過范圍掃描或全表掃描权悟,必須要過濾掉不匹配的行
如果能利用索引下推砸王,InnoDB層直接過濾掉不匹配的行
-
否則,逐行返回峦阁,MySQL服務(wù)層來過濾
索引下推 Index Condition PushDown -ICP
是利用索引優(yōu)化查詢的技術(shù)谦铃,查詢數(shù)據(jù)的流程,InnoDB層在主鍵索引中(如果執(zhí)行機會能走二級索引榔昔,會先在二級索引中過濾掉不匹配的主鍵)找到整行數(shù)據(jù)驹闰,返回給MySQL層瘪菌,一直循環(huán),直至所有符合條件的行被返回嘹朗。這時候看執(zhí)行計劃中师妙,顯示的是using where.如果where 條件中有索引字段,但是沒被計劃選擇(比如 where a like '%xxx')屹培,則在InnodDB層默穴,現(xiàn)在索引中比對該字段,如果不符合條件褪秀,不會再去獲取整行蓄诽,當(dāng)然也不會返回給MySQL 層了。
-
每返回一行媒吗,就開啟一個mini-transaction
這里說的每返回的一行仑氛,表示InnoDB返回的,即便是這行在MySQL層會過濾掉闸英,也會開啟一個mini-transaction嗎锯岖?
Step 2c: 獲取所有匹配行的鎖
-
InnoDB will write-lock each index leaf read
Note: InnoDB has no “table row locks”, but “record locks” in each index separately.
-
If using index condition pushdown, non-matching records are not locked.
看不懂。甫何。出吹。。沛豌。鎖的到底是什么 索引趋箩??加派?因為row只能通過主鍵索引來獲取
- 所有可能被修改的記錄被鎖捉腥贰?
Step 3a: 記錄Undo log
Step 3b: 更新所有匹配的行
Step 4a: 提交
可能的Step 4a: 回滾
Step 4b: 清理
- 當(dāng)
COMMIT
執(zhí)行后芍锦,釋放所有的行鎖 - 喚醒其他等待這些鎖的事務(wù)
- 釋放MDL竹勉,此時可以執(zhí)行DDL了
這一套又是好復(fù)雜的東西 騎馬得看好幾天。娄琉。次乓。。孽水。票腰。