Oracle 备份恢复详

jopen 10年前


一、备份方式:
1、在非归档模式下,只能做冷备份
2、在归档模式,可以使用热备份,也可以做冷备份。(数据文件 控制文件 临时文件 在线日志文件)

二、冷备份
(每周做一次)
1、首先得关闭数据库
2、然后将所有文件拷贝到备份的文件夹中。
临时文件和在线日志文件可以不拷贝。但是在线日志文件拷贝和不拷贝的差别是很大的,使用冷备份的时候只是备份的一个时间点的内容,在还原的时候就只还原到当前状态。在只有数据文件和控制文件的时候数据一致性是可以保证的。但是数据库是不能立马开启的,需要把在线日志文件修复
3、修复在线日志文件
在mount模式下
>  recover database until cancel/scn;  (基于用户干涉/SCN号)
在控制文件和数据文件的头部都有一个SCN号  这两个一致的时候就不需要进行修复
4、开启数据库
>alter database open resetlogs;


三、热备份
1.必要条件:数据库必须出于归档模式
查看是否出于归档模式
> archive log list;

2.热备份:做热备一般会对数据库做热备份
基于表空间的热备份
>  alter tablespace tablespace_name begin backup;
然后去物理上进行拷贝,只要拷贝dbf文件就行

>  alter tablespace tablespace_name end backup;


PS:begin和end之间的时间越短,产生的日志量越少,所以建议使用一个数据库一个数据库的备份。如果在begin和end之间数据库挂了,则会进行报错,这个时候就需要进行介质恢复


相关指令:查看有哪些表空间
>  desc dba_tablespaces
>  select tablespace_name from dba_tablespaces



3.控制文件备份
不需要进行关闭数据库,在数据库结构变化的时候需要备份
比如增加表空间了,增加用户组等等,只要是数据结构变化了就需要备份。

可以使用二进制文件的形式备份
>  alter database backup controlfile to '/tmp/control.bak';

还可以使用sql脚本的形式来备份

>  alter database backup controlfle to trace as '/tmp/control.sql' ;


这个不是备份控制文件,而是记录把这个空间文件重新建立所需要的操作,重新在建立的时候可以修改一些原本固定的参数
这里面的语句分为noresetlogs和resetlogs,在可以使用no的时候尽量使用no
使用no的前提:仅仅是控制文件丢失了,但是在线日志文件仍旧存在


4.参数文件和密码文件,都是可以备份,可以不备份,直接CP就行


四、恢复
尽量做完全恢复,对数据库的影响小

完全恢复:

1.在归档模式下

2.需要备份文件+归档日志+在线日志


不完全恢复:在线日志文件丢失了或者归档日志文件有断层(不全)或者控制文件完全损坏
      对于不完全恢复,启动的时候不能直接启动,而是需要加参数resetlogs
      resetlogs会进行把日志序列重置,重建在线日志文件等操作,加这个选项必须是在不完全恢复的前提下

不完全恢复的种类:

1、基于用户干涉   可能归档文件和在线日志是全的,而用户要求到这一点停止

2、基于时间的   还原到误删除的状态
3、SCN   在数据库中有函数可以把SCN和时间之间进行转换
dbms_flshback:里面有将SCN和时间进行转换的函数

实例恢复:实例恢复是oracle会自行进行的,是逻辑错误

介质恢复:需要DBA介入进行恢复,是文件损坏,会报如下错误
ORA-01113:FILE 7 NEED MEDIA RECOVERY  显示的是7号文件出错
如果是在对system表空间进行备份的时候关闭 则是报1号文件错误
>  shutdown abort;
>  desc v$backup;
>  selecct * from v$backup;
>  startup mount;
>  alter tablespace test2 end backup;
>  alter database open;


恢复数据库
system01.dbf被删除的的时候
>  recover datafile 1;
>  alter database open;



非系统表空间归档模式下的完全恢复
一、在数据库开启的情况下
1.1:场景模拟
>  alter database archivelog;  
>  create tablespace test datafile '/u01/app/oracle/oradata/dodo/test01.dbf' size 10M;
>  create user test identified by test defult tablespace test;
>  grant connect,resource to test;
>  conn test/test;
>  create table t;
>  commit;
>  conn / as sysdba
>  alter tablespace test begin backup;

物理上拷贝相关文件
>  alter tablespace test end backup;
然后在物理上进行删除
##在这个时候查询还是能查出来,因为是从buffer cache中查询的,
  有时候清空buffer cache还是不够,因而需要清空所有脏块
>  alter system flush buffer_cache; (清空buffer cache)
>  alter system checkpoint;         (清空所有脏块)

>  select * from v$recover_file; (如果是正常的这里面应该是没有任何的文件的,但是我们删除了dbf文件,所以这里会显现7号文件OFFLINE)


