百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

「Oracle数据库」手滑删错数据,一步步教你如何挽救?

sinye56 2024-10-10 10:41 4 浏览 0 评论

前言

常在河边走,哪能不湿鞋?

今天有客户联系说误更新数据表,导致数据错乱了,希望能帮忙恢复下。数据库版本为 11.2.0.1,操作系统是 Windows64 位,数据已经被更改超过1周时间,数据库已开启归档模式没有DG容灾有RMAN备份,希望将这张表恢复到 一周前 的指定时间点。

一、分析

以下只列出常规恢复手段:

1、数据已经误操作超过一周,所以排除使用UNDO快照来找回。
2、没有DG容灾环境,排除使用DG闪回。
3、主库已开启归档模式,并且存在RMAN备份,可使用RMAN异机恢复表对应表空间,使用DBLINK捞回数据表。
4、Oracle 12C后支持单张表恢复。

结论:安全起见,使用RMAN异机恢复表空间来捞回数据表。

二、思路

客户希望将表数据恢复到 2021/06/08 17:00:00 之前某个时间点。

大致操作步骤如下:

1、主库查询误更新数据表对应的表空间和无需恢复的表空间。
2、新主机安装Oracle 11.2.0.1数据库软件,无需建库,目录结构最好保持一致。
3、主库拷贝参数文件,密码文件至新主机,根据新主机修改参数文件和创建新实例所需目录。
4、新主机使用修改后的参数文件打开数据库实例到nomount状态。
5、主库拷贝备份的控制文件至新主机,新主机使用RMAN恢复控制文件,并且MOUNT新实例。
6、新主机RESTORE TABLESPACE恢复至时间点 2021/06/08 16:00:00 。
7、新主机RECOVER DATABASE SKIP TABLESPACE恢复至时间点 2021/06/08 16:00:00 。
8、新主机实例开启到只读模式。
9、确认新主机实例的表数据是否正确,若不正确则重复 第7步 调整时间点慢慢往 2021/06/08 17:00:00 推进恢复。
10、主库创建连通新主机实例的DBLINK,通过DBLINK从新主机实例捞取表数据。

注意:选择表空间恢复是因为主库数据量比较大,如果全库恢复需要大量时间。

三、测试环境模拟

为了数据脱敏,因此以测试环境模拟场景进行演示。

1、环境准备

节点

主机版本

主机名

实例名

Oracle版本

IP地址

主库

rhel6.9

orcl

orcl

11.2.0.1

10.211.55.111

新主机

rhel6.9

orcl

不创建实例

11.2.0.1

10.211.55.112

环境部署可以通过 Oracle一键安装脚本 进行初始化环境,然后手动安装即可。

主库:./OracleShellInstall.sh -i 10.211.55.111 -m Y -txh Y
新主机:./OracleShellInstall.sh -i 10.211.55.112 -m Y -txh Y

2、模拟测试场景

主库开启归档模式

--设置归档路径
alter system set log_archive_dest_1='LOCATION=/archivelog';
--重启开启归档模式
shutdown immediate
startup mount
alter database archivelog;
--打开数据库
alter database open;
复制代码

创建测试数据

sqlplus / as sysdba
--创建表空间
create tablespace lucifer datafile '/oradata/orcl/lucifer01.dbf' size 10M autoextend off;
create tablespace ltest datafile '/oradata/orcl/ltest01.dbf' size 10M autoextend off;
--创建用户
create user lucifer identified by lucifer;
grant dba to lucifer;
--创建表
conn lucifer/lucifer
create table lucifer(id number not null,name varchar2(20)) tablespace lucifer;
--插入数据
insert into lucifer values(1,'lucifer');
insert into lucifer values(2,'test1');
insert into lucifer values(3,'test2');
commit;
复制代码

进行数据库全备

run {
allocate channel c1 device type disk;
allocate channel c2 device type disk;
crosscheck backup;
crosscheck archivelog all; 
sql"alter system switch logfile";
delete noprompt expired backup;
delete noprompt obsolete device type disk;
backup database include current controlfile format '/backup/backlv0_%d_%T_%t_%s_%p';
backup archivelog all DELETE INPUT;
release channel c1;
release channel c2;
}
复制代码

模拟数据修改

sqlplus / as sysdba
conn lucifer/lucifer
delete from lucifer where id=1;
update lucifer set name='lucifer' where id=2;
commit;
复制代码


注意:为了模拟客户环境,假设无法通过UNDO快照找回,当前删除时间点为:2021/06/17 18:10:00。

如果使用UNDO快照,比较方便:

