redo->每次操作都先記錄到redo日志中,當出現實例故障(像斷電),導致數據未能更新到數據文件,則數據庫重啟時須redo,重新把數據更新到數據文件
undo->記錄更改前的一份copy,但你系統rollback時,把這份copy重新覆蓋到原來的數據
redo->記錄所有操作,用於恢復(redo records all the database transaction used for recovery)
undo->記錄所有的前印象,用於回滾(undo is used to store uncommited data infor used for rollback)
redo->已遞交的事務,實例恢復時要寫到數據文件去的
undo->未遞交的事務.
redo的原因是:每次commit時,將數據的修改立即寫到online redo中,但是並不一定同時將該數據的修改寫到數據文件中。因為該數據已經提交,但是只存在聯機日志文件中,所以在恢復時需要將數據從聯機日志文件中找出來,重新應用一下,使已經更改數據在數據文件中也改過來!
undo的原因是:在oracle正常運行時,為了提高效率,假如用戶還沒有commit,但是空閑內存不多時,會由DBWR進程將臟塊寫入到數據文件中,以便騰出寶貴的內存供其它進程使用。這就是需要UNDO的原因。因為還沒有發出commit語句,但是oracle的dbwr進程已經將沒有提交的數據寫到數據文件中去了。
Undo存在的意義就是為了讀一致性,回滾,讓數據庫知道它過去的狀態
讀一致性的具體步驟
1、確認讀取時間的SCN號
2、搜索所有關聯此表、行的數據塊,要求數據塊ILT事務槽的SCN號要小於讀取時刻的SCN號。
3、如果搜索到小於讀取時刻的SCN號,直接讀取
4、如果全部沒有小於讀取時刻的SCN號,則根據數據塊內ILT事務槽記錄的undo信息,查找改變之前的數據。如果SCN號還是大於讀取時刻,那么通過遞歸讀取undo塊所有關聯這一事務的數據塊,直至找到比讀取時刻SCN號小undo塊的信息,找到后進行讀取。
5、如果沒有比讀取時刻的SCN號小的undo信息,那就會報經典錯誤ORA-1555 snapshoot too old(快照過舊),這樣是為了避免幻影讀、臟讀等現象,保證讀一致性的絕對特性
Redo(在線重做日志)存在的意義就是為了做恢復用的,讓數據庫在崩潰后才能恢復如初,不丟數據
redo做恢復需要依靠undo先還原,在恢復
1.查看當前日志組成員
SQL> select member from v$logfile;
2.查看當前日志組狀態
SQL> select group#,members,bytes/1024/1024,status from v$log;
橫縱向對比單位小時內重做日志組的切換次數SQL語句
SELECT TO_CHAR(FIRST_TIME,'YYYY-MM-DD') DAY, TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'00',1,0)),'99') "00", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'01',1,0)),'99') "01", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'02',1,0)),'99') "02", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'03',1,0)),'99') "03", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'04',1,0)),'99') "04", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'05',1,0)),'99') "05", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'06',1,0)),'99') "06", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'07',1,0)),'99') "07", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'08',1,0)),'99') "0", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'09',1,0)),'99') "09", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'10',1,0)),'99') "10", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'11',1,0)),'99') "11", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'12',1,0)),'99') "12", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'13',1,0)),'99') "13", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'14',1,0)),'99') "14", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'15',1,0)),'99') "15", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'16',1,0)),'99') "16", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'17',1,0)),'99') "17", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'18',1,0)),'99') "18", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'19',1,0)),'99') "19", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'20',1,0)),'99') "20", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'21',1,0)),'99') "21", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'22',1,0)),'99') "22", TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'23',1,0)),'99') "23" FROM V$LOG_HISTORY GROUP BY TO_CHAR(FIRST_TIME,'YYYY-MM-DD') ORDER BY 1 DESC;