mysql實戰45講學習筆記 15

2021-09-25 15:00:22 字數 1720 閱讀 5765

15 日誌和索引相關問題
1.在兩階段提交的不同瞬間,mysql如果發生異常重啟,是怎樣保證資料完整性的。

如果在圖中a的地方,也就是寫入redo log處於prepare階段之後,寫binlog之前,發生了崩潰(crash),由於此時binlog還沒寫,redolog還沒提交,所以崩潰恢復的時候。事務會回滾,這時,binlog還沒寫,所以不會傳到備庫。

時刻b,binlog寫完,redo log還沒commit前發生crash,崩潰恢復的mysql處理

1.如果redo log裡面是事務是完整的,也就是已經有了commit標識,則直接提交

2.如果redo log裡面的事務只有完整的prepare,則判斷對應的事務binlog是否存在並完整

a.如果是,則提交事務

b.否則,回滾事務

時刻b發生crash對應的就是2(a)的情況,崩潰恢復過程事務會被提交。

q2.mysql怎麼知道binlog是完整的
乙個事務的binlog是有完整格式的

statement格式的binlog,最後會有commit

row格式的binlog,最後會有乙個xid event

在5.6.2之後,還引入了binlog-checksum引數來驗證binlog內容的正確性

q3:redo log和binlog是怎麼關聯起來的
因為他們都有乙個共同的資料字段,叫xid,崩潰恢復的時候,會按順序掃瞄redo log;

如果碰到既有prepare,又有commit的redo log,就直接提交

如果碰到只有prepare,而沒有commit的redo log,則拿著xid去binlog找對應的事務

q4:處於prepare階段的redo log加上完整binlog,重啟就能恢復,mysql為什麼這樣設計
為了保證主庫和備庫的資料一致性

q8:redo log一般設定多大
redo log設定太小的話,會導致很快就寫滿,然後不得不強行刷redo log,這樣wal機制的能力就發揮不出來了

所以,如果現在常見的幾tb的磁碟,直接將redo log設定為4個檔案,每個檔案1gb。

q9:正常執行的例項,資料寫入後的最終落盤,是從redo log更新過來的還是從buffer pool更新過來的。
實際上,redo log並沒有記錄資料頁的完整資料,所以並沒有能力自己更新磁碟資料頁

1.如果正常執行的例項,資料頁被修改後,跟磁碟的資料頁不一致,稱為髒頁,最終資料落盤,就是把記憶體中的資料頁寫盤,這個過程與redo log 無關。

2.在崩潰恢復的情況下,innodb如果判斷到乙個資料頁可能在崩潰恢復的時候丟失了更新,就會將他讀到記憶體,然後讓redo log更新記憶體內容,更新完成後,記憶體頁變成髒頁,回到第一種情況。

q10:redo log buffer是什麼,是先修改記憶體,還是先寫redo log檔案
redo log buffer就是一塊記憶體,用來先存redo日誌的,也就是,在執行第乙個insert的時候,資料的記憶體就被修改了,redo log buffer也寫入了記憶體中。

真正把日誌寫到redo log檔案,是在執行commit語句的時候做的。

mysql實戰45講學習筆記 02

2.日誌系統 一條sql更新語句是如何執行的 一條查詢語句執行過程是經過聯結器,分析器,優化器,執行器等功能模組最後到達儲存引擎 查詢語句的流程,更新語句也是會同樣走一遍。更新流程還涉及兩個重要的日誌系統,redo log 重做日誌 和binlog 歸檔日誌 重要的日誌模組 redo log mys...

mysql實戰45講學習筆記 11

11 怎麼給字串欄位加索引字首索引的優勢,選取欄位前幾個作為索引,占用的空間更小 使用字首索引,定義好長度,就可以做到既節省空間,又不用額外增加太多的查詢成本。建立索引的時候關注的是區分度,區分度越高越好,區分度越高,意味著重複的鍵值越少,因此,可以通過統計索引上有多少不同的值來判斷使用多長字首。m...

mysql實戰45講學習筆記 12

為什麼我的mysql 抖 了一下一條sql語句,正常執行的時候特別快,但有時會突然變得特別慢,並且隨機,持續時間短。將對應的記憶體資料寫入到磁碟的過程,叫做flush。當記憶體資料頁跟磁碟資料頁內容不一致的時候,我們稱這個記憶體頁為 髒頁 記憶體資料寫入到磁碟後,記憶體和磁碟上的資料頁就一致,稱為 ...