7.Using RMAN to Perform Recovery
使用RMAN进行完全恢复
system表空间文件丢失的恢复
模拟损坏:
SQL> conn /as sysdba; SQL> create table t as select * from scott.dept; SQL> !rm -rf /u01/app/oracle/oradata/orcl/system01.dbf; SQL> alter system flush buffer_cache; SQL> conn /as sysdba;
执行恢复:
[oracle@oracle u01]$ ps -ef | grep dbw [oracle@oracle u01]$ kill -9 4233 [oracle@oracle u01]$ rman target / RMAN> startup mount; RMAN> run{ restore datafile 1; recover datafile 1; sql 'alter database open'; } [oracle@oracle u01]$ sqlplus / as sysdba; SQL> select * from t;
发现t表仍然存在,完全恢复
undo表空间文件丢失的恢复
模拟损坏:
SQL> conn /as sysdba; SQL> !rm -rf /u01/app/oracle/oradata/orcl/undotbs01.dbf; SQL> alter system flush buffer_cache; SQL> conn scott/tiger; SQL> update emp set sal=sal+100;
使用rman进行恢复:
[oracle@oracle u01]$ rman target / RMAN> run{ shutdown abort; startup mount; restore datafile 2; recover datafile 2; sql 'alter database open'; } [oracle@oracle u01]$ sqlplus scott/tiger SQL> update emp set sal=sal+100; SQL> commit;
普通表空间文件丢失的恢复
模拟损坏:
SQL> create table t3 as select * from dept; SQL> !rm -rf /u01/app/oracle/oradata/orcl/users01.dbf SQL> select * from t3; SQL> conn /as sysdba SQL> alter system flush buffer_cache; SQL> conn scott/tiger SQL> select * from t3;
使用rman进行恢复:
rman target / RMAN> run{ sql 'alter database datafile 4 offline'; restore datafile 4; recover datafile 4; sql 'alter database datafile 4 online'; } [oracle@oracle u01]$ sqlplus scott/tiger SQL> select * from t3;
备份脚本
cd /u01/app/oracle
vi rman.sh写入以下内容:
rman target / <<eof run{ delete noprompt backup; backup database plus archivelog; } exit echo "backup is ok" eof
保存
授予权限:chmod +x rman.sh
执行:./rman.sh
未备份的数据文件丢失的恢复
模拟损坏:
SQL> create tablespace tt datafile '/u01/app/oracle/oradata/orcl/tt01.dbf' size 1M; SQL> conn scott/tiger SQL> create table tt tablespace tt as select * from dept; SQL> !rm -rf /u01/app/oracle/oradata/orcl/tt01.dbf SQL> conn /as sysdba SQL> alter system flush buffer_cache; SQL> conn scott/tiger SQL> select * from tt;
使用rman进行恢复:
[oracle@oracle u01]$ rman target / RMAN> run { sql 'alter database datafile 6 offline'; restore datafile 6; recover datafile 6; sql 'alter database datafile 6 online'; } [oracle@oracle u01]$ sqlplus scott/tiger SQL> select * from tt;
使用RMAN进行不完全恢复
基于SCN的不完全恢复
模拟损坏:
[oracle@oracle ~]$ sqlplus scott/tiger; SQL> select * from tab; SQL> drop table emp purge; SQL> create table t as select * from dept; SQL> conn / as sysdba; SQL> select 'execute dbms_logmnr.add_logfile('''||member||''')' from v$logfile; SQL> exec dbms_logmnr.start_logmnr(); SQL> select scn,sql_redo from v$logmnr_contents where seg_name='EMP' and seg_owner='SCOTT' and sql_redo like '%drop table emp%';
使用rman进行恢复:
RMAN> run{ shutdown immediate; startup mount; set until scn=1409215; restore database; recover database; sql 'alter database open resetlogs'; } SQL> select * from tab;
emp回来了,但是t表没了
使用备份的控制文件的不完全恢复
SQL> drop tablespace tt including contents and datafiles; SQL> select 'execute dbms_logmnr.add_logfile('''||member||''')' from v$logfile; SQL> exec dbms_logmnr.start_logmnr(); SQL> select scn,sql_redo from v$logmnr_contents where sql_redo like '%drop%';
使用rman进行恢复:
RMAN> shutdown immediate; RMAN> startup nomount; RMAN> restore controlfile from '/u01/backup/rmanbk/ORCL_200.dbf'; RMAN> sql 'alter database mount'; RMAN> run{ set until scn=1411525; restore database; recover database; sql 'alter database open resetlogs'; } [oracle@oracle rmanbk]$ sqlplus / as sysdba SQL> select name from v$tablespace; SQL> select name from v$datafile; SQL> conn scott/tiger SQL> select * from tt;
所有文件丢失的恢复
模拟损坏:
[oracle@oracle ~]sqlplus / as sysdba SQL> shutdown abort; SQL> !cd $ORACLE_BASE/oradata/orcl; SQL> !rm -rf *; SQL> !cd $ORACLE_HOME/dbs; SQL> !rm -rf *orcl*;
执行恢复:
[oracle@oracle dbs]$ echo $ORACLE_SID [oracle@oracle dbs]$ sqlplus / as sysdba SQL> startup; [oracle@oracle dbs]$ cd $ORACLE_HOME/dbs vi initorcl.ora--写入如下内容: db_name=orcl 保存退出 SQL> startup nomount--启动实例 SQL> exit [oracle@oracle dbs]$ rman target / RMAN> restore spfile from '/u01/backup/rmanbk/ORCL_209.dbf';--恢复参数文件 RMAN> shutdown abort RMAN> startup nomount--使用恢复的参数文件启动实例 RMAN> restore controlfile from '/u01/backup/rmanbk/ORCL_209.dbf'; --恢复控制文件 恢复数据文件: RMAN> sql 'alter database mount'; RMAN> run { restore database; recover database; } RMAN> exit 由于在线日志被删除,所以不能进行完全恢复,进行cancel恢复: [oracle@oracle dbs]$ sqlplus / as sysdba SQL> recover database until cancel; SQL> recover database until cancel using backup controlfile; Specify log: {<RET>=suggested | filename | AUTO | CANCEL} cancel SQL> alter database open resetlogs;
使用增量更新备份进行恢复
RMAN> RUN { RECOVER COPY OF DATABASE WITH TAG 'incr_update'; BACKUP INCREMENTAL LEVEL 1 FOR RECOVER OF COPY WITH TAG 'incr_update' DATABASE; }
为了理解上述脚本,我们先看一下如果没有数据文件拷贝和增量备份运行这两个脚本的情况
如果需要恢复,我们首先恢复镜像文件拷贝和最后一次LEVEL1增量备份,最后应用REDO
第一次执行:先对数据库中文件执行镜像备份
RMAN> RUN { RECOVER COPY OF DATABASE WITH TAG 'incr_update'; BACKUP INCREMENTAL LEVEL 1 FOR RECOVER OF COPY WITH TAG 'incr_update' DATABASE; } SQL> conn scott/tiger; SQL> create table t1 as select * from emp;
第二次执行:使用增量备份,对所有的数据文件执行恢复,但是此时没有增量备份,然后对数据库执行增量1级备份
RMAN> RUN { RECOVER COPY OF DATABASE WITH TAG 'incr_update'; BACKUP INCREMENTAL LEVEL 1 FOR RECOVER OF COPY WITH TAG 'incr_update' DATABASE; }
第三次备份:使用增量备份,对所有的数据文件执行恢复,此时增量备份,然后对数据库执行增量1级备份
RMAN> RUN { RECOVER COPY OF DATABASE WITH TAG 'incr_update'; BACKUP INCREMENTAL LEVEL 1 FOR RECOVER OF COPY WITH TAG 'incr_update' DATABASE; }
如果此时数据库发生了故障,可以只恢复最近一次的增量1级备份和归档日志
使用镜像切换进行快速恢复
rman target / RMAN> backup as copy tablespace users format='/u01/app/oracle/backup/rmanbk/%d_%s.dbf';
模拟损害:
SQL> !rm -rf /u01/app/oracle/oradata/orcl/users01.dbf SQL> conn scott/tiger SQL> select * from emp
使用镜像切换进行恢复:
rman target / RMAN> run{ sql 'alter tablespace users offline immediate'; SET NEWNAME FOR DATAFILE '/u01/app/oracle/oradata/orcl/users01.dbf' TO '/u01/app/oracle/backup/rmanbk/users01.dbf'; restore tablespace users; switch datafile all; recover tablespace users; sql 'alter tablespace users online'; }
可以将备份恢复到新的位置:
RMAN> run{ sql 'alter tablespace users offline immediate'; SET NEWNAME FOR DATAFILE '/u01/app/oracle/oradata/orcl/users01.dbf' TO '/u01/app/oracle/oradata/users01.dbf'; restore tablespace users; switch datafile all; recover tablespace users; sql 'alter tablespace users online'; } SQL> select file_name from dba_data_files where tablespace_name='USERS';
改回原来的位置:
RMAN> run{ sql 'alter tablespace users offline immediate'; SET NEWNAME FOR DATAFILE '/u01/app/oracle/oradata/users01.dbf' TO '/u01/app/oracle/oradata/orcl/users01.dbf'; restore tablespace users; switch datafile all; recover tablespace users; sql 'alter tablespace users online'; } SQL> select file_name from dba_data_files where tablespace_name='USERS';
参数文件丢失的恢复
模拟损害:
[oracle@oracle dbs]$ cd $ORACLE_HOME/dbs [oracle@oracle dbs]$ rm -rf spfileorcl.ora
执行恢复:
基于内存中的参数值创建spfile:
SQL> create spfile='/u01/app/oracle/spfileorcl.ora' from memory;
将恢复的参数文件复制到原来的位置:
[oracle@oracle dbs]$ cp /u01/app/oracle/spfileorcl.ora $ORACLE_HOME/dbs
转储数据库到新的主机
使用rman复制数据库
有一个orcl数据库的备份,使用这个备份,复制数据库名为hndx
创建pfile:
[oracle@oracle dbs]$ sqlplus / as sysdba SQL> create pfile='$ORACLE_HOME/dbs/inithndx.ora' from spfile;
编辑pfile:
[oracle@oracle dbs]$ cd $ORACLE_HOME/dbs [oracle@oracle dbs]$ vi inithndx.ora 将orcl替换为hndx :%s/orcl/hndx/g
创建目录:
[oracle@oracle dbs]$ mkdir -p /u01/app/oracle/oradata/hndx [oracle@oracle dbs]$ mkdir -p $ORACLE_BASE/admin/hndx/{a,b,c,u}dump
启动hndx实例:
[oracle@oracle ~]$ export ORACLE_SID=hndx [oracle@oracle ~]$ sqlplus / as sysdba SQL> create spfile from pfile; SQL> startup nomount;
使用rman复制数据库hndx:
对hndx进行静态注册:
[oracle@oracle dbs]$ cd $ORACLE_HOME/network/admin vi listener.ora SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = PLSExtProc) (ORACLE_HOME = /u01/app/oracle/product/11.2/db_1) (PROGRAM = extproc) ) (SID_DESC = (SID_NAME = hndx) (ORACLE_HOME = /u01/app/oracle/product/11.2/db_1) (GLOBAL_DBNAME=hndx) ) )
创建hndx网路连接符:
[oracle@oracle dbs]$ vi tnsnames.ora hndx= (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = hndx) ) )
为hndx创建口令文件:
[oracle@oracle ~]$ orapwd file=$ORACLE_HOME/dbs/orapwhndx password=a [oracle@oracle ~]$ rman target sys/a@orcl auxiliary sys/a@hndx
RMAN> run { allocate auxiliary channel aux1 device type disk; allocate auxiliary channel aux2 device type disk; allocate auxiliary channel aux3 device type disk; duplicate target database to hndx db_file_name_convert=('/u01/app/oracle/oradata/orcl/','/u01/app/oracle/oradata/hndx/') logfile group 1('/u01/app/oracle/oradata/hndx/redo01.log') size 50M, group 2('/u01/app/oracle/oradata/hndx/redo02.log') size 50M, group 3('/u01/app/oracle/oradata/hndx/redo03.log') size 50M; } [oracle@oracle admin]$ export ORACLE_SID=hndx [oracle@oracle admin]$ sqlplus / as sysdba SQL> select name from v$database; SQL> select instance_name from v$instance;
使用增量备份恢复NOARCHIVELOG模式的数据库
将数据库改为非归档:
SQL> shutdown immediate SQL> startup mount SQL> alter database noarchivelog; SQL> alter database open;
对数据库做增量备份:
打开控制文件的自动备份:
rman target / run { shutdown immediate; startup mount; backup incremental level 0 database; alter database open; } run { shutdown immediate; startup mount; backup incremental level 1 database; alter database open; }
删除所有的数据文件:
[oracle@oracle admin]$ cd $ORACLE_BASE/oradata/orcl [oracle@oracle admin]$ rm -rf *dbf
执行恢复:
run{ STARTUP FORCE NOMOUNT; RESTORE CONTROLFILE from autobackup; ALTER DATABASE MOUNT; RESTORE DATABASE; RECOVER DATABASE NOREDO; ALTER DATABASE OPEN RESETLOGS; }
--------------------------------------------------------------------------------------------------------------------
使用RMAN的RESTORE和RECOVER命令
RESTORE {DATABASE | TABLESPACE name [,name]... | DATAFILE name [,name] }...
RECOVER {DATABASE | TABLESPACE name [,name]... | DATAFILE name [,name] }...
RMAN> SQL 'ALTER TABLESPACE inv_tbs OFFLINE IMMEDIATE';
RMAN> RESTORE TABLESPACE inv_tbs;
RMAN> RECOVER TABLESPACE inv_tbs;
RMAN> SQL 'ALTER TABLESPACE inv_tbs ONLINE';
执行完全恢复:归档模式下丢失数据文件
1.如果实例没有关闭,关闭实例
2.Mount数据库。
3.拷贝请别恢复丢失的数据文件
4.打开数据库
恢复镜像拷贝
RMAN> REVOCER COPY OF DATAFILE {n | 'file_name'}
RMAN> recover copy of database with tag 'daily_inc';
RMAN> backup incremental level 1 for recover of copy with tag 'daily_inc' database;
RECOVER | BACKUP | |
Day 1 | Nothing | Create image copies |
Day 2 | Nothing | Create incremental Level 1 |
Day 3 onward | Recover copies based on incremental | Create incremental Level 2 |
执行快速切换到镜像拷贝操作
1.将数据文件离线
2.使用SWITCH TO ... COPY命令切换到镜像拷贝
SQL> SWITCH DATAFILE 'filename' TO COPY;
3.恢复数据文件
4.使数据文件在线。现在数据文件在新的位置被恢复和使用。
可选下列操作将文件放到原来位置
5.在原始位置创建镜像拷贝
6.将数据文件离线
7.使用SWITCH TO ... COPY
8.恢复数据文件
9.使数据文件在线
run {
allocate channel dev1 device type disk;
allocate channel dev2 device type sbt;
sql 'alter tablespace users offline immediate';
set newname for datafile '/disk1/oradata/prod/users01.dbf' to '/disk2/users01.dbf';
restore tablespace users;
switch datafile all;
recover tablespace users;
sql 'alter tablespace users online';
}
在非归档模式下执行恢复
1.关闭实例
2.从备份位置恢复整个数据库,包括所有数据文件和控制文件
3.打开数据库
使用恢复点
SQL> CREATE RESTORE POINT before_mods; (Now)
SQL> CREATE RESTORE POINT end_q1 AS OF SCN 100; (Some time in the past)
执行指定时间点恢复
1. 确定恢复的目标点: SCN, 时间, 恢复点, 或者日志的序列号
2. 设定正确的NLS环境变量
$ export NLS_LANG = american_america.us7ascii
$ export NLS_DATE_FORMAT = "yyyy-mm-dd:hh24:mi:ss"
3. Mount数据库
RMAN> shutdown immediate
RMAN> startup mount
4. 准备和运行RUN程序块
RMAN> RUN
{
SET UNTIL TIME '2007-08-14:21:59:00';
RESTORE DATABASE;
RECOVER DATABASE;
}
5.将数据库打开到READONLY模式,确定恢复到了正确的目标点
RMAN> SQL 'ALTER DATABASE OPEN READ ONLY';
6. 使用RESETLOGS参数打开数据库.
RMAN> ALTER DATABASE OPEN RESETLOGS;
从服务端丢失参数文件中恢复
SQL> CREATE PFILE [= 'pfile_name' ] FROM {{SPFILE [= 'spfile_name']} | MEMORY };
SQL> CREATE SPFILE [= 'spfile_name' ] FROM {{PFILE [= 'pfile_name']} | MEMORY };
从自动备份的控制文件中恢复服务端参数文件
RESTORE SPFILE TO <file_name> FROM AUTOBACKUP
RMAN> STARTUP FORCE NOMOUNT;
RMAN> RESTORE SPFILE FROM AUTOBACKUP;
RMAN> STARTUP FORCE;
从FRA中恢复
RMAN> run {
2> restore spfile from autobackup
3> recovery area = '<flash recovery area destination>'
4> db_name = '<db_name>';
5> }
从自动备份中恢复控制文件
RMAN> STARTUP NOMOUNT;
RMAN> RESTORE CONTROLFILE FROM AUTOBACKUP;
RMAN> ALTER DATABASE MOUNT;
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN RESETLOGS;
在非归档模式下使用增量备份恢复数据库
STARTUP FORCE NOMOUNT;
RESTORE CONTROLFILE;
ALTER DATABASE MOUNT;
RESTORE DATABASE;
RECOVER DATABASE NOREDO;
ALTER DATABASE OPEN RESETLOGS;
在另一台服务器上进行恢复
可以执行恢复测试
可以将生产数据库移到新的服务器
准备
1.记录源数据库的数据库ID(DBID)
2.拷贝源数据库初始化参数文件到新的服务器
3.确保源数据库备份,包括自动备份的控制文件,可以从新的恢复服务器访问
在新的服务器进行恢复
1.配置ORACLE_SID环境变量
$ setenv ORACLE_SID orcl
2.启动RMAN并且连接到非归档模式下的目标实例
$ rman TARGET /
3.设定DBID,可以从V$DATABASE中查询源数据库DBID
RMAN> SET DBID 1090770270;
4.将实例启动到NOMOUNT模式下
RMAN> STARTUP NOMOUNT
5.从备份集中恢复服务端参数文件
RMAN> RESTORE SPFILE TO PFILE '?/oradata/test/initorcl.ora' FROM AUTOBACKUP;
6.关闭实例
SHUTDOWN IMMEDIATE;
7.编辑恢复的初始化参数文件
8.将实例启动到MOUNT模式下
RMAN> STARTUP NOMOUNT PFILE='?/oradata/test/initorcl.ora';
9.创建RUN程序块以恢复控制文件和mount数据库
RUN
{
RESTORE CONTROLFILE FROM AUTOBACKUP;
ALTER DATABASE MOUNT;
}
10.创建RMAN恢复脚本用以恢复数据库
RUN
{
SET NEWNAME FOR DATAFILE 1 TO '?/oradata/test/system01.dbf';
SET NEWNAME FOR DATAFILE 2 TO '?/oradata/test/undotbs01.dbf';
SET NEWNAME FOR DATAFILE 3 TO '?/oradata/test/sysaux.dbf';
SET NEWNAME FOR DATAFILE 4 TO '?/oradata/test/users01.dbf';
SET NEWNAME FOR DATAFILE 5 TO '?/oradata/test/example01.dbf';
SQL "ALTER DATABASE RENAME FILE '/u01/app/oracle/oradata/orcl/redo01.log' TO '?/oradata/test/redo01.log' ";
SQL "ALTER DATABASE RENAME FILE '/u01/app/oracle/oradata/orcl/redo02.log' TO '?/oradata/test/redo02.log' ";
SQL "ALTER DATABASE RENAME FILE ''/u01/app/oracle/oradata/orcl/redo03.log'' TO '?/oradata/test/redo03.log' ";
SET UNTIL SCN 4545727;
RESTORE DATABASE;
SWITCH DATAFILE ALL;
RECOVER DATABASE;
}
11.执行恢复脚本
12.使用RESETLOGS选项打开数据库
RMAN> ALTER DATABASE OPEN RESETLOGS;
执行灾难恢复
灾难意味着丢失了整个目标数据库,恢复目录数据库,所有当前控制文件,所有在线重做日志以及所有参数文件。
灾难恢复包括目标数据库的restoreation和recovery
执行灾难恢复要求的最小备份集
1.数据文件备份
2.相应的归档重做日志文件
3.至少一份自动备份的控制文件
基本过程
1.恢复自动备份的服务端参数文件
2.启动目标数据库实例
3.从自动备份中恢复控制文件
4.Mount数据库
5.Restore数据文件
6.Recover数据文件
7.用RESETLOGS选项打开数据库
备注:
当使用RESTORE命令时,从备份恢复了数据文件,但是还没有从重做日志中应用前滚
备份脚本
cd /u01/app/oracle
vi rman.sh写入以下内容:
rman target / <<eof
run{
delete noprompt backup;
backup database plus archivelog;
}
exit
echo "backup is ok"
eof
保存
授予权限:chmod +x rman.sh
执行:./rman.sh
system表空间文件丢失的恢复:
模拟损坏:
conn /as sysdba
create table t as select * from scott.dept;
!rm -rf /u01/app/oracle/oradata/orcl/system01.dbf
alter system flush buffer_cache;
[oracle@oracle u01]$ ps -ef | grep dbw
oracle 4233 1 0 15:30 ? 00:00:00 ora_dbw0_orcl
oracle 6272 4195 1 17:03 pts/1 00:00:00 grep dbw
[oracle@oracle u01]$ kill -9 4233
[oracle@oracle u01]$ rman target /
RMAN> startup mount
RMAN> run{
2> restore datafile 1;
3> recover datafile 1;
4> sql 'alter database open';
5> }
[oracle@oracle u01]$ sqlplus / as sysdba
SQL> select * from t;
发现t表仍然存在,完全恢复
undo表空间文件丢失的恢复:
模拟损坏:
SQL> !rm -rf /u01/app/oracle/oradata/orcl/undotbs01.dbf
SQL> alter system flush buffer_cache;
SQL> conn scott/tiger
SQL> update emp set sal=sal+100; --error
使用rman进行恢复:
[oracle@oracle u01]$ rman target /
RMAN> run{
2> shutdown abort
3> startup mount
4> restore datafile 2;
5> recover datafile 2;
6> sql 'alter database open';
7> }
[oracle@oracle u01]$ sqlplus scott/tiger
普通表空间文件丢失的恢复:
模拟损坏:
SQL> create table t3 as select * from dept;
SQL> !rm -rf /u01/app/oracle/oradata/orcl/users01.dbf
SQL> select * from t3;
SQL> conn /as sysdba
SQL> alter system flush buffer_cache;
SQL> conn scott/tiger
SQL> select * from t3;-error
使用rman进行恢复:
rman target /
RMAN> run{
2> sql 'alter database datafile 4 offline';
3> restore datafile 4;
4> recover datafile 4;
5> sql 'alter database datafile 4 online';
6> }
[oracle@oracle u01]$ sqlplus scott/tiger
SQL> select * from t3;
未备份的数据文件丢失的恢复:
模拟损坏:
create tablespace tt datafile '/u01/app/oracle/oradata/orcl/tt01.dbf' size 1M;
conn scott/tiger
create table tt tablespace tt as select * from dept;
SQL> !rm -rf /u01/app/oracle/oradata/orcl/tt01.dbf
SQL> conn /as sysdba
SQL> alter system flush buffer_cache;
SQL> conn scott/tiger
SQL> select * from tt; --error
使用rman进行恢复:
[oracle@oracle u01]$ rman target /
RMAN> run {
2> sql 'alter database datafile 6 offline';
3> restore datafile 6;
4> recover datafile 6;
5> sql 'alter database datafile 6 online';
6> }
[oracle@oracle u01]$ sqlplus scott/tiger
SQL> select * from tt;