--查找UNDO快照数据是否正确
select * from lucifer.lucifer as of timestamp to_timestamp('2021-06-17 18:05:00','YYYY-MM-DD HH24:MI:SS');
--将UNDO快照数据捞至新建表中
create 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');
复制代码

四、RMAN完整恢复过程

主库查询误更新数据表对应的表空间和无需恢复的表空间

--查询误更新数据表对应表空间
select owner,tablespace_name from dba_segments where segment_name='LUCIFER';
--查询所有表空间
select tablespace_name from dba_tablespaces;
复制代码



主库拷贝参数文件,密码文件至新主机,根据新主机修改参数文件和创建新实例所需目录

##生成pfile参数文件
sqlplus / as sysdba
create pfile='/home/oracle/pfile.ora' from spfile;
##拷贝至新主机
su - oracle
scp /home/oracle/pfile.ora 10.211.55.112:/tmp
scp $ORACLE_HOME/dbs/orapworcl 10.211.55.112:$ORACLE_HOME/dbs
###新主机根据实际情况修改参数文件并且创建目录
mkdir -p /u01/app/oracle/admin/orcl/adump
mkdir -p /oradata/orcl/
mkdir -p /archivelog
chown -R oracle:oinstall /archivelog
chown -R oracle:oinstall /oradata
复制代码


新主机使用修改后的参数文件打开数据库实例到nomount状态

sqlplus / as sysdba
startup nomount pfile='/tmp/pfile.ora';
复制代码


主库拷贝备份的控制文件至新主机,新主机使用RMAN恢复控制文件,并且MOUNT新实例

rman target /
list backup of controlfile;
##拷贝备份文件至新主机
scp /backup/backlv0_ORCL_20210617_107548592* 10.211.55.112:/tmp
scp /u01/app/oracle/product/11.2.0/db/dbs/0c01l775_1_1 10.211.55.112:/tmp
##新主机恢复控制文件并开启到mount状态
rman target /
restore controlfile from '/tmp/backlv0_ORCL_20210617_1075485924_9_1';
alter database mount;
复制代码

通过 list backup of controlfile; 可以看到控制文件位置。




新主机RESTORE TABLESPACE恢复至时间点 2021/06/17 18:06:00

##新主机注册备份集
rman target /
catalog start with '/tmp/backlv0_ORCL_20210617_107548592';
crosscheck backup;
delete noprompt expired backup;
delete noprompt obsolete device type disk;
##恢复表空间LUCIFER和系统表空间,指定时间点 `2021/06/17 18:06:00`
run {
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';
set until time '2021-06-17 18:06:00';
allocate channel ch01 device type disk;
allocate channel ch02 device type disk;
restore tablespace SYSTEM,SYSAUX,UNDOTBS1,USERS,LUCIFER;
release channel ch01;
release channel ch02;
}
复制代码


新主机RECOVER DATABASE SKIP TABLESPACE恢复至时间点 2021/06/17 18:06:00

rman target /
run {
sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"';
set until time '2021-06-17 18:06:00';
allocate channel ch01 device type disk;
recover database skip tablespace LTEST,EXAMPLE;
release channel ch01;
}
复制代码

这里有一个小BUG:客户环境是Windows,执行这一步最后报错,手动offline数据文件依然无法开启数据库。

解决方案:

--将恢复跳过的表空间都offline drop掉,执行以下查询结果
select 'alter database datafile '|| file_id ||' offline drop;' from dba_data_files where tablespace_name in ('LTEST','EXAMPLE');
--再次开启数据库
alter database open read only;
复制代码

注意:如果显示缺归档日志,可以参考如下步骤:

##查询恢复需要的归档日志号时间 alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"; select first_time,sequence# from v$archived_log where sequence#='7'; ##通过备份RESTORE吐出所需的归档日志 rman target / catalog start with '/tmp/0c01l775_1_1'; crosscheck archivelog all; run { allocate channel ch01 device type disk; SET ARCHIVELOG DESTINATION TO '/archivelog'; restore ARCHIVELOG SEQUENCE 7; release channel ch01; } ##再次recover进行恢复至指定时间点 2021-06-17 18:06:00 run { sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"'; set until time '2021-06-17 18:06:00'; allocate channel ch01 device type disk; recover database skip tablespace LTEST,EXAMPLE; release channel ch01; } 复制代码

新主机实例开启到只读模式

sqlplus / as sysdba
alter database open read only;
复制代码


确认新主机实例的表数据是否正确

select * from lucifer.lucifer;
复制代码

注意:若不正确则重复 第7步 调整时间点慢慢往 2021/06/17 18:10:00 推进恢复:

