12.3 主动恢复
主动不完全恢复是将数据库“撤回”到从前的传统方法,主要用来撤销认为修改。一般需要先判断PIT点的时间或SCN
--1 重启db到mount状态
--2 用restore将所有的数据文件还原到PIT点之前
--3 用recover命令将数据库恢复到PIT点
--4 用resetlogs方式打开数据库。
场景1: 10分钟前,人为truncate了某些重要的表,业务无法运行,
使用RMAN命令可将数据库恢复到10分钟之前:
RMAN> run { startup force mount; set until time "sysdate-interval '10' minute"; restore database; recover database; alter database open resetlogs; }
必须注意“unti time”的PIT目标不一定是极其准确的。
场景2:执行了一个批处理脚本,该脚本将对很多吧进行了大量的不确定性修改。现在需要将批处理的修改结果撤销。
解决这样的问题,最好能在执行批处理之前记录一下当前的SCN以便将来使用until scn不完全恢复,这样处理比较严谨,因为使用until time存在3秒定位问题,使用until time时oracle还要先将时间转换成SCN,这样做只有3秒的精确度。
SQL> set linesize 99 SQL> select timestamp_to_scn(systimestamp-to_dsinterval('00 00:00:0'||level)) SCN, systimestamp-to_dsinterval('00 00:00:0'||level) TIME from dual connect by level <10; 2 3 4 SCN TIME ---------- --------------------------------------------------------------------------- 1196059 29-JUL-19 10.21.50.751565000 AM +08:00 1196059 29-JUL-19 10.21.49.751565000 AM +08:00 1196058 29-JUL-19 10.21.48.751565000 AM +08:00 1196058 29-JUL-19 10.21.47.751565000 AM +08:00 1196058 29-JUL-19 10.21.46.751565000 AM +08:00 1196057 29-JUL-19 10.21.45.751565000 AM +08:00 1196057 29-JUL-19 10.21.44.751565000 AM +08:00 1196057 29-JUL-19 10.21.43.751565000 AM +08:00 1196056 29-JUL-19 10.21.42.751565000 AM +08:00
在批处理开始之前,查询到SCN
SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1195995
或是直接对当前的SCN号取别名,即在控制文件中创建一个还原点
SQL> create restore point before_batch;
这样,若在批处理后需要撤销
RMAN> run { startup force mount; set until scn 1195995; restore database; recover database; alter database open resetlogs; }
或者
RMAN> run { startup force mount; set until restore point before_batch; restore database; recover database; alter database open resetlogs; }
另外,还原点可以被删除
SQL> drop restore point before_batch;
12.4 数据库的incarnation
既然不完全恢复可以让数据库回到过去,那么能否利用不完全恢复让数据库回到resetlogs打开数据库之前呢?
数据库的每一次resetlogs(不完全恢复)都会创建一个新的incarnation
SQL> select * from v$database_incarnation; RMAN> list incarnation; List of Database Incarnations DB Key Inc Key DB Name DB ID STATUS Reset SCN Reset Time ------- ------- -------- ---------------- --- ---------- ---------- 1 1 ORCL 1542322764 PARENT 1 25-JUL-19 2 2 ORCL 1542322764 PARENT 1013511 25-JUL-19 3 3 ORCL 1542322764 CURRENT 1055594 25-JUL-19
结果发现当前的incarnation编号是3,时间发生在SCN为1055594
现在尝试利用不完全恢复回到SCN是1051693
RMAN> run { startup force mount; set until scn 1051693; restore database; recover database; alter database open resetlogs; } RMAN-03002: failure of restore command at ... RMAN-06004: ORACLE error from recovery catalog database:RMAN-20208: UNTIL CHANGE is before RESETLOGS change
RMAN报错06004,表示不可能回到resetlogs之前
RMAN> reset database to incarnation 2; ##进入incarnation为2 RMAN> run { startup force mount; set until scn 1051693; restore database; recover database; alter database open resetlogs; }
注意,以上操作是在使用catalog的情况下进行,若仅仅使用控制文件作为RMAN资料库,理论上可行,但却不太实际。
因为让数据库回到之前的incarnation就需要当时的备份及其归档日志,可能只有catalog才能保留那么多的资料,单凭控制文件可能会有些问题。
12.5 小范围不完全恢复
比如以不完全恢复一张表,dba可以完全不需要在生产库上做,在另外一个数据库上进行不完全恢复(首先按照参数文件,控制文件,控制文件的顺序还原数据库),在新的数据库上进行不完全恢复,完成导出这张表,再导入生产库。
Oracle在RMAN中实现了一个全自动的表空间一级的不完全恢复命令
recover tablespace .. until
将一个命名为test1的表空间不完全恢复到15分钟前
RMAN> recover tablespace test1 until time “sysdate - interval ‘15’ minute” auxiliary destination ‘/u01/app/oracle/oradata/aux/’;
其中auxiliary destination 是克隆数据库必要文件的临时保存目录,包括其控制文件,关键数据文件、重做日志等。该命令自动为克隆数据库及其实例分别命名,
并将控制文件、system、sysaux、undotbs1表空间的数据文件还原到‘/u01/app/oracle/oradata/aux/’目录的子目录下,将test1表空间的数据文件还原到原路径,
其余数据文件一律下线,然后在克隆库上(只包含system、sysaux、undotbs1和test1表空间)进行PIT点位15分钟前的不完全恢复,待使用resetlogs打开克隆数据库后,
再使用expdp的可传输表空间功能将test1表空间迁移到目标库,最后关闭克隆库。
小结:
虽然实际生产环境中很少使用不完全恢复,这里还是介绍了不完全恢复的原理和使用方式,并介绍了incarnation。
--被动不完全恢复的主要原因是日志的丢失或损坏,所以采用精确到日志文件的形式(until sequence,until cancel),
--主动恢复是因为日志大多数情况下无损,采用精确到重做记录的形式(until time,until scn/change)
不完全恢复绝非解决问题的首选方案。