1核心业务表误delete恢复
1.1模拟delete误操作
创建jason业务表,如下:
SQL> create table jason as select * from dba_objects; SQL> create index idx_jason_oid on jason(object_id);
删除jason业务表部分数据,在提交之后,发现部分数据存在误删,如下:
SQL> delete from jason where object_id between 3000 and 6000; 3001 rows deleted.
1.2闪回查询恢复误删数据
首先,检查当前时间和undo保留时间,如下:
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; SQL> select sysdate from dual; SYSDATE ------------------- 2022-05-06 23:29:07 SQL> show parameter undo_retention NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ undo_retention integer 900
根据时间戳执行闪回查询,检查数据能否被找回,如下:
SQL> select count(*) from sys.jason as of timestamp to_timestamp('2022-05-06 23:14:07','yyyy-mm-dd hh24:mi:ss') where object_id between 3000 and 6000;
COUNT(*)
----------
3001
如果数据确认可以被找回来,立即将undo中前镜像数据插回至jason业务表,如下:
SQL> insert into jason select * from sys.jason as of timestamp to_timestamp('2022-05-06 23:14:07','yyyy-mm-dd hh24:mi:ss') where object_id between 3000 and 6000;
3001 rows created.
如果数据无法通过undo闪回查询找到,则尝试1.1.3节方案进行数据挽救。
SQL> select count(*) from sys.jason as of timestamp to_timestamp('2022-05-06 23:14:07','yyyy-mm-dd hh24:mi:ss') where object_id between 3000 and 6000;
ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 7 with name
"_SYSSMU7_2329891355$" too small
1.3归档日志挖掘恢复误删数据
检查数据库全局force_logging和supplemental_log_data_min特性是否开启,如下:
SQL> select name,open_mode,log_mode,force_logging,supplemental_log_data_min from v$database; NAME OPEN_MODE LOG_MODE FORCE_LOGGING SUPPLEMENTAL_LOG_DATA_MIN --------- -------------------- ------------ --------------- ------------------------- TESTDB19 READ WRITE ARCHIVELOG NO NO
手动切换归档日志,并记录当前时间,如下:
SQL> alter system switch logfile; SQL> select sysdate from dual; SYSDATE ------------------- 2022-05-06 23:58:35
检查数据误删除期间产生的归档日志文件,如下:
select unique NAME, THREAD#, SEQUENCE#, COMPLETION_TIME
from gv$archived_log
where thread# = 1
and COMPLETION_TIME >=
to_date('2022-05-07 03:09:24', 'yyyy-mm-dd hh24:mi:ss')
and COMPLETION_TIME <=
to_date('2022-05-07 03:11:19', 'yyyy-mm-dd hh24:mi:ss')
order by SEQUENCE#;
添加第一个要加载的归档日志文件,如下:
SQL> execute dbms_logmnr.add_logfile(logfilename=>'/oracle/app/fast_recovery_area/TESTDB19C/archivelog/2022_05_07/o1_mf_1_134_k7d6w2g6_.arc',options=>dbms_logmnr.new);
多次添加要加载的归档日志文件,如下:
SQL> execute dbms_logmnr.add_logfile(logfilename=>'/oracle/app/fast_recovery_area/TESTDB19C/archivelog/2022_05_07/o1_mf_1_135_k7d6wo28_.arc',options=>dbms_logmnr.addfile);
执行日志挖掘分析,如下:
SQL> execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
查询v$logmnr_contents动态性能视图,获取归档日志解析信息,如下:
SQL> select count(*) from v$logmnr_contents; COUNT(*) ---------- 391721 SQL> create table sys.hzmc_logmnr_contents as select * from v$logmnr_contents;
关闭日志挖掘分析,如下:
SQL> execute dbms_logmnr.end_logmnr;
将误删除操作的反向插入语句输出至jason_insert.sql,如下:
SQL> set lines 1000 pages 0 SQL> spool jason_insert.sql SQL> select sql_undo from sys.hzmc_logmnr_contents where OPERATION='DELETE' and sql_redo like '%JASON%'; SQL> spool off
清理jason_insert.sql文本中的首行和尾行,如下:
shell> vi jason_insert.sql
将反向解析出来的SQL语句插回至jason业务表,如下:
SQL> @jason_insert.sql
2、核心业务表误update恢复
2.1模拟update误操作
创建jason业务表,如下:
SQL> create table jason as select * from dba_objects; SQL> create index idx_jason_oid on jason(object_id);
更新jason业务表部分数据,在提交之后,发现部分数据存在误更新,如下:
SQL> update jason set object_id=1 where object_id<=70000; 69346 rows updated. SQL> commit;
2.2闪回查询恢复误删数据
首先,检查当前时间和undo保留时间,如下:
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; SQL> select sysdate from dual; SYSDATE ------------------- 2022-05-07 06:13:38 SQL> show parameter undo_retention NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ undo_retention integer 900
根据时间戳执行闪回查询,检查数据能否被找回,如下:
SQL> select count(*) from sys.jason as of timestamp to_timestamp('2022-05-07 06:12:38','yyyy-mm-dd hh24:mi:ss') where object_id<=70000;
COUNT(*)
----------
69346
如果数据确认可以被找回来,先创建jason业务表的备份jason_old,再基于闪回数据创建新业务表jason_new,然后立即删除jason业务表误更新的数据,再将undo中前镜像数据插回至jason表,如下:
SQL> create table jason_old as select * from jason;
SQL> create table jason_new as select * from jason where 1=2;
SQL> insert into jason_new select * from sys.jason as of timestamp to_timestamp('2022-05-07 06:12:38','yyyy-mm-dd hh24:mi:ss') where object_id<=70000;
69346 rows created.
SQL> commit;
SQL> delete from jason where object_id<=70000;
SQL> commit;
SQL> insert into jason select * from jason_new;
69346 rows created.
SQL> commit;
如果数据无法通过undo闪回查询找到,则尝试1.2.3节方案进行数据挽救。
SQL> select count(*) from sys.jason as of timestamp to_timestamp('2022-05-07 06:12:38','yyyy-mm-dd hh24:mi:ss') where object_id<=70000;
ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 7 with name
"_SYSSMU7_2329891355$" too small
2.3归档日志挖掘恢复误删数据
检查数据库全局force_logging和supplemental_log_data_min特性是否开启,如下:
SQL> select name,open_mode,log_mode,force_logging,supplemental_log_data_min from v$database; NAME OPEN_MODE LOG_MODE FORCE_LOGGING SUPPLEMENTAL_LOG_DATA_MIN --------- -------------------- ------------ --------------- ------------------------- TESTDB19 READ WRITE ARCHIVELOG NO NO
手动切换归档日志,并记录当前时间,如下:
SQL> alter system switch logfile; SQL> select sysdate from dual; SYSDATE ------------------- 2022-05-07 06:34:09
检查数据误删除期间产生的归档日志文件,如下:
select unique NAME, THREAD#, SEQUENCE#, COMPLETION_TIME
from gv$archived_log
where thread# = 1
and COMPLETION_TIME >=
to_date('2022-05-07 06:12:38', 'yyyy-mm-dd hh24:mi:ss')
and COMPLETION_TIME <=
to_date('2022-05-07 06:34:09', 'yyyy-mm-dd hh24:mi:ss')
order by SEQUENCE#;
添加第一个要加载的归档日志文件,如下:
SQL> execute dbms_logmnr.add_logfile(logfilename=>'/oracle/app/fast_recovery_area/TESTDB19C/archivelog/2022_05_07/o1_mf_1_137_k7dlrmqx_.arc',options=>dbms_logmnr.new);
多次添加要加载的归档日志文件,如下:
SQL> execute dbms_logmnr.add_logfile(logfilename=>'/oracle/app/fast_recovery_area/TESTDB19C/archivelog/2022_05_07/o1_mf_1_138_k7dlrtnr_.arc',options=>dbms_logmnr.addfile);
执行日志挖掘分析,如下:
SQL> execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
查询v$logmnr_contents动态性能视图,获取归档日志解析信息,如下:
SQL> select count(*) from v$logmnr_contents; COUNT(*) ---------- 345231 SQL> create table sys.hzmc_logmnr_contents as select * from v$logmnr_contents;
关闭日志挖掘分析,如下:
SQL> execute dbms_logmnr.end_logmnr;
将误删除操作的反向插入语句输出至jason_insert.sql,如下:
SQL> set lines 1000 pages 0
SQL> spool jason_update.sql
select sql_undo
from sys.hzmc_logmnr_contents
where OPERATION = 'UPDATE'
and sql_redo like '%JASON%'
and TIMESTAMP >= to_date('2022-05-07 06:12:38', 'yyyy-mm-dd hh24:mi:ss')
and TIMESTAMP <= to_date('2022-05-07 06:34:09', 'yyyy-mm-dd hh24:mi:ss');
SQL> spool off
清理jason_update.sql文本中的首行和尾行,如下:
shell> vi jason_update.sql
将反向解析出来的SQL语句插回至jason业务表,如下:
SQL> @jason_update.sql