oracle的數據庫操作都會被記錄在redo log中,用來進行undo(回滾)或在數據庫異常的時候redo(重做)。redo log又分為online(在線日志)和archive(歸檔日志)兩部分。
oracle默認有3個在線日志文件,通常它們是按順序寫滿一個再寫下一個,而寫滿的在線日志文件會被整理為歸檔日志。在每個在線日志內部,可能按順序或隨機填寫數據。
在線日志和歸檔日志一樣,都是由很多塊組成,文件第1塊作為文件頭,包含塊大小、塊總數等信息,第2塊作為數據庫頭,包含數據庫信息(如版本號、數據庫ID、文件序號等)。默認情況下,塊大小為512bytes,也可能有1k、2k等的情況(我還沒遇到),所以redo log文件大小一定是512字節的整數倍。
第1塊的數據格式:
typedef struct fh0 { uint32_t unknown0; uint32_t unknown1; uint32_t unknown2; uint32_t unknown3; uint32_t unknown4; uint32_t blocksize; //每塊大小(字節), 512/1024... uint32_t blockcount; //當前文件的總塊數(不包括第一塊) uint32_t unknown5; uint8_t nouse[480]; }Redo_fh0; Redo_fh0
第2塊的數據格式:
typedef struct scn { uint32_t scnbase; uint16_t scnwrapper; uint16_t filler; }Redo_scn; typedef struct fh1 { Redo_bh blockhead; uint32_t unknown0; uint32_t comvsn; //Compatibility Vsn uint32_t dbid; uint8_t dbname[8]; //"ORCL"(sid) uint32_t controlseq; uint32_t filesize; uint32_t blocksize; uint16_t filenum; uint16_t filetype; uint32_t activid; uint8_t nouse0[36]; //0 uint8_t descript[64]; uint32_t nab; //next available block uint32_t resetcount; Redo_scn resetscn; uint32_t hws; //後3字節為0 uint32_t thread; Redo_scn lowscn; uint32_t lowscntime; Redo_scn nextscn; uint32_t nextscntime; uint32_t unknown11; Redo_scn enablescn; uint32_t enablescntime; Redo_scn thrclosescn; uint32_t thrclosescntime; uint8_t unknown13[52]; Redo_scn prevresetscn; uint32_t prevresetcount; uint8_t nouse1[152]; //0 uint8_t unknown14[36]; uint8_t nouse2[28]; //0 }Redo_fh1; Redo_fh1
第1塊與其他塊完全不同,它不含有塊頭,也不被包含在塊總數之內。從第2塊開始,所有的數據塊的前16個字節為塊頭,格式:
typedef struct bh { uint32_t signature; //簽名 uint32_t blocknum; //塊號 uint32_t sequence; //順序號 uint16_t offset; //最高位1需過濾掉 uint16_t checksum; }Redo_bh; Redo_bh
下面詳細研究歸檔日志。