##关闭数据库 sqlplus / as sysdba shutdown immediate; ##开启数据库到mount状态 startup mount pfile='/tmp/pfile.ora'; ##重复 第7步,往前推进1分钟,调整时间点为 `2021/06/08 18:07:00` rman target / run { sql 'alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss"'; set until time '2021-06-17 18:07:00'; allocate channel ch01 device type disk; recover database skip tablespace LTEST,EXAMPLE; release channel ch01; } 复制代码

主库创建连通新主机实例的DBLINK,通过DBLINK从新主机实例捞取表数据

sqlplus / as sysdba
CREATE PUBLIC DATABASE LINK ORCL112
CONNECT TO lucifer
IDENTIFIED BY lucifer
USING '(DESCRIPTION_LIST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=10.211.55.112)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=orcl)
)
)
)';
--通过dblink捞取数据
create table lucifer.lucifer_0618 as select /*+full(lucifer)*/ * from lucifer.lucifer@ORCL112;
select * from lucifer.lucifer_0618;
复制代码


至此,整个RMAN恢复过程就结束了。



相关推荐

Linux基础知识之修改root用户密码

现象:Linux修改密码出现:Authenticationtokenmanipulationerror。故障解决办法:进入单用户,执行pwconv,再执行passwdroot。...

Linux如何修改远程访问端口

对于Linux服务器而言,其默认的远程访问端口为22。但是,出于安全方面的考虑,一般都会修改该端口。下面我来简答介绍一下如何修改Linux服务器默认的远程访问端口。对于默认端口而言,其相关的配置位于/...

如何批量更改文件的权限

如果你发觉一个目录结构下的大量文件权限(读、写、可执行)很乱时,可以执行以下两个命令批量修正:批量修改文件夹的权限chmod755-Rdir_name批量修改文件的权限finddir_nam...

CentOS「linux」学习笔记10:修改文件和目录权限

?linux基础操作:主要介绍了修改文件和目录的权限及chown和chgrp高级用法6.chmod修改权限1:字母方式[修改文件或目录的权限]u代表所属者,g代表所属组,o代表其他组的用户,a代表所有...

Linux下更改串口的权限

问题描述我在Ubuntu中使用ArduinoIDE,并且遇到串口问题。它过去一直有效,但由于可能不必要的原因,我觉得有必要将一些文件的所有权从root所有权更改为我的用户所有权。...

Linux chown命令:修改文件和目录的所有者和所属组

chown命令,可以认为是"changeowner"的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。当只需要修改所有者时,可使用...

chmod修改文件夹及子目录权限的方法

chmod修改文件夹及子目录权限的方法打开终端进入你需要修改的目录然后执行下面这条命令chmod777*-R全部子目录及文件权限改为777查看linux文件的权限:ls-l文件名称查看li...

Android 修改隐藏设置项权限

在Android系统中,修改某些隐藏设置项或权限通常涉及到系统级别的操作,尤其是针对非标准的、未在常规用户界面显示的高级选项。这些隐藏设置往往与隐私保护、安全相关的特殊功能有关,或者涉及开发者选项、权...

完蛋了!我不小心把Linux所有的文件权限修改了!在线等修复!

最近一个客户在群里说他一不小心把某台业务服务器的根目录权限给改了,本来想修改当前目录,结果执行成了根目录。...

linux改变安全性设置-改变所属关系

CentOS7.3学习笔记总结(五十八)-改变安全性设置-改变所属关系在以前的文章里,我介绍过linux文件权限,感兴趣的朋友可以关注我,阅读一下这篇文章。这里我们不在做过的介绍,注重介绍改变文件或者...

Python基础到实战一飞冲天(一)--linux基础(七)修改权限chmod

#07_Python基础到实战一飞冲天(一)--linux基础(七)--修改权限chmod-root-groupadd-groupdel-chgrp-username-passwd...

linux更改用户权限为root权限方法大全

背景在使用linux系统时,经常会遇到需要修改用户权限为root权限。通过修改用户所属群组groupid为root,此操作只能使普通用户实现享有部分root权限,普通用户仍不能像root用户一样享有超...

怎么用ip命令在linux中添加路由表项?

在Linux中添加路由表项,可以使用ip命令的route子命令。添加路由表项的基本语法如下:sudoiprouteadd<network>via<gateway>这...

Linux配置网络

1、网卡名配置相关文件回到顶部网卡名命名规则文件:/etc/udev/rules.d/70-persistent-net.rules#PCIdevice0x8086:0x100f(e1000)...

Linux系列---网络配置文件

1.网卡配置文件在/etc/sysconfig/network-scripts/下:[root@oldboynetwork-scripts]#ls/etc/sysconfig/network-s...

取消回复欢迎 发表评论: