bin log、redo log、undo log和MVVC
logs
innodb事務日誌包括redo log和undo log。redo log是重做日誌,提供前滾操作,undo log是回滾日誌,提供回滾操作。
undo log不是redo log的逆向過程,其實它們都算是用來恢復的日誌:
redo log通常是物理日誌,記錄的是數據頁的物理修改,而不是某一行或某幾行修改成怎樣怎樣,它用來恢復提交後的物理數據頁(恢復數據頁,且只能恢復到最後一次提交的位置)。mysql中使用了大量緩存,緩存存在於內存中,修改操作時會直接修改內存,而不是立刻修改磁盤,當內存和磁盤的數據不一致時,稱內存中的數據為臟頁(dirty page)。為了保證數據的安全性,事務進行中時會不斷的產生redo log,在事務提交時進行一次flush操作,保存到磁盤中, redo log是按照順序寫入的,磁盤的順序讀寫的速度遠大於隨機讀寫。當數據庫或主機失效重啟時,會根據redo log進行數據的恢復,如果redo log中有事務提交,則進行事務提交修改數據。這樣維護了事務的原子性、一致性和持久性。
undo log用來回滾行記錄到某個版本。undo log一般是邏輯日誌,根據每行記錄進行記錄。undo log用於數據的撤回操作,它記錄了修改的反向操作,比如,插入對應刪除,修改對應修改為原來的數據,通過undo log可以實現事務回滾,並且可以根據undo log回溯到某個特定的版本的數據,實現MVCC。undo log在沒有活動事務依賴(用於consistent read或回滾)便可以清楚,innodb 中存在後臺purge 線程進行後臺輪詢刪除undo log。
此外還有binlog。binlog是mysql服務層產生的日誌,位於innodb引擎的上層。常用來進行數據恢復、數據庫復制,常見的mysql主從架構,就是采用slave同步master的binlog實現的, 另外通過解析binlog能夠實現mysql到其他數據源(如ElasticSearch)的數據復制。
MVCC實現
innodb中通過B+樹作為索引的數據結構,並且主鍵所在的索引為ClusterIndex(聚簇索引), ClusterIndex中的葉子節點中保存了對應的數據內容。一個表只能有一個主鍵,所以只能有一個聚簇索引,如果表沒有定義主鍵,則選擇第一個非NULL唯一索引作為聚簇索引,如果還沒有則生成一個隱藏id列作為聚簇索引。
除了Cluster Index外的索引是Secondary Index(輔助索引)。輔助索引中的葉子節點保存的是聚簇索引的葉子節點的值。
InnoDB行記錄中除了剛才提到的rowid外,還有trx_id和db_roll_ptr, trx_id表示最近修改的事務的id,db_roll_ptr指向undo segment中的undo log。
新增一個事務時事務id會增加,trx_id能夠表示事務開始的先後順序。
Undo log分為Insert和Update兩種,delete可以看做是一種特殊的update,即在記錄上修改刪除標記。
update undo log記錄了數據之前的數據信息,通過這些信息可以還原到之前版本的狀態。
當進行插入操作時,生成的Insert undo log在事務提交後即可刪除,因為其他事務不需要這個undo log。
進行刪除修改操作時,會生成對應的undo log,並將當前數據記錄中的db_roll_ptr指向新的undo log
參考文檔
https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html#auto_id_0
https://zhuanlan.zhihu.com/p/29532524
bin log、redo log、undo log和MVVC