2.4.4.1.4 SCN 与 timestamp 关系
Oracle 在内部都是使用scn,即使你指定的是as of timestamp,oracle 也会将其转换成scn,系统时间标记与scn 之间存在一张表,即SYS 下的SMON_SCN_TIME
SQL> desc sys.smon_scn_time 名称 是否为空? 类型 ----------------------------------------- -------- -------------------------- THREAD NUMBER TIME_MP NUMBER TIME_DP DATE SCN_WRP NUMBER SCN_BAS NUMBER NUM_MAPPINGS NUMBER TIM_SCN_MAP RAW(1200) SCN NUMBER ORIG_THREAD NUMBER
每隔5 分钟,系统产生一次系统时间标记与scn 的匹配并存入sys.smon_scn_time 表,该表中记录了最近1440个系统时间标记与scn 的匹配记录,由于该表只维护了最近的1440 条记录,因此如果使用as of timestamp 的方式则只能flashback 最近5 天内的数据(假设系统是在持续不断运行并无中断或关机重启之类操作的话)。
注意理解系统时间标记与scn 的每5 分钟匹配一次这句话,举个例子,比如scn:339988,339989 分别匹配08-05-3013:52:00 和2008-13:57:00,则当你通过as of timestamp 查询08-05-30 13:52:00 或08-05-30 13:56:59 这段时间点内的时间时,oracle 都会将其匹配为scn:339988 到undo 表空间中查找,也就说在这个时间内,不管你指定的时间点是什么,查询返回的都将是08-05-30 13:52:00 这个时刻的数据。
查看SCN 和 timestamp 之间的对应关系: SQL>select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time;
2.4.4.1.5 Flashback Query 函数,存储过程,包,触发器等对象
Flashback Drop 可以闪回与表相关联的对象, 如果是其他的对象,比如function,procedure,trigger等。 这时候,就需要使用到ALL_SOURCE 表来进行Flashback Query。
先看联机文档对该表的说明: ALL_SOURCE describes the text source of the stored objects accessible to the current user.
Related Views DBA_SOURCE describes the text source of all stored objects in the database. USER_SOURCE describes the text source of the stored objects owned by the current user. This view does not display the OWNER column.
Column Datatype NULL Description OWNER VARCHAR2(30) NOT NULL Owner of the object NAME VARCHAR2(30) NOT NULL Name of the object TYPE VARCHAR2(12)
Type of object: FUNCTION, JAVA SOURCE, PACKAGE, PACKAGE BODY, PROCEDURE, TRIGGER, TYPE, TYPE BODY LINE NUMBER NOT NULL Line number of this line of source TEXT VARCHAR2(4000)
Text source of the stored object
如果我们误删除了某些对象,如procedure,就可以使用all_source 表进行恢复。
SQL> desc dba_source Name Null? Type ----------------------------------------- -------- ---------------------------- OWNER VARCHAR2(30) NAME VARCHAR2(30) TYPE VARCHAR2(12) LINE NUMBER TEXT VARCHAR2(4000)
查看dba_source 的所有type SQL> select type from dba_source group by type;
TYPE ------------ PROCEDURE PACKAGE PACKAGE BODY TYPE BODY TRIGGER FUNCTION TYPE
7 rows selected.
基于timestamp恢复的语句 SQL>SELECT text FROM dba_source AS OF TIMESTAMP TO_TIMESTAMP ('XXXXX', 'YYYY-MM-DD HH24:MI:SS') WHERE owner = 'XXXX' AND name = '你删除的对象名' ORDER BY line;
示例:
创建函数: SQL> CREATE OR REPLACE function getdate return date as v_date date; begin select sysdate into v_date from dual; return v_date; end; / Function created.
查询函数: SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; Session altered.
SQL> select getdate() from dual; GETDATE() ------------------- 2011-04-07 21:02:09
查询dba_source 表: SQL> select text from dba_source where name='GETDATE' order by line;
TEXT -------------------------------------------------------------------------------- function getdate return date as v_date date; begin select sysdate into v_date from dual; return v_date; end;
7 rows selected.
drop 函数,在查询,记录不存在 SQL> drop function getdate; Function dropped.
SQL> select text from dba_source where name='GETDATE' order by line; no rows selected
使用我们的Flashback Query 查询: SQL> select text from dba_source as of timestamp to_timestamp('2011-04-07 21:02:09','yyyy-mm-dd hh24:mi:ss') where name='GETDATE' order by line;
TEXT -------------------------------------------------------------------------------- function getdate return date as v_date date; begin select sysdate into v_date from dual; return v_date; end;
7 rows selected.
这时候,又查看到了函数的代码,只需要把这些代码重新执行一下就ok了。 其他对象和这个类似。 这里就不演示了。
2.4.4.2 Flashback version Query
相对于Flashback Query 只能看到某一点的对象状态, Oracle 10g引入的Flashback Version Query可以看到过去某个时间段内,记录是如何发生变化的。 根据这个历史,DBA就可以快速的判断数据是在什么时点发生了错误,进而恢复到之前的状态。
先看一个伪列 ORA_ROWSCN. 所谓的伪列,就是假的,不存在的数据列,用户创建表时虽然没有指定,但是Oracle为了维护而添加的一些内部字段,这些字段可以像普通文件那样的使用。
最熟悉的伪列就是 ROWID, 它相当于一个指针,指向记录在磁盘上的位置。ORA_ROWSCN 是Oracle 10g 新增的,暂且把它看作是记录最后一次被修改时的SCN。 Flashback Version Query 就是通过这个伪列来跟踪出记录的变化历史。
举个例子: SQL> select * from A; ID ---------- 2 1 3 4
SQL> insert into A values(5); 已创建 1 行。
SQL> select * from A; ID ---------- 2 1 3 4 5 SQL> commit; 提交完成。 SQL> select ora_rowscn, id from A; ORA_ROWSCN ID ---------- ---------- 1098443 2 1098443 1 1098443 3 1098443 4 1098443 5
获取更多的历史信息 SQL>Select versions_xid,versions_startscn,versions_endscn, DECODE(versions_operation,'I','Insert','U','Update','D','Delete', 'Original') "Operation", id from A versions between scn minvalue and maxvalue;
或者 SQL>select xid,commit_scn,commit_timestamp,operation,undo_sql from flashback_transaction_query q where q.xid in(select versions_xid from B versions between scn 413946 and 413959);
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN Operatio ID ---------------- ----------------- --------------- -------- ---------- 05001A0054020000 1099482 Update 3
05001A0054020000 1099482 Delete 3
05001A0054020000 1099482 Delete 2
05001A0054020000 1099482 Delete 1
0400150005020000 1098443 Insert 5
|