面試官:在數據庫恢復過程,InnoDB如何定位到具體的數據文件呢?
瀏覽量: 次 發布日期:2023-08-26 22:20:25
面試官:在數據庫恢復過程,InnoDB如何定位到具體的數據文件呢?
InnoDB作為事務性引擎,使用write-ahead logging(WAL)機制保證ACID中的Automicity和Durability,使用undo機制保證ACID中的Consistency和Isolation。
按照WAL和undo的機制,形成以下兩個原則:
1、數據塊的更改需要先記錄redo日志。
2、數據塊的更改需要先寫入undo。
根據這兩個原則,InnoDB更新數據的基本流程可以簡單的總結為:記錄需要更改undo record的redo log記錄需要更改data record的redo log寫入redo log寫入undo record更新data record
如果MySQL實例異常crash,那么重啟過程中首先會進行InnoDB recovery。 即:根據last checkpoint點,順序讀取后面的redo log,按照先前滾,再回滾的原則, 應用所有的redo log。
因為redo record中記錄著數據塊的地址(space_id+page_no),所以recovery的過程首先會執行合并相同數據塊的操作,以加快recovery的過程。
那么mysql數據庫怎么根據space_id找到對應IDB數據文件? 因為在恢復的過程中,InnoDB只load了redo文件和系統表空間文件,如何查找InnoDB的數據文件呢?InnoDB的數據字典dict_table_t結構中也保存了對應關系,但數據字典受redo保護,recovery的過程中不可用。掃描datadir的所有數據文件,讀取page中保存的space_id,建立space_id和數據文件的對應關系。 MySQL目前采用第二種方式,但帶來了一個問題,當設置了innodb_file_per_table后,每一個表對應一個表空間,那么需要讀取所有的目錄下的所有Innodb數據文件,這樣就會嚴重的影響了recovery的時間。
MySQL 5.7改進策略:
MySQL 5.7中,在redo log中增加了一種新的record類型,即MLOG_FILE_NAME,記錄了自last checkpoint以來更改的數據文件的file name。 這樣在應用的時候,直接根據文件名就可以找到數據文件。
Oracle數據庫recovery的過程中,有沒有這個問題呢? 答案是沒有。
看下Oracle的設計機制:
oracle同樣在系統表空間中記錄了數據字典,受redo保護,可以通過DBA_開頭的表來查詢。但Oracle還維護了一個control file,控制文件中記錄了database name,redo file,datafile,backup等信息,通過v$開頭的表查詢。 當Oracle在recovery的過程中,需要數據庫在mount狀態下,即打開了控制文件,這時數據字典還不可用(DB沒有open),在應用redo log的時候,根據控制文件中的v$datafile,檢索file_id和file_name的對應關系。 MySQL是根據datadir,innodb_data_home_dir,innodb_log_group_home_dir等幾個目錄配置,通過文件系統的查找,找到相應文件的,而Oracle維護了一個集中式的control file管理這些初始加載的文件地址。
后面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注下~