關於Oracle資料庫熱備份指令碼深入剖析
通常的熱備指令碼都是這樣的:
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 43408
SQL> 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.
一個update的動作產生44060-43408=652bytes的redo,把表空間置為backup mode:
SQL> alter tablespace test begin backup;
Tablespace altered.
SQL> select name,value from v$sysstat where name='redo size';
NAME VALUE
------------------------------------------------------------------
redo size 44732
SQL> 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 53560
SQL> alter tablespace test end backup;
Tablespace altered.
一個update的動作產生53560-44732=8828bytes的redo,看看到底是記了些什麼?
SQL> ALTER SYSTEM DUMP LOGFILE '/netappredo/redo05.log';
System altered.
REDO RECORD - Thread:2 RBA: 0x00004e.000000b0.0128 LEN: 0x01b0 VLD: 0x01
SCN: 0x0000.19ed24f7 SUBSCN: 1 06/29/2004 15:05:32
CHANGE #1 TYP:0 CLS:29 AFN:33 DBA:0x08400029
SCN:0x0000.19ed24f2 SEQ: 1 OP:5.2
...... (改動向量1,記載對undo header事務表的修改)
CHANGE #2 TYP:0 CLS:30 AFN:33 DBA:0x0840002e
SCN:0x0000.19ed24f0 SEQ: 1 OP:5.1
...... (改動向量2,記載對undo block的修改)
CHANGE #3 TYP:2 CLS: 1 AFN:51 DBA:0x0cc0000f
SCN:0x0000.19ed24e8 SEQ: 1 OP:11.5
KTB Redo (改動向量3,記載對資料塊的修改,
也就是在資料塊上執行update test set a=a)
op: 0x11 ver: 0x01
op: F xid: 0x0007.001.00014ece uba: 0x0840002e.0859.38
Block cleanout record, scn: 0x0000.19ed24f7 ver: 0x01 opt: 0x02,
entries follow...
itli: 1 flg: 2 scn: 0x0000.19ed24e8
KDO Op code: URP row dependencies Disabled
xtype: XA bdba: 0x0cc0000f hdba: 0x0cc0000b
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 2 ckix: 0
ncol: 1 nnew: 1 size: 0
col 0: [ 2] c1 02
CHANGE #4 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ: 0 OP:5.20
......(改動向量4,一些標記)
我們看到了正常的日誌記錄,此外還有些block cleanout及回滾段改變的日誌記錄,但是相比較不是backup模式的日誌來說多了這一部分。
Log block image redo entry
Dump of memory from 0x0AE48820 to 0x0AE4A808
AE48820 00280001 00002C32 19ED24E6 1FE80000 [..(.2,...$......]
AE48830 00321F02 0CC00009 00210005 000307F1 [..2.......!.....]
AE48840 0840000E 0021100C 00002001 19ED24E8 [..@...!.. ...$..]
AE48850 001F0016 0001A94C 0840007C 000D0C08 [....L...|.@.....]
AE48860 00008000 19ED2468 00000000 00000000 [....h$..........]
AE48870 00020100 00160001 1F791F8C 00001F79 [..........y.y...]
AE48880 1F920002 0F88FFFF 0ED00F2C 0E180E74 [........,...t...]
AE48890 0D600DBC 0CA80D04 0BF00C4C 0B380B94 [..`.....L.....8.]
AE488A0 0A800ADC 09C80A24 0910096C 085808B4 [....$...l.....X.]
AE488B0 07A007FC 06E40744 06240684 056405C4 [....D.....$...d.]
......
這一部分是對更改的資料塊做的一個映象,把這個塊完全記錄到redo裡面去了,但是為什麼要這麼做呢。
這就又牽扯到一個概念,'block split',當資料檔案在備份cp時,因為Oracle資料塊和作業系統塊的差異,一個資料塊可能由16個作業系統塊組成(8KB 資料塊,512位元組系統塊),這樣的話可能出現一個資料塊包含了幾個不同版本的作業系統塊,會導致資料塊的不一致,所以在備份模式下如果有語句對備份塊產生更新,那麼Oracle會先把當前塊複製一份到redo,當恢復的時候如果碰到資料塊不一致就從redo把這個映象複製回去,然後在這個一致性的映象開始恢復。 如果使用rman來備份可以避免產生過多的塊,就像上面所說的,rman會去建議塊的一致性,所以不用複製映象塊到日誌。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/143526/viewspace-975090/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於資料庫的熱備指令碼資料庫指令碼
- oracle資料庫使用rman備份指令碼Oracle資料庫指令碼
- Oracle多例項資料庫備份指令碼Oracle資料庫指令碼
- 資料庫備份指令碼資料庫指令碼
- oracle資料庫資料備份成文字的指令碼Oracle資料庫指令碼
- Oracle物理熱備份指令碼(ZT)Oracle指令碼
- Oracle學習系列—資料庫備份—熱備份Oracle資料庫
- 資料庫全備份指令碼資料庫指令碼
- Oracle資料庫冷備份與熱備份操作梳理Oracle資料庫
- linux下oracle熱備份指令碼LinuxOracle指令碼
- 【Oracle指令碼】-很不錯的Windows下資料庫備份EXP指令碼Oracle指令碼Windows資料庫
- 《mysql資料庫備份小指令碼》MySql資料庫指令碼
- 關於Oracle 資料庫備份的幾個概念Oracle資料庫
- 生成熱備份指令碼指令碼
- MySQL資料庫備份的shell指令碼MySql資料庫指令碼
- 《mysql資料庫備份小指令碼》(轉)MySql資料庫指令碼
- 簡單的備份資料庫指令碼資料庫指令碼
- mysqldump來備份MYSQL資料庫(指令碼)MySql資料庫指令碼
- oracle 熱備指令碼 .Oracle指令碼
- windows下oracle資料庫的exp自動備份指令碼WindowsOracle資料庫指令碼
- Oracle expdp/impdp匯入匯出備份資料庫指令碼Oracle資料庫指令碼
- 基於表空間的熱備份指令碼指令碼
- ORACLE備份指令碼Oracle指令碼
- oracle 備份指令碼Oracle指令碼
- Liunx備份mysql資料庫的shell指令碼MySql資料庫指令碼
- 恢復目錄資料庫備份指令碼資料庫指令碼
- Mysql資料庫的簡單備份指令碼MySql資料庫指令碼
- 資料庫連結的備份指令碼(轉)資料庫指令碼
- oracle的熱備指令碼Oracle指令碼
- 關於批處理(bat)資料庫備份BAT資料庫
- 使用shell 指令碼備份資料指令碼
- ORACLE日常備份指令碼Oracle指令碼
- Oracle 集中備份指令碼Oracle指令碼
- oracle RMAN備份指令碼Oracle指令碼
- oracle_備份指令碼Oracle指令碼
- 課時7-備份與恢復----資料庫備份策略指令碼資料庫指令碼
- oracle資料庫備份之exp增量備份Oracle資料庫
- HP Data Protector Manager 備份和恢復oracle資料庫參考指令碼Oracle資料庫指令碼