Oracle19c 误删除恢复(PDB指定表空间恢复)

一、问题背景:

        5月20日客户反应某个系统两张表少数据,这两个表位于一套Oracle 19c RAC容器数据库的一个PDB中,需要使用备份将这两个表恢复到5月17日早上8点。首先这套库有三个PDB,加起来大小10T左右,全库恢复太浪费时间;出问题的PDB大小5T,只恢复一个PDB效率也不理想。最理想的方案就是tablespace point-in-time recovery (TSPITR),但是客户为了不影响生产,只认可异机恢复,所以只能手动的来实现TSPITR。

二、环境介绍

生产环境 Oracle 19.11 RAC+DG ,两个表被误删除部分数据,需要进行恢复,恢复到5月17日上午9点。
目标环境 单节点19c的数据库软件环境

准备工作:
 1、完整备份 + 连续归档(当前环境为5月14日的全备+5月17日的增量+归档备份) NBU备份。
 2、复制生产端的参数文件为pfile,目标端启动到mount状态
 3、连接NUB备份正常,正确的驱动程序

三、操作流程

1、数据库实例启动到nomount状态
startup nomount pfile='/home/oracle/testdb20230520.ora';

提示:单价环境需要手动指定归档地址,如果需要恢复的数据量较大可能需要很多的归档空间,提前规划磁盘空间。

2、恢复控制文件

run
{allocate channel ch00 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
restore controlfile to '/oradata/testdb/CONTROLFILE/controlfile01' from 'cntrl_362787_1_1137101912';
release channel ch00;
}

3 转储cdb

数据文件目录提前创建好

run{allocate channel ch00 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch01 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch02 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch03 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
set newname for database to '/oradata/testdb/CDB/%b';
restore database root;
switch datafile all;
release channel ch00;
release channel ch01;
release channel ch02;
release channel ch03;
}

5 转储pdb1指定表空间
run{allocate channel ch00 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch01 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch02 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch03 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch04 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch05 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch06 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch07 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
set newname for datafile 294  to '/oradata/testdb/pdb1/%b';
set newname for datafile 297  to '/oradata/testdb/pdb1/%b';
set newname for datafile 411  to '/oradata/testdb/pdb1/%b';
set newname for datafile 412  to '/oradata/testdb/pdb1/%b';
set newname for datafile 413  to '/oradata/testdb/pdb1/%b';
set newname for datafile 414  to '/oradata/testdb/pdb1/%b';
set newname for datafile 415  to '/oradata/testdb/pdb1/%b';
set newname for datafile 416  to '/oradata/testdb/pdb1/%b';
set newname for datafile 417  to '/oradata/testdb/pdb1/%b';
set newname for datafile 418  to '/oradata/testdb/pdb1/%b';
set newname for datafile 419  to '/oradata/testdb/pdb1/%b';
set newname for datafile 420  to '/oradata/testdb/pdb1/%b';
set newname for datafile 421  to '/oradata/testdb/pdb1/%b';
set newname for datafile 422  to '/oradata/testdb/pdb1/%b';
set newname for datafile 423  to '/oradata/testdb/pdb1/%b';
set newname for datafile 424  to '/oradata/testdb/pdb1/%b';
set newname for datafile 425  to '/oradata/testdb/pdb1/%b';
set newname for datafile 426  to '/oradata/testdb/pdb1/%b';
set newname for datafile 427  to '/oradata/testdb/pdb1/%b';
set newname for datafile 428  to '/oradata/testdb/pdb1/%b';
set newname for datafile 429  to '/oradata/testdb/pdb1/%b';
set newname for datafile 430  to '/oradata/testdb/pdb1/%b';
set newname for datafile 431  to '/oradata/testdb/pdb1/%b';
set newname for datafile 432  to '/oradata/testdb/pdb1/%b';
set newname for datafile 433  to '/oradata/testdb/pdb1/%b';
set newname for datafile 434  to '/oradata/testdb/pdb1/%b';
set newname for datafile 435  to '/oradata/testdb/pdb1/%b';
set newname for datafile 436  to '/oradata/testdb/pdb1/%b';
set newname for datafile 437  to '/oradata/testdb/pdb1/%b';
set newname for datafile 438  to '/oradata/testdb/pdb1/%b';
set newname for datafile 439  to '/oradata/testdb/pdb1/%b';
set newname for datafile 440  to '/oradata/testdb/pdb1/%b';
set newname for datafile 441  to '/oradata/testdb/pdb1/%b';
set newname for datafile 490  to '/oradata/testdb/pdb1/%b';
set newname for datafile 491  to '/oradata/testdb/pdb1/%b';
set newname for datafile 492  to '/oradata/testdb/pdb1/%b';
set newname for datafile 296  to '/oradata/testdb/pdb1/%b';
restore tablespace "pdb1":system,"pdb1":undotbs1,"pdb1":undo_2,"pdb1":pdb1_fm;
switch datafile all;
switch tempfile all;
release channel ch00;
release channel ch01;
release channel ch02;
release channel ch03;
release channel ch04;
release channel ch05;
release channel ch06;
release channel ch07;
}

