文档结构
- 1、恢复原理
- 1.1、recyclebin(回收站)
- 相关操作
- 2、恢复场景
- 2.1、定义删除
- 2.2、记录删除
- 2.2.1、undo恢复
- 2.2.2、redo恢复
- 2.2.3、dbms_logmnr
场景:在 Oracle数据库使用过程中,误删对象或误删记录的情况时有发生;这种情况下通过技术手段可以将对象的状态和数据恢复到删除前的某个时刻;
建议:技术手段的恢复毕竟是有限的,为了降低类似的误操作还是要通过规范的流程和定期的备份来规避,就像是车技再好的车手也不该经常在悬崖边漂移,否则可能都来不及说再见!
1、恢复原理
Oracle数据库提供了多种方式可以将数据库或对象或记录恢复到某个时间节点;
1)undo文件
说明:undo文件的数据有空间大小限制,数据库按照循环写的方式类使用,可恢复的数据也限于短时间内的操作;
2)redo日志
说明:redo日志因为有空间大小限制,和 undo文件数据类似,是循环写数据,所以可以恢复的数据时间跨度不会很大,一般只限于很短的时间内的操作;
3)archived redo(归档日志)
说明:归档日志是将online redo日志固化为文件存储下来,会占用不小的服务器空间;
4)rman备份
5)recyclebin(回收站)
1.1、recyclebin(回收站)
从ORACLE 10g开始,引入了一个叫回收站(RecycleBin)的概念,全称为Tablespace Recycle Bin。回收站实际是一个逻辑区域,它以表空间中现有已经分配的空间为基础,而不是从表空间上物理划出一个固定区域用作回收站。这意味着回收站和表空间中的对象共用存储区域、系统没有给回收站预留空间。
当表被DROP后,如果可用空间充足,并且没有对回收站进行清理,那么被DROP掉的对象会一直存在回收站中,仍然会占用空间。但是如果可用空间紧张的情况下,数据库会根据先进先出的顺序覆盖Recycle Bin中的对象。所以回收站机制也不是百分百的保险机制。另外从原理上来说它就是一个数据字典表,放置用户Drop掉的数据库对象信息。
相关操作
- 参数状态
SQL>
SQL> show parameter recyclebin;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
recyclebin string on
SQL>
或者
select t.NAME, t.VALUE, t.DISPLAY_VALUE
from v$parameter t
where t.NAME = 'recyclebin';
---输出
NAME VALUE DISPLAY_VALUE
1 recyclebin on on
- 开启关闭
回收站的开启和关闭可以按照时效分为会话级别和系统级别;
1)会话级别
---session
alter session set recyclebin=on/off;
2)系统级别
---system
alter system set recyclebin=on/off;
- 对象查找
涉及的系统表或视图有
A:RECYCLEBIN(指向 USER_RECYCLEBIN的同义词)
B:USER_RECYCLEBIN
C:DBA_RECYCLEBIN
---query_sql
select owner,
object_name,
original_name,
operation,
type,
ts_name,
createtime,
droptime,
dropscn,
partition_name,
can_undrop,
can_purge,
related,
base_object,
purge_object,
space
from DBA_RECYCLEBIN t
where t.owner = '&username'
order by t.createtime desc;
2、恢复场景
2.1、定义删除
对于对象被误删除定义的场景,只能依靠回收站来恢复;需要确定回收站处于开启状态,且在 dba_recyclebin 里可以查到相应记录;
执行恢复操作
flashback table ${schema_name.object_name} to before drop;
对于被恢复定义的对象,索引和主键等名称处于乱码状态,需要重建;
2.2、记录删除
对象数据被误删除在没有开启归档且没有 RMAN 备份的情况下,可以依靠 Undo 数据或者 Redo 数据来恢复;
2.2.1、undo恢复
通过闪回查询确定删除前的记录:
select * from ${schema_name.object_name} as of timestamp to_timestamp('2020-07-26 17:00:50','yyyy-mm-dd hh24:mi:ss') where 1=1 and ${query_condition};
闪回操作:
flashback table ${schema_name.object_name} to timestamp to_timestamp('2020-07-26 17:00:50','yyyy-mm-dd hh24:mi:ss');
说明:这类操作需要确保 undo被删除前的数据没有被覆盖,如果执行flashback操作报错 ora-01555,则相应的回滚段数据已经被覆盖;此时这种方式已经无法恢复数据,或者只能恢复一部分;
2.2.2、redo恢复
该类恢复方式需要依赖到redo日志文件,需要确保redo文件内容没有被覆盖;
step_1:select * from v$logfile t;
step_2:登录数据库服务器
sqlplus '/as sysdba'
exec dbms_logmnr.add_logfile('/data/zxcp/redo05.log',options=>dbms_logmnr.new);
exec dbms_logmnr.add_logfile('/data/zxcp/redo06.log', dbms_logmnr.ADDFILE);
exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
create table log_recover as select * from v$logmnr_contents;
select to_char(timestamp,'yyyy-mm-dd hh24:mi:ss'),sql_redo,sql_undo from log_recover where username='xxxx' and table_name='xxxx';
---最后执行
exec dbms_logmnr.end_logmnr();
此处 sql_redo里的dml语句是当时执行的删除语句,sql_undo里的语句是对应恢复的dml语句;可以将 sql_undo 里的语句存储为动态语句循环执行;
注意:此种方式对于 lob 字段,值内容很长的,可能最终恢复的数据 lob 列的值部分记录为空;因为对于 lob 字段,数据不直接存储在表里;
2.2.3、dbms_logmnr
dbms_logmnr.start_logmnr
begin
-- Call the procedure
sys.dbms_logmnr.start_logmnr(startScn => :startScn,
endScn => :endScn,
startTime => :startTime,
endTime => :endTime,
DictFileName => :DictFileName,
Options => :Options);
end;
说明:该方法有如上几个参数,在进行redo日志文件分析时,可以加 scn号的限制或时间戳的限制;
============================================== over ================================================