寫這篇文章,源于客戶的資料庫因為斷電後無法啟動,經過從網上檢視,最後聯系oracle得以解決,我後續會把此次客戶問題及處理過程貼上。
現在我打算根據warehouse老師的試驗,走一遍,研究下具體的原理:http://www.itpub.net/thread-1065138-1-1.html。
試驗環境11.2.0.3
其實一句話就可以說明白:那就是資料檔案的頭上不僅包含了checkpoint_change#,更重要的是它包含了這個checkpoint_change#所在的logfile的sequence#,準确的說是rba。有了rba,在恢複時就能準确的知道到底需要哪個logfile(archivelog or redo)。
1、首先,檢視控制檔案(control file)中記錄的checkpoint_change#,這個就是做checkpoint時的scn号:
SQL> set pages 80
SQL> set lines 1500
SQL> set numwidth 20
SQL> select resetlogs_change#, to_char(resetlogs_time, 'DD-MON-YYYY HH24:MI:SS') RSLTime,
to_char(resetlogs_change#) RSLscn, to_char(prior_resetlogs_time, 'DD-MON-YYYY HH24:MI:SS') PRSLTime, to_char(prior_resetlogs_change#) PRSLscn,
checkpoint_change# CKPscn, controlfile_change# CTLscn,
to_char(controlfile_time, 'DD-MON-YYYY HH24:MI:SS') CTLTime,
current_scn, controlfile_type from v$database;
這裡我多查詢了一些其他的資訊,比如上一次open resetlogs的時間,當時的scn;當然,我們現在關注的還是 checkpoint_change# (此處給它取了個别名CKPSCN);注意controlfile_change#是指“Last SCN in backup control file; null if the control file is not a backup”,
current_scn是指:目前系統的scn号,如果系統是沒有啟動的,此值為0.
2、檢視目前資料檔案中記錄的checkpoint_change#:
select status, to_char(checkpoint_change#), to_char(checkpoint_time, 'DD-MON-YYYY HH24:MI:SS') as
checkpoint_time, count(*)
from v$datafile_header
group by status, checkpoint_change#, checkpoint_time
order by status, checkpoint_change#, checkpoint_time;
當然,我可以可以檢視每個資料檔案對應的檢查點scn(先從資料檔案裡檢視):
然後是從控制檔案裡檢視:
感覺,一般來說,應該不會出現控制檔案和資料檔案内checkpoint_change#不一緻的情況。
3、檢視控制檔案(control file)裡記錄redo的checkpoint_change# :
select groups,current_group#,sequence#,checkpoint_change#,checkpoint_time,last_redo_change#
from v$thread;
其中last_redo_change#是指redo log裡,最後的scn值(實際上也是記錄在控制檔案裡的)。
驗證恢複過程:
--輸入測試資料,驗證備份恢複的過程,注意仔細觀查插入到tt表中的dbms_flashback.get_system_change_number和v$log中的FIRST_CHANGE#之間的關系,我們通常了解備份恢複的原理是:事務對應的scn如果落在了哪個archivelog裡,那麼這個archivelog在恢複時就被用到,下面的大緻試驗過程也會驗證這一點:
1、冷備份目前資料庫
2、建立測試表:
SQL> conn scott/tiger
Connected.
SQL> desc tt
Name Null? Type
--------------------------------------- ----------------------------
ID NUMBER
NAME VARCHAR2(20)
SQL> insert into tt values(dbms_flashback.get_system_change_number,'a');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from tt;
ID NAME
---------- --------------------
1111433 a
--datafile header上記錄的rba資訊,rba的意義在下面做了詳細解釋,這裡隻需知道FHRBA_SEQ表示redo的sequence#=13對應的是目前聯機日志,而該sequence#被
記錄在了datafile header上
select f.member, v.thread#, v.sequence#, v.group#, v.status,v.archived,v.first_change#
from v$log v, v$logfile f where v.group# = f.group#;
下面我們插入第二條記錄:
SQL> insert into tt values(dbms_flashback.get_system_change_number,'b');
ID NAME
---------- --------------------
1111433 a
1133720 b
現在看來,