1.2:恢复
>  alter database datafile 7 offline ;         (针对某一个文件)
>  restore datafile 7;
然后把备份的文件拷贝过来
>  recover datafile 7;
>  select * from v$recover_file; (这里应该显示no rows selected)
>  alter database datafile 7 online


实际步骤:
(1)将相应的表空间或者文件offline  
(2)进行restore
(3)拷贝文件
(4)进行recover
(5)最后online


二、在数据库关闭后发现出错的情况下
前提:!!在没有备份的情况下进行完全恢复
条件:不能是系统表空间,所有的归档文件都在,控制文件是最新的
1.场景
创建好了不去做备,直接删除
同时要注意,必须是在revocer_file里面能够查到才能进行
下面两条指令是在sysdba中进行的
>  alter system checkpoint;
>  select * from v$recover_file;
>  alter database create datafile '/u01/app/oracle/oradata/dodo/test01.dbf';

>  recover datafile 6;
>  alter database datafile 6 online;
这个时候就可以了


控制文件丢失
1、如果控制文件没有完全丢失,则可以在其他控制文件复制一下就行
2、控制文件的完全丢失在实际意义上都是完全丢失

当备份成二进制文件时
>  alter database backup controlfile to '/u01/control.bak'; (首先先备份控制文件)
物理上删除控制文件
>  shutdown abort;   (这个时候理论上正常关机是关闭不了的)
物理上拷贝控制文件
$  cp control.bak /u01/app/oracle/oradata/dodo/control01.ctl
$  cp control.bak /u01/app/oracle/oradata/dodo/control02.ctl
$  cp control.bak /u01/app/oracle/oradata/dodo/control03.ctl
$  sqlplus / as sysdba
>  startup mount
>  recover database using backup controlfile;          
(告诉数据库现在的的控制文件是旧的)
如果归档之前配置过,则可以选择AUTO就行
/u01/app/oracle/oradata/dodo/redo02.log
Log applied.
Media recovery complete.

可能会报错:则可能是损坏后时间太短,还没有来得及切换日志组;也有可能是控制文件旧的,找不到目前的组
这个时候就需要选择filename  一个一个的去试用redo01.log redo02.log  redo03.log
>  alter database open resetlogs;


当备份成脚本时
>  alter database backup controlfile to trace as '/u01/control.sql';  (备份控制文件)
把脚本里面的内容拷贝过来  
$  rm -rf *.ctl
>  shutdown abort
>  startup nomount
>  @createctl

这个时候创建的控制文件是最新的,并且数据库会自动切换到mount状态
但是这个时候临时文件是不可用的,需要把脚本里面和临时文件有关的也要拷贝上或者运行一次
>  desc V$database;
>  select open_mode from v$database;
>  recover database;
>  alter database open;

控制文件和在线文件都丢失,resetlogs    
这个时候所有的文件都不一致了,原来是靠在线日志文件把控制文件拉到最新




冷备份,来保证控制文件和在线日志文件保持一次
在物理上将控制文件和在线日志文件全部删除
$  rm -rf *ctl
$  rm -rf *log
>  shutdown abort
>  startup nomount
$  rm -rf *dbf

把数据文件删除,然后再把冷备份的数据文件拷贝进去(因为在冷备份里面是一致性的)
$  cp *dbf /u01/app/oracle/oradata/dodo/
>  @createctl
(运行脚本将控制文件恢复)
>  recover database using backup controlfile until cancel;
然后接下来选择 auto  然后在运行一次 cancel
>  alter database open resetlogs;

这个只能恢复到归档的最新状态



场景:在数据库结构变化后,没有备份控制文件,这个时候控制文件丢失了,在老的控制文件里面是没有新的表空间,但事实中确实存在新的表空间,使用旧的控制文件来恢复


新建一个表空间

在物理上删除控制文件
>  shutdown abort
然后在物理上把三个都拷贝进去
>  startup mount
>  recover database using backup controlfile
先auto   找不到再找redo
>  desc v$datafile;
>  select name from v$datafile;
会发现一个不正常的文件
>  alter database rename file '/home/oracle......' to '/home/xinming';
>  recover database using backup controlfile;

然后就会显示complete
>  alter database open resetlogs;


不完全恢复
基于时间,基于用户干涉,基于SCN
基于时间的:会丢数据,在迫不得已的情况下才进行
比如删除了某个用户之类的,alter是有一个表格,可以在里面进行查找时间
$ cd admin/xinming/bdump/
> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')from dual;

冷备和热备份不能跨多个生命周期,如果有resetlogs等操作需要重新备份
>  drop user qq cascade;
>  shutdown immediate;

在物理上将现在的数据文件全部删除
从冷备中将数据文件拷贝回来
>  recover database until time '2015-03-04 11:46:00';

这个是不完全恢复
>  alter database open resetlogs;


来自:http://blog.csdn.net/doiido/article/details/44058905