無論是在各種會議上,還是在朋友/網友私下請教Oracle資料庫恢複的問題之時,我都強調,如果你沒有十足的把握,請你對您的現場進行備份,確保別對現場進行二次損壞。你不能恢複資料庫,但絕對不能再次破壞資料庫,給二次恢複增加難度.這裡對恢複前備份提供一些指導思想和簡單指令碼,希望對大家有協助.
哪些檔案需要備份
熟悉資料庫恢複的朋友可能都情況,Oracle在異常恢複的過程中主要修改的是system資料表空間裡面資料,其他資料檔案,redo資料,控制檔案(當然由於redo,undo導致其他資料檔案內部的block也可能發生改變)。在備份時間,備份空間允許的情況下,是對這些檔案全部備份為好
完整備份檔案
set lines 150
set pages 10000
select name from v$datafile
union all
select name from v$controlfile
union all
select member from v$logfile;
有些情況下:比如如果全部備份時間過長,備份空間不足等情況下,我們該如何備份,盡量減少因為異常恢複導致對原環境的損壞.備份最核心的system資料表空間,資料檔案頭,redo file,control file等資料,由於這個不是簡單的拷貝操作,因此在產生備份語句同時,也產生還原語句,切不可產生了備份語句後,無恢複語句,導致後面還原故障現場難度增大.
無法全備情況下linux/unix資料庫恢複前備份
set lines 150
set pages 10000
select 'dd if='||name||' of=&&back_dir/'||ts#||'_'||file#||'.dbf bs=1048576 count=10'
from v$datafile where ts#<>0
union all
select 'dd if='||name||' of=&&back_dir/'||ts#||'_'||file#||'.dbf' from v$datafile where ts#=0
union all
select 'dd if='||name||' of=&&back_dir/control0'||rownum||'.ctl' from v$controlfile
union all
select 'dd if='||member||' of=&&back_dir/'||thread#||'_'||a.group#||'_'||sequence#||'_'||substr(member,
instr(member,'/',-1)+1) FROM v$log a, v$logfile b WHERE a.group# = B.GROUP#;
無法全備情況下linux/unix使用備份還原
set lines 150
set pages 1000
select 'dd of='||name||' if=&&back_dir/'||ts#||'_'||file#||'.dbf bs=1048576 count=10 conv=notrunc'
from v$datafile where ts#<>0
union all
select 'dd if='||name||' if=&&back_dir/'||ts#||'_'||file#||'.dbf' from v$datafile where ts#=0
union all
select 'dd of='||name||' if=&&back_dir/control0'||rownum||'.ctl' from v$controlfile
union all
select 'dd of='||member||' if=&&back_dir/'||thread#||'_'||a.group#||'_'||sequence#||'_'||substr(member,
instr(member,'/',-1)+1) FROM v$log a, v$logfile b WHERE a.group# = B.GROUP#;
由於win路徑斜杠不一樣(/和\的區別),因此在無法全備情況下win備份語句
set lines 150
set pages 10000
select 'dd if='||name||' of=&&back_dir\'||ts#||'_'||file#||'.dbf bs=1048576 count=10'
from v$datafile where ts#<>0
union all
select 'dd if='||name||' of=&&back_dir\'||ts#||'_'||file#||'.dbf' from v$datafile where ts#=0
union all
select 'dd if='||name||' of=&&back_dir\control0'||rownum||'.ctl' from v$controlfile
union all
select 'dd if='||member||' of=&&back_dir\'||thread#||'_'||a.group#||'_'||sequence#||'_'||substr(member,
instr(member,'\',-1)+1) FROM v$log a, v$logfile b WHERE a.group# = B.GROUP#;
在無法全備情況下win還原語句
set lines 150
set pages 1000
select 'dd of='||name||' if=&&back_dir\'||ts#||'_'||file#||'.dbf bs=1048576 count=10 conv=notrunc'
from v$datafile where ts#<>0
union all
select 'dd if='||name||' if=&&back_dir\'||ts#||'_'||file#||'.dbf' from v$datafile where ts#=0
union all
select 'dd of='||name||' if=&&back_dir\control0'||rownum||'.ctl' from v$controlfile
union all
select 'dd of='||member||' if=&&back_dir\'||thread#||'_'||a.group#||'_'||sequence#||'_'||substr(member,
instr(member,'\',-1)+1) FROM v$log a, v$logfile b WHERE a.group# = B.GROUP#;
asm磁碟的備份主要是備份磁碟頭100M空間,使用dd命令直接備份
asm 備份
set lines 150
set pages 1000
select 'dd if='||path||' of=&asmbackup_dir/'||group_number||'_'||disk_number||'.asm bs=1048576
count=100' from v$asm_disk;
asm 恢複
set lines 150
set pages 1000
select 'dd of='||path||' if=&asmbackup_dir/'||group_number||'_'||disk_number||'.asm bs=1048576
count=100 conv=notrunc' from v$asm_disk;
asmlib需要注意把ORCL:替換為/dev/oracleasm/disks/對應目錄.另外提供win環境下dd命令程式dd
備忘:對於asm情況,如果asm磁碟組正常mount,而資料庫無法open的異常情況恢複,備份情況請不要參考該文章,具體請見後續文章,敬請關注