适用场景
(1)恢复错误的dml语句
(2)恢复错误的ddl语句,比如说更改了表结构,这个时候无法使用flashback table
(3)恢复drop+purge的表 (只是drop 可以使用闪回删除 flashback table xxx to before drop ;)
(4)恢复逻辑错误的表
(5)恢复被删除的表空间(rman可以在被drop的表空间上面执行TSPITR)
TSPITR的限制
1)你不能将其应用到SYSTEM表空间和UNDO表空间,或者任何包括回滚段的表空间上。
会报ORA-39917 错误 (如果报这个错,证明在AA表空间中这个表的拥有者是SYS ,但是表空间时间点恢复不能恢复system表空间,所以不能使用,如果是索引的话可以先删除。)
总结:拥有者是SYS 的表不能恢复。
2)包含相互依赖数据的多个表空间必须被一起同时恢复。例如:你要即时恢复拥有索引的表空间的话,必须和索引所引用的基表所在的表空间一起同时做时间点恢复,(还可以先把索引删除,恢复后再重新创建)
注意:恢复集表空间必须为自包含;
违反自包含表空间集合的常见情况如下:
1> 表空间集合包含有SYS 方案对象
2>表空间集合包含了索引所在的表空间,但没有包含索引基表所在的表空间
3>表空间集合没有包含分区表的所有分区
4> 表空间集合包含了表所在的表空间,但没有包含其LOB 列所在的表空间
检查自包含方式:
SQL> connect sys/oracle@demo as sysdba
SQL> executedbms_tts.transport_set_check(‘user01’,true);
SQL> Select * From transport_set_violations;
TSPITR 相关的概念:
(1) TSPITR (Tablespace Point-In-Time Recover)。TSPITR 是表空间时间点恢复的英文缩写格式,它表示将一个或多个表空间恢复到过去时间点的状态,而其他表空间仍然保持现有状态。
(2) TSPITR 实现方法。当实现表空间时间点恢复时,既可以使用用户管理的表空间时间点恢复方法,也可以使用RMAN 管理的表空间时间点恢复。
(3) DBPITR (Database Point-In-Time Recovery)。DBPITR 是数据库时间点恢复的英文缩写格式,它表示将数据库的所有表空间恢复到过去时间点的状态。注意,DBPITR 只适用于ARCHIVELOG 模式。
(4) 主数据库(Primary Database)。当执行TSPITR 时,主数据库是指包含被恢复表空间的数据库。也就是当前正在使用的数据库
(5) 恢复集(Recovery Set):需要恢复的表空间的集合。注意,当在恢复集的表空间上执行TSPITR 时,要求这些表空间必须是自包含的。
(6) 辅助数据库(Auxiliary Database)。辅助数据库是主数据库的一个副本数据库。当执行TSPITR 时,辅助数据库用于将恢复集表空间恢复到过去时间点。注意,辅助数据库的所有物理文件都是从主数据库备份中取得,并且辅助数据库必须包含SYSTEM 表空间、UNDO 表空间以及恢复集表空间的备份文件。(恢复结束后会自动删除辅助数据库的所有物理文件)
(7) 辅助集(Auxiliary Set)。辅助集是指辅助数据库所需要的、除了恢复集表空间文件之外的其他文件集合。当执行 TSPITR 时,辅助数据库除了需要恢复集表空间的备份文件之外,还需要备份控制文件、SYSTEM 表空间的备份文件、UNDO 表空间的备份文件。
实验:
1.备份数据库
恢复之前先备份
创建表空间
SYS@ghyyk> create tablespace AAA datafile ‘+data’ size 20m autoextend on ;
RMAN> report schema;
6 20 AA *** +DATA/ghyyk/datafile/aa.262.103304359
RMAN> backup as compressed backupset full database include current controlfile plus archivelog delete all input;
RMAN>list backupset
RMAN> list backupset summary;
2 建立测试表并做truncate误操作
AA表空间下建立2个表,并建立一个索引在users表空间中,注意做误操作之前先切换一下日志。
(必须重新创建一个用户,不能在sys用户下创建这两张表,把新建用户创建到AA表空间上)
create user hjj identified by oracle;
grant dba to hjj;
SQL> alter system switch logfile;
SQL> alter system switch logfile;
create table hjj.tspitr_test111 tablespace AAA as select * from test221;
SYS@ghyyk> select count(*) from hjj.tspitr_test111;
COUNT(*)
107
SYS@ghyyk> create table hjj.tspitr_test112 tablespace AAA as select * from test221 where rownum<=2;
Table created.
SYS@ghyyk> select count(*) from hjj.tspitr_test112;
COUNT(*)
2
SYS@ghyyk> create index tspitr_test111_index on hjj.tspitr_test111(EMPLOYEE_ID) tablespace users;
Index created.
SYS@ghyyk> alter system switch logfile;
System altered.
SYS@ghyyk> select group#,status,archived from v$log;
GROUP# STATUS ARC
1 CURRENT NO
2 ACTIVE YES
3 ACTIVE YES
4 ACTIVE YES
删除测试表 tspitr_test222
SYS@ghyyk> truncate table hjj.tspitr_test111;
Table truncated.
SYS@ghyyk> select * from hjj.tspitr_test111;
no rows selected
SYS@ghyyk> select group#,member from v$logfile;
GROUP#
----------
MEMBER
--------------------------------------------------------------------------------
2
+DATA/ghyyk/onlinelog/group_2.271.1032375791
2
+FRA/ghyyk/onlinelog/group_2.306.1032375791
1
+DATA/ghyyk/onlinelog/group_1.272.1032375789
GROUP#
----------
MEMBER
--------------------------------------------------------------------------------
1
+FRA/ghyyk/onlinelog/group_1.305.1032375789
3
+DATA/ghyyk/onlinelog/group_3.260.1032375791
3
+FRA/ghyyk/onlinelog/group_3.307.1032375793
GROUP#
----------
MEMBER
--------------------------------------------------------------------------------
4
+DATA/ghyyk/onlinelog/group_4.261.1032375793
4
+FRA/ghyyk/onlinelog/group_4.308.1032375795
8 rows selected.
SYS@ghyyk> create table hjj.tspitr_test114 tablespace AAA as select * from test221;
Table created.
SYS@ghyyk> create table hjj.tspitr_test115 tablespace AAA as select * from test221;
Table created.
SYS@ghyyk> create table hjj.tspitr_test116 tablespace AAA as select * from test221;
Table created.
3 采用logmner找回误删除的时间点
通过v
l
o
g
v
log v
logvlogfile 定位到大致误删除是在哪个redo文件中,使用logmnr查找
select group#,status,archived from v$log;
select group#,member from v$logfile;
execute dbms_logmnr.add_logfile(’+DATA/ghyyk/onlinelog/group_4.261.1032375793’,dbms_logmnr.new);
SYS@ghyyk> exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
SYS@ghyyk> select a.SCN,a.TIMESTAMP,a.sql_REDO from v$logmnr_contents a where table_name=‘TSPITR_TEST111’ and OPERATION=‘DDL’ order by a.SCN;
要大写表名
1182330 2020-02-22 18:11:26
truncate table hjj.tspitr_test111;
4 执行TSPITR之前的检查
检查是否自包含
SYS@ghyyk> BEGIN
2 SYS.DBMS_TTS.TRANSPORT_SET_CHECK(‘AAA’, TRUE, TRUE);
3 END;
4 /
PL/SQL procedure successfully completed.
SYS@ghyyk> select * from SYS.TRANSPORT_SET_VIOLATIONS;
ORA-39907: Index SYS.TSPITR_TEST111_INDEX in tablespace USERS points to table HJ
J.TSPITR_TEST111 in tablespace AAA.
VIOLATIONS
ORA-39917: SYS owned object TSPITR_TEST223 in tablespace AA not allowed in plugg
able set
(如果报这个错,证明在AA表空间中属主是SYS ,但是表空间时间点恢复不能恢复system表空间,所以不能使用,如果是索引的话可以先删除。)
还可以这样去检查:
select * from SYS.TS_PITR_CHECK a WHERE a.ts1_name=‘AA’;
说明,有一个索引 LHR…TSPITR_TEST_INDEX在users表空间中,那么我们删除这个索引,等待恢复完成后再重建该索引。
SQL> drop index SYS.TSPITR_TEST111_INDEX;
SYS@ghyyk> BEGIN
2 SYS.DBMS_TTS.TRANSPORT_SET_CHECK(‘AAA’, TRUE, TRUE);
3 END;
4 /
PL/SQL procedure successfully completed.
SYS@ghyyk> select * from SYS.TRANSPORT_SET_VIOLATIONS;
至此,自包含问题已解决。
5.检查哪些对象执行TSPITR后将被删除
select * from SYS.TS_PITR_OBJECTS_TO_BE_DROPPED A WHERE a.tablespace_name=‘AAA’ and a.creation_time>=‘2020-02-22 18:11:26’;
HJJ TSPITR_TEST114
2020-02-22 18:12:23 AAA
HJJ TSPITR_TEST115
2020-02-22 18:12:27 AAA
HJJ TSPITR_TEST116
2020-02-22 18:12:33 AAA
则说明若执行TSPITR后,AA表空间中的表TSPITR_TEST114、TSPITR_TEST115、TSPITR_TEST116将被删除,那么为了保存这些对象我们将其利用expdp导出备份,等待tspitr执行完毕后再导入回来即可。
SYS@ghyyk> create directory data_pump_dirs as ‘/home/oracle/data_pump’;
SYS@ghyyk> grant read ,write on directory data_pump_dirs to public;
expdp hjj/oracle directory=DATA_PUMP_DIRS dumpfile=exptable_tspitrlhr.dmp TABLES=TSPITR_TEST114,TSPITR_TEST115,TSPITR_TEST116 LOGFILE=exptable_tspitrlhr.log
6.执行TSPITR
不用重启数据库,在线进行表空间恢复
recover tablespace AAA until time “to_date(‘2020-02-22 18:11:26’,‘YYYY-MM-DD HH24:mi:ss’)” auxiliary destination ‘/home/oracle/auxdest’;
7.online表空间并且导入丢失的对象
执行完恢复之后,表空间处于offline状态,需要将表空间online。
SYS@ghyyk> select * from hjj.TSPITR_TEST111;
select * from hjj.TSPITR_TEST111
*
ERROR at line 1:
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: ‘+DATA/ghyyk/datafile/aaa.263.1033063463’
SYS@ghyyk> alter tablespace aaa online;
Tablespace altered.
SYS@ghyyk> select count(*) from hjj.TSPITR_TEST111;
COUNT(*)
107
SYS@ghyyk> select * From hjj.TSPITR_TEST113;
select * From hjj.TSPITR_TEST113
*
ERROR at line 1:
ORA-00942: table or view does not exist
数据已经恢复,可是hjj.TSPITR_TEST113丢失,下边我们来导入备份的数据
impdp hjj/oracle directory=data_pump_dirs dumpfile=exptable.dmp tables=TSPITR_TEST114,TSPITR_TEST115,TSPITR_TEST116 LOGFILE=imptable.log
HJJ@ghyyk> select FILE#,CHECKPOINT_CHANGE# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1184810
2 1184810
3 1184810
4 1184810
5 1184810
6 1178037
7 1185794
7 rows selected.
HJJ@ghyyk> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1184810
2 1184810
3 1184810
4 1184810
5 1184810
6 1178340
7 1185794
7 rows selected.
表空间所在6号数据文件的scn恢复到了之前时间点的scn,发其他的数据文件还是现在的scn。
表空间相关表完全恢复到过去时间点
12c新特性:Recover Table 在版本12c之前单独恢复Oracle中某一张表,常规的方法是TSPITR或Flashback闪回。在版本12c中提供了Table Recovery单独恢复表的RMAN特性,该特性用以直接从RMAN backup中恢复table的方法,该特性的特点:
不影响数据库中的其他数据库对象
减少时间和磁盘空间的消耗,和早期的TSPIRT工作流程类似:
从另一个磁盘路径恢复表空间
导出想要的表数据
导入到原数据库
在何种场景下值得考虑使用该rman table recovery特性恢复单个表或分区的数据:
在下列场景中不建议使用TSPITR特性,但是建议用12c的table recovery特性:
少数几个表需要恢复
非子包含的表空间
在下列条件中不可能使用闪回,但是可以用12c的table recovery特性:
purge掉的表,不再可能flashback drop
必要的undo已经被覆盖的情况,不再可能flashback table
经过一些结构化的DDL变更后,不再可能flashback table