无论是在各种会议上,还是在朋友/网友私下请教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_dircontrol0'||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_dircontrol0'||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的异常情况恢复,备份情况请不要参考该文章,具体请见后续文章,敬请关注