暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

记一次业务人员误删数据后的处理方法

原创 lvzhengwei 2020-03-27
1648

记录一次意外删除业务表数据的处理
在一个周六的中午,突然接到了客户的电话,说有一个很紧急的故障需要处理,开发人员误删了一张业务表,且因为种种原因已经commit,现在需要恢复。虽然后来才知道是非常核心的业务表(以下称表A),当天这个操作已经严重影响电信用户查询修改各种套餐,不过当时并没有想到影响这么大,后续的处理过程也让给我一个深刻的教训。
由于以前也经历过类似的事件,当时的时间约是10点10分左右,客户和我说操作时间在9点50分左右,时间不算常,第一时间想起用undo闪回查询保留数据:
select * from table_name as of timestamp to_timestamp(‘2019-xx-xx xx:xx:xx’,‘YYYY-MM-DD HH24:MI:SS’);
10点15查询当前A表的才200多条,查9点55 229条,查9点53分就160多万行,不过数量级还是不对,客户说正常应该1200万左右,再闪回查询,这期间可以看到随着时间往前推移行数在不断增加:10点51的980万,10点50的时候就变1500万,9点49的时候有 2300万,9点48分10秒的时候有3000万,9点48分0秒就报快照过久了。不过我发现9点48分08秒到9点48分10秒这段时间内行数没有减少,行数在3000万左右;介于刚才的查询每一秒行数都在减少的情况下,我主观认为这个时刻可能就是delete之前行数最大的时刻,和客户沟通这个行数也和业务对得上,48分0秒undo就过期了,当时觉得有点幸运,抓紧create table as select 创建出备份表,数据出来了后续就让开发人员折腾数据就行了,以为这事结了,准备吃口饭时,客户打来电话,说数据还是不对,还是少。不过这时我也没太慌,因为在设计这套库的时候就已经考虑到可能有这种delete发生,所以在上线的之前就已经打开了数据库的flashback,我寻思最差最差就用flashback table恢复这个表,虽然不如ctas创建备份表让开发人员倒腾数据对原表以及业务影响小,但是也没什么其他好的办法了。执行flashback table 命令,报错,还是报快照过久。这个时候我就非常慌了,明明开了flashback了,为什么还是报错。抓紧问问专家,才明白咋回事:
alter database flashback on;
这条命令开启的是数据库级别的闪回,并不代表数据库中的每个表随时都能闪回,数据库级别的闪回只能把整个数据库闪回到某个时刻;这样就非常棘手了,和专家和客户商量,想出了一条解决方案:
1.停库,起mount

2.flashback database to timestamp to_timestamp(‘2019-09-07 09:47:54’,‘yyyy-mm-dd hh24:mi:ss’);

3.alter database open read only;

4.查数据是否满足要求,expdp导出

5.停库 起mount

6.recover database;
alter database open;
测试环境下简单测试下可以操作,不过心里非常害怕,万一recover有问题,那不是这个表的问题了,整个数据库都回到47分54秒,影响非常巨大,内心十分抗拒这个方案,无奈影响太大,需要尽快恢复。不过后来和客户再三沟通该方案的风险性,再加上已经恢复了3000万左右的数据,客户同意采用风险度较低的异机恢复方案,这才稍微放下点心来。
异机恢复还算顺利,我们从全备恢复出数据库来,归档也从备份里拉出来,然后recover指定时间,一秒一秒recover,recover一秒查一次行数,最后数据量大约在3300万左右,该故障告一段落。
我认为本次故障我的失误占了很大一部分,本来对flashback不是很熟悉,误认为flashback table这个命令是依赖于flashback database on;实际上该命令完完全全是依赖于undo,和闪回查询是一个东西,对于一个自己不熟悉的技术,绝对不能自以为是的用于生产环境,任何一个变更操作都要在做了充足的测试后才能给客户使用,本次故障让我受益匪浅,以后我也将铭记于心,不会再发生类似事件。
亡羊补牢,事情结束后第一时间准备开启可以不依赖undo闪回查询表的flashback archive技术,这个flashback archive的粒度是表,可以闪回查询指定保留时间的数据,且不依赖undo表空间,如果想实现业务表的实时回溯,那flashback archive可以满足要求,flashback database 实用性不高,一般用在备库上居多,下面贴出我整理的flashback archive的简单步骤,可以参考参考:
flashback archive 测试:
开启flashback archive前提:
undo管理是AOTU
表空间必须是ASSM

1.创建flashback archive 表空间
create tablespace fba datafile ‘+DATADG’ size 10g;

2.创建flashback archive 区域
create flashback archive default fba1 tablespace fba retention 2 day; //创建时指定数据库默认闪回区域

查询:
select flashback_archive_name name, status from dba_flashback_archive;
select OWNER_NAME,FLASHBACK_ARCHIVE_NAME,FLASHBACK_ARCHIVE#,RETENTION_IN_DAYS,CREATE_TIME,LAST_PURGE_TIME,STATUS from dba_flashback_archive;

3.尝试修改保留时间:
alter flashback archive fba1 modify retention 1 day;

4.清空flashback archive中的全部信息:
alter flashback archive fba1 purge all;
清空1天前的信息:
alter flashback archive fba1 purge before timestamp (systimestamp - interval ‘1’ day);

5.创建测试数据
test1 2936192 384M
test2 2936192 384M

6.把test2 放到flashback archive 里面去
alter table test2 flashback archive fba1;
查询:
SELECT table_name,archive_table_name,status from dba_flashback_archive_tables;

7.都delete掉 18:07 左右
delete from test1;
delete from test2; 占用了1000m的表空间

8.做些别的操作确保清空undo

9.查询尝试:
test1已经无法查询:
select count(*) from test1 as of timestamp to_timestamp(‘2019-09-18 18:01:00’,‘YYYY-MM-DD HH24:MI:SS’)
*
ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 10 with name “_SYSSMU10_1251597811$” too small

test2 可以在开启后查询任意时间的数据:
SQL> select /*+ parallel(16) / count() from test2 as of timestamp to_timestamp(‘2019-09-18 18:20:00’,‘YYYY-MM-DD HH24:MI:SS’);

COUNT(*)

2936192

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论