提示1:这里需要恢复的两个表自包含于一个表空间pdb1_FM,所以只需要恢复这一个表空间,再加上SYSTEM表空间和UNDO表空间,就可以将PDB拉起来。
提示2:因为是异机恢复,数据文件路径改变,这里需要查询需要恢复的表空间的所有数据文件的file_ID,执行set newname。转储完需要switch,将数据文件信息注册到控制文件。


6、开始recover
run{allocate channel ch00 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch01 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch02 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
allocate channel ch03 type 'sbt_tape';
send 'NB_ORA_SERV=bak-svr,NB_ORA_CLIENT=node1';
set until time "to_date('2023/05/17 08:00:00','yyyy/mm/dd hh24:mi:ss')";
recover database  skip forever tablespace "pdb1":SYSAUX,"pdb1":TEMP,"pdb2":ts1,"pdb2"ts2,"pdb3"ts1;
release channel ch00;
release channel ch01;
release channel ch02;
release channel ch03;}


提示:这里指定跳过recover没有转储的自身PDB下表空间和其他没有恢复的PDB下的表空间。可以执行下列查询来生成跳过的表空间,没有open的PDB不会查询到,需要单独添加。
set pagesize 400;
set line 400
select '"'||b.name||'"'||':'||a.name||','
from v$tablespace a,v$containers b
where a.con_id=b.con_id 
and b.name not in('CDB$ROOT','pdb1');
and a.name not in('pdb1_FM','UNDOTBS1','SYSTEM');


7、重新指定redo位置

select 'alter database rename file '||chr(39)||member||chr(39)||' to '||chr(39)||member||chr(39)||';' 
from v$logfile ;


将redo日志文件位置指定到本地。
alter database rename file '+DATA/testdb/ONLINELOG/group_1.258.1076782375' to  '/oradata/testdb/ONLINELOG/group_1.258.1076782375';
。。。

8、拉起CDB和PDB
alter database open resetlogs;
alter pluggable database pdb1 open;


9、确定要恢复的数据正常后可以将数据导回生产环境

两种方法:数据泵和DBLINK。

但是本次没有做全库的恢复,只做了指定表空间恢复,没有恢复SYSAUX而且也没有新建TEMP表空间,使用数据泵导出会报错,所以使用DBLINK。


创建PDB的监听和连接字符串

1)新建监听
LISTENER2=
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.88)(PORT = 1522))
    )
  )
SID_LIST_LISTENER2 =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME=testdb)
      (SID_NAME=testdb)
      (ORACLE_HOME='/u01/app/oracle/product/19.0.0/db_1')
    )
  )

 执行:
lsnrctl start listener2

2)新建连接字符串

pdb1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.88)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME =pdb1)
    )
  )

LISTENER_testdb=
  (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.88)(PORT = 1522))
   )

如果PDB监听无法注册 :
alter system set local_listener='LISTENER_testdb'
手动注册:
alter system register

3)生产端创建DBLINK

alter session set container=pdb1;
create public database link pdb1_rec connect to dump_user identified by "8Qllyhy!" using '192.168.18.88:1522/pdb1';

4)恢复数据

可以通过DBLINK将数据复制到新表里面,也可以将丢失的数据插入到原表。

5)删掉DBLINK
恢复完成后删除DBLINK

drop database link pdb1_rec;

你可能感兴趣的:(数据库)