运维管理12 分钟阅读
【Oracle数据库】手滑删错数据,一步步教你如何挽救?
大家好,这里是公众号 DBA学习之路,分享一些学习数据库路上的知识和经验。 @TOC目录 <font color='orage'常在河边走,哪能不湿鞋?</font 今天有客户联系说误更新数据表,导致数据错乱了,希望将这
2021年11月10日阅读—点赞—收藏—
oraclerac
在知识库中专注阅读,并随时返回相关工具与课程
大家好,这里是公众号 DBA学习之路,分享一些学习数据库路上的知识和经验。 @TOC目录 <font color='orage'常在河边走,哪能不湿鞋?</font 今天有客户联系说误更新数据表,导致数据错乱了,希望将这
大家好,这里是公众号 DBA学习之路,分享一些学习数据库路上的知识和经验。

本章目标:掌握本章核心知识点 前置要求:完成前序章节学习 预计时长:60 分钟
常在河边走,哪能不湿鞋?
今天有客户联系说误更新数据表,导致数据错乱了,希望将这张表恢复到 一周前 的指定时间点。
11.2.0.1Windows64下面模拟一下问题的详细解决过程!
以下只列出常规恢复手段:
结论:安全起见,使用RMAN异机恢复表空间来捞回数据表。
客户希望将表数据恢复到 <2021/06/08 17:00:00> 之前某个时间点。
大致操作步骤如下:
📢 注意: 选择表空间恢复是因为主库数据量比较大,如果全库恢复需要大量时间。
为了数据脱敏,因此以测试环境模拟场景进行演示!
⭐️ 测试环境可以使用脚本安装,可以使用博主编写的 Oracle 一键安装脚本,同时支持单机和 RAC 集群模式!
更多更详细的脚本使用方式可以订阅专栏:Oracle 一键安装脚本实操合集,持续更新中!!!。
测试环境信息如下:
主库开启归档模式:
1sqlplus / as sysdba2## 设置归档路径3alter system set log_archive_dest_1='LOCATION=/archivelog';4## 重启开启归档模式5shutdown immediate6startup mount7alter database archivelog;8## 打开数据库9alter database open;创建测试数据:
1sqlplus / as sysdba2## 创建表空间3create tablespace lucifer datafile '/oradata/orcl/lucifer01.dbf' size 10M autoextend off;4create tablespace ltest datafile '/oradata/orcl/ltest01.dbf' size 10M autoextend off;5## 创建用户6create user lucifer identified by lucifer;7grant dba to lucifer;8## 创建表9conn lucifer/lucifer10create table lucifer(id number not null,name varchar2(20)) tablespace lucifer;11## 插入数据12insert into lucifer values(1,'lucifer');13insert into lucifer values(2,'test1');14insert into lucifer values(3,'test2');15commit;
进行数据库全备:
1rman target /2## 进入 rman 后执行以下命令3run {4allocate channel c1 device type disk;5allocate channel c2 device type disk;6crosscheck backup;7crosscheck archivelog all; 8sql"alter system switch logfile";9delete noprompt expired backup;10delete noprompt obsolete device type disk;11backup database include current controlfile format '/backup/backlv0_%d_%T_%t_%s_%p';12backup archivelog all DELETE INPUT;13release channel c1;14release channel c2;15}
模拟数据修改:
1sqlplus / as sysdba2conn lucifer/lucifer3delete from lucifer where id=1;4update lucifer set name='lucifer' where id=2;5commit;
📢 注意: 为了模拟客户环境,假设无法通过UNDO快照找回,当前删除时间点为:<2021/06/17 18:10:00>。
如果使用UNDO快照,比较方便:
1sqlplus / as sysdba2## 查找UNDO快照数据是否正确3select * from lucifer.lucifer as of timestamp to_timestamp('2021-06-17 18:05:00','YYYY-MM-DD HH24:MI:SS');4## 将UNDO快照数据捞至新建表中5create table lucifer.lucifer_0617 as select * from lucifer.lucifer as of timestamp to_timestamp('2021-06-17 18:05:00','YYYY-MM-DD HH24:MI:SS');
主库查询误更新数据表对应的表空间和无需恢复的表空间:
1sqlplus / as sysdba2## 查询误更新数据表对应表空间3select owner,tablespace_name from dba_segments where segment_name='LUCIFER';4## 查询所有表空间5select tablespace_name from dba_tablespaces;

主库拷贝参数文件,密码文件至新主机,根据新主机修改参数文件和创建新实例所需目录:
1## 生成pfile参数文件2sqlplus / as sysdba3create pfile='/home/oracle/pfile.ora' from spfile;4exit;5## 拷贝至新主机6su - oracle7scp /home/oracle/pfile.ora 10.211.55.112:/tmp8scp $ORACLE_HOME/dbs/orapworcl 10.211.55.112:$ORACLE_HOME/dbs9## 新主机根据实际情况修改参数文件并且创建目录10mkdir -p /u01/app/oracle/admin/orcl/adump11mkdir -p /oradata/orcl/12mkdir -p /archivelog13chown -R oracle:oinstall /archivelog14chown -R oracle:oinstall /oradata
新主机使用修改后的参数文件打开数据库实例到nomount状态:
1sqlplus / as sysdba2startup nomount pfile='/tmp/pfile.ora';
主库拷贝备份的控制文件至新主机,新主机使用RMAN恢复控制文件,并且MOUNT新实例:
1rman target /2list backup of controlfile;3exit;4## 拷贝备份文件至新主机5scp /backup/backlv0_ORCL_20210617_107548592* 10.211.55.112:/tmp6scp /u01/app/oracle/product/11.2.0/db/dbs/0c01l775_1_1 10.211.55.112:/tmp7## 新主机恢复控制文件并开启到mount状态8rman target /9restore controlfile from '/tmp/backlv0_ORCL_20210617_1075485924_9_1';10alter database mount;通过 list backup of controlfile; 可以看到控制文件位置:



新主机RESTORE TABLESPACE恢复至时间点 <2021/06/17 18:06:00> :
1## 新主机注册备份集2rman target /3catalog start with '/tmp/backlv0_ORCL_20210617_107548592';4crosscheck backup;5delete noprompt expired backup;6delete noprompt obsolete device type disk;7## 恢复表空间LUCIFER和系统表空间,指定时间点 `2021/06/17 18:06:00`8run {9sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';10set until time '2021-06-17 18:06:00';11allocate channel ch01 device type disk;12allocate channel ch02 device type disk;13restore tablespace SYSTEM,SYSAUX,UNDOTBS1,USERS,LUCIFER;14release channel ch01;15release channel ch02;16}
新主机RECOVER DATABASE SKIP TABLESPACE恢复至时间点 <2021/06/17 18:06:00> :
1rman target /2run {3sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';4set until time '2021-06-17 18:06:00';5allocate channel ch01 device type disk;6recover database skip tablespace LTEST,EXAMPLE;7release channel ch01;8}
这里有一个小BUG: 客户环境是Windows,执行这一步最后报错,手动offline数据文件依然无法开启数据库。
windows恢复报错
解决方案:
1sqlplus / as sysdba2## 将恢复跳过的表空间都offline drop掉,执行以下查询结果3select 'alter database datafile '|| file_id ||' offline drop;' from dba_data_files where tablespace_name in ('LTEST','EXAMPLE');4## 再次开启数据库5alter database open read only;📢 注意: 如果显示缺归档日志,可以参考如下步骤:
1sqlplus / as sysdba2## 查询恢复需要的归档日志号时间 3alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"; 4select first_time,sequence# from v$archived_log where sequence#='7';5exit;6## 通过备份RESTORE吐出所需的归档日志 7rman target / 8catalog start with '/tmp/0c01l775_1_1'; 9crosscheck archivelog all; 10run { 11allocate channel ch01 device type disk; 12SET ARCHIVELOG DESTINATION TO '/archivelog';13restore ARCHIVELOG SEQUENCE 7; 14release channel ch01; 15}16## 再次recover进行恢复至指定时间点 2021-06-17 18:06:00 17run { 18sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"'; 19set until time '2021-06-17 18:06:00'; 20allocate channel ch01 device type disk; 21recover database skip tablespace LTEST,EXAMPLE; 22release channel ch01; 23}新主机实例开启到只读模式:
1sqlplus / as sysdba2alter database open read only;
确认新主机实例的表数据是否正确:
1sqlplus / as sysdba2select * from lucifer.lucifer;
📢 注意: 若不正确则重复 第7步 调整时间点慢慢往 2021/06/17 18:10:00 推进恢复:
1## 关闭数据库2sqlplus / as sysdba3shutdown immediate; 4## 开启数据库到mount状态5startup mount pfile='/tmp/pfile.ora';6## 重复 第7步,往前推进1分钟,调整时间点为 `2021/06/08 18:07:00`7rman target /8run {9sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';10set until time '2021-06-17 18:07:00';11allocate channel ch01 device type disk;12recover database skip tablespace LTEST,EXAMPLE;13release channel ch01;14}主库创建连通新主机实例的DBLINK,通过DBLINK从新主机实例捞取表数据:
1sqlplus / as sysdba2## 创建dblinnk3CREATE PUBLIC DATABASE LINK ORCL1124CONNECT TO lucifer5IDENTIFIED BY lucifer6USING '(DESCRIPTION_LIST=7(DESCRIPTION=8(ADDRESS=(PROTOCOL=tcp)(HOST=10.211.55.112)(PORT=1521))9(CONNECT_DATA=10(SERVICE_NAME=orcl)11)12)13)';14## 通过dblink捞取数据15create table lucifer.lucifer_0618 as select /*+full(lucifer)*/ * from lucifer.lucifer@ORCL112;16select * from lucifer.lucifer_0618;

至此,整个RMAN恢复过程就结束了!
备份永远是最后一道防线,所以备份一定要做好!!!
Oracle 一键巡检自动生成 Word 报告
Oracle 一键安装合集
Oracle一键安装脚本的 21 个疑问与解答
Oracle一键巡检脚本的 21 个疑问与解答
全网首发:Oracle 23ai 一键安装脚本(非 RPM)
Oracle 19C 最新 RU 补丁 19.24 ,一键安装!
Oracle Linux 7.9 一键安装 Oracle 19C
RedHat 9.4(aarch64) 一键安装 Oracle 19C
openEuler 22.03 LTS SP4 一键安装 Oracle 19C RAC
RHEL 7.9 一键安装 Oracle 19C 19.23 RAC
Oracle DataGuard GAP 修复手册
优化 Oracle:最佳实践与开发规范
DBA 必备:Linux 软件源配置全攻略
Linux 一键配置时钟同步全攻略
