点击上方"数据与人", 右上角选择“设为星标”
分享干货,共同成长!


背景:
我们的一些业务测试系统,数据库一般也是由开发同事自行维护,所以不可避免会有一些问题,经常会有开发同事火急火燎的打电话给我们,如果语气急切,态度恭谨,一般就是误操作数据了(八九不离十)。
最近我们就遇到了一起误更新数据的事件。
由于update SQL编写问题,开发同事将整个表的一个字段进行了更新。
SQL:
UPDATE tab_order a set a.status = '01'
WHERE
EXISTS (
SELECT
order_id
FROM
tab_tmp b,
tab_order c
WHERE
b.cust_no = c.cust_no
AND b.state = 3):
处理方案
1.事务未结束,直接rollback
SQL> begin;
SQL> UPDATE tab_order a set a.status = '01';
SQL> rollback;
2.使用闪回查询
SQL> show parameter unod NAME TYPE VALUE --------------------------------- undo_management string AUTO undo_retrntion intrger 900 undo_tablespace string UNDOTBS1 /* 默认undo_retention为900s SQL> SELECT * FROM tab_order a
AS OF TIMESTAMP TO_TIMESTAMP('2023-04-20 21:10:00', 'YYYY-MM-DD HH24:MI:SS');
/* 查询的时间应该位于 update之前的最近时刻,如果undo信息被覆盖了,会报错ORA-01555,则无法使用该方法恢复*/
/*如果闪回查询可以查到数据,可以新建一个表用来存储历史数据,进行恢复*/
SQL> CREATE TABLE tab_old as SELECT * FROM tab_order a
AS OF TIMESTAMP TO_TIMESTAMP('2023-04-20 21:10:00', 'YYYY-MM-DD HH24:MI:SS');
3.使用LogMinner挖掘日志,执行undo sql恢复
加入日志,如果不确定时间就多家几组日志
execute dbms_logmnr.add_logfile('/opt/oracle/archive/1_85_782895629.dbf',dbms_logmnr.new);
分析日志
execute dbms_logmnr.START_LOGMNR(options => dbms_logmnr.dict_from_online_catalog);
查询分析结果,可以按照表明 like
select username,sql_redo,sql_undo from v$logmnr_contents where operation='UPDATE' and
sql_redo like '%tab_order a%';
5.使用备份恢复异机恢复表,导出、导入恢复
1、恢复参数文件。 设置环境变量: export ORACLE_SID=xxx 登录RMAN: rman target / 在RMAN里把数据库起到nomount状态: RMAN> startup nomount; 设置DBID: RMAN> set dbid=3931082997 恢复spfile: RMAN> restore spfile from '/backup/test/c-3931082997-20131204-02'; 关闭数据库: RMAN> shutdown immediate; 把数据库起到nomount状态: RMAN> startup nomount; 2、恢复控制文件。 RMAN> restore controlfile from '/backup/test/ctl_HNCDFHQ_20131204_21_1'; 把数据库启动到mount状态: RMAN> alter database mount; 3、恢复数据文件: 如果备份不在备份时所在的目录,在新的目录。 可以用此命令注册到控制文件。 RMAN> catalog start with '/oradata1/backup'; restore数据库: RMAN> run { allocate channel c1 type disk ; allocate channel c2 type disk ; restore database ; release channel ch1; release channel ch2; } recover 数据库: RMAN> recover database; SQL> recover database until cancel using backup controlfile ; --选择redo的绝对路径,一个一个试,有多少组redo,就试多少次 SQL> alter database open resetlogs; /*4.恢复完使用expdp导出*/ $ expdp "'/ as sysdba'" table=userA.tab_order dumpfilefile=tab_order.dmp directory=dumpdir /* 恢复时可以新建一个用户 */ $ impdp "'/ as sysdba'" dumpfile=tab_order.dmp directory=dumpdir remap_schema=userA:userB /* 然后根据恢复的表把原来的值UPDATE回来 */ SQL> UPDATE userA.tab_order a , userB.tab_order b set a.status = b.tab_order where a.id=b.id
最后修改时间:2023-04-26 15:47:00
文章转载自数据与人,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




