alter tablespace XXX begin backup;cp XXX ....alter tablespace XXX end backup;
(這里需要注重一點,Oracle的最小存儲單位是一個數據塊,一個塊的大小通常設置為8KB,而操作系統的塊通常是512B,這樣的話一個Oracle的數據由很多個操作系統的塊組成。而且對于一個數據文件來說,它的所有塊對應的操作系統的塊并不是按順序存儲的,當運行cp等操作系統命令時并不能指定從那個Oracle數據塊開始拷貝。)當open數據庫的時候,Oracle會去比較控制文件中數據文件記錄和數據文件頭的checkpoint cnt,假如兩者相同,則判定不需要介質恢復,假如不同,這時候Oracle就會報某某文件需要介質恢復。然后拷貝回數據文件備份我們開始recover,這時候就從上次做備份時的scn開始恢復,運用日志,直到恢復結束。當cp數據文件時,比如說我們拷貝的第一個塊可能是scn為100的數據塊,當我們完成這個塊的拷貝后,這個塊有可能被別的進程多次修改,scn變為900。我們知道當數據庫發生檢查點時會去更新數據文件頭和控制文件中的checkpoint scn,假如當我們在cp數據文件的同時發生了n次checkpoint,這時候數據文件頭的scn可能被更新了很多次。這時候cp的進程去拷貝數據文件頭所在的操作系統塊,可能這個數據文件頭的塊因為被checkpoint了很多次導致它的scn為1000,這時候整個數據文件會出現不一致,當用這個備份文件去恢復時,恢復進程會從scn=1000開始恢復,這樣的話開始那個scn=100的塊將丟失從scn100-scn1000的數據,因為數據塊并不應用scn在1000以前的日志,而且這樣做的話可能出現一些數據塊的corruption,所以不置成backup模式備份的話并不可取。當然,假如你能確保當cp的時候不發生checkpoint,或者你的操作系統塊的大小不小于Oracle的數據塊大小,這些情況下不置backup mode拷貝出來的文件也是有效的。 現在我們知道了為什么不能不設置backup模式,下面來講講alter tablespace XXX begin backup做了什么? 當數據文件置于backup模式時,Oracle會去鎖定數據文件頭,這時候數據庫發生檢查點的話將不會修改文件頭的checkpoint scn,而只是增加checkpoint cnt,所以不管執行cp的時候操作系統塊的拷貝順序是如何,Oracle總會從文件頭的scn開始恢復,這樣的話也就避免了數據丟失和數據塊corruption。假如大家用的是rman來備份,那么就不會有這個問題,因為rman備份的時候rman會去對比數據塊的頭尾標志,假如發現不一致,那么它將會再去讀這個塊,直到讀到一致的塊才往備份集里寫。 但是alter tablespace XXX begin backup帶來的另一個問題是會導致產生多余的日志,通過一個小小的試驗就可以證實這一點。
SQL> select name,value from v$sysstat where name='redo size';NAME VALUE--------------------------------------------------- ----------redo size 43408SQL> update test set a=a;1 row updated.SQL> commit;Commit complete.SQL> select name,value from v$sysstat where name='redo size';NAME VALUE--------------------------------------------------------------redo size 44060 SQL> ALTER SYSTEM DUMP LOGFILE '/netapPRedo/redo05.log';System altered.
SQL> alter tablespace test begin backup;Tablespace altered.SQL> select name,value from v$sysstat where name='redo size';NAME VALUE------------------------------------------------------------------redo size 44732SQL> update test set a=a;1 row updated.SQL> commit;Commit complete.SQL> select name,value from v$sysstat where name='redo size';NAME VALUE-------------------------------------------------------------------redo size 53560SQL> alter tablespace test end backup;Tablespace altered.