Está en la página 1de 12

FLASHBACK QUERY in ORACLE 10g

Flashback technology provides a set of features to view and rewind data back and forth in time.

The flashback features offer the capability to query past versions of schema objects, query

historical data, perform change analysis, and perform self-service repair to recover from logical

corruption while the database is online.

Flashback technology provides a SQL interface to quickly analyze and repair human errors.

Flashback provides fine-grained analysis and repair for localized damage such as deleting the

wrong customer order. Flashback technology also enables correction of more widespread

damage, yet does it quickly to avoid long downtime. Flashback technology is unique to the

Oracle Database and supports recovery at all levels including row, transaction, table, tablespace,

and database.

Oracle Flashback Versions Query is an extension to SQL that can be used to retrieve the versions

of rows in a given table that existed in a specific time interval. Oracle Flashback Versions Query

returns a row for each version of the row that existed in the specified time interval. For any

given table, a new row version is created each time the COMMIT statement is executed.

Oracle Flashback Table enables users to recover a table to a previous point in time. It provides a

fast, online solution for recovering a table or set of tables that has been erroneously modified by

a user or application. In most cases, Flashback Table alleviates the need for administrators to

perform more complicated point-in-time recovery operations. Even after a flashback, the data in

the original table is not lost; it can later be reverted back to the original state.

With 9i this feature was marketed as “Oracle found the time machine” :) But with 9i to flashback

was not so easy, needed DBA privileges etc. After 10g with SELECT statements we are not able

to get only a picture but a movie of our data in time. Ok lets work on an example, seeing is

necessary for believing, we are not marketing here :)

create table flashback_test ( c1 number, c2 date ) nologging ;

insert into flashback_test values ( 1, sysdate ) ;


commit ;
exec dbms_lock.sleep(15);
update flashback_test set c1 = c1 * 2 ;
commit ;
exec dbms_lock.sleep(15);

update flashback_test set c1 = c1 * 2 ;


commit ;
exec dbms_lock.sleep(15);

delete flashback_test ;
commit ;
exec dbms_lock.sleep(15);

select versions_starttime, versions_endtime, versions_xid, versions_operation,


c1
from flashback_test versions between timestamp minvalue and maxvalue
order by VERSIONS_STARTTIME ;

VERSIONS_STARTTIME VERSIONS_ENDTIME
VERSIONS_XID VERSIONS_OPERATION C1
-------------------------------------------------
------------------------------------------------- ----------------
------------------ ----------
08/10/2007 08:18:29 08/10/2007 08:18:44
08002200A6040000 U 2
08/10/2007 08:18:44 08/10/2007 08:18:59
03002300C7040000 U 4
08/10/2007 08:18:59
06002900AC040000 D 4
08/10/2007 08:18:29
1

SELECT UNDO_SQL FROM FLASHBACK_TRANSACTION_QUERY WHERE XID =


hextoraw('06002900AC040000') ; -- delete

UNDO_SQL
----------------------------------------------------------------------------
insert into "HR"."FLASHBACK_TEST"("C1","C2") values ('4',TO_DATE('08/10/2007',
'

SELECT UNDO_SQL FROM FLASHBACK_TRANSACTION_QUERY WHERE XID =


hextoraw('03002300C7040000') ; -- update 4

UNDO_SQL
-----------------------------------------------------------------------------
update "HR"."FLASHBACK_TEST" set "C1" = '2' where ROWID =
'AAAONoAAEAAAAGWAAA';

The maximum of there versions e can get are dependent on UNDO_RETENTION parameter of the

database. TIMESTAMP_TO_SCN and SCN_TO_TIMESTAMP flashback functions are used in SQL or

PL/SQL as needed. In this example we are looking for the sum of the salaries on the employees

in time;
set serveroutput on
DECLARE
l_scn NUMBER;
l_timestamp TIMESTAMP;
BEGIN
l_scn := TIMESTAMP_TO_SCN(SYSTIMESTAMP - 1/48);
dbms_output.put_line('l_scn '||l_scn);
l_timestamp := SCN_TO_TIMESTAMP(l_scn);
dbms_output.put_line('l_timestamp '||l_timestamp);
END;
/

SELECT sum(salary) FROM employees


AS OF SCN TIMESTAMP_TO_SCN(SYSTIMESTAMP - 1/24);

SELECT sum(salary) FROM employees -- TIMESTAMP_TO_SCN(SYSTIMESTAMP - 1/48)


AS OF TIMESTAMP SCN_TO_TIMESTAMP(1531264);

SQL>

l_scn 1531264
l_timestamp 04/01/2007 08:01:29,000000

PL/SQL procedure successfully completed

SUM(SALARY)
-----------
691400

SUM(SALARY)
-----------
691400

Another related subject is PURGE command and RECYCLEBIN with 10g, after 10g when you drop

a table by default it is stored in recyclebin like windows. And you can restore the table with

flashback command easily;

drop table RECYCLETEST purge ;


create table RECYCLETEST (c1 number) ;
select * from tab where tname like '%REC%';

-- lets drop the table, this must be seen as an accident :)


drop table recycletest;
select * from tab where tname like '%BIN%';
show recyclebin

-- ok lets restore back


FLASHBACK TABLE RECYCLETEST TO BEFORE DROP;
select * from tab where tname like '%REC%';

SQL>

Table dropped

Table created

TNAME TABTYPE CLUSTERID


------------------------------ ------- ----------
RECYCLETEST TABLE

Table dropped

TNAME TABTYPE CLUSTERID


------------------------------ ------- ----------
BIN$6V3qqZH/Q1ascMRsn5uImg==$0 TABLE

Done

TNAME TABTYPE CLUSTERID


------------------------------ ------- ----------
RECYCLETEST TABLE

Similar to windows you may want to free the recyclebin in time.

* For an index, table or tablespace you can use;

PURGE TABLE TEST; or PURGE TABLE “BIN$04LhcpndanfgMAAAAAANPw==$0";


purge index in_test1_01;
PURGE TABLESPACE USERS; or PURGE TABLESPACE USERS USER SCOTT;

* For the all objects belonging to the user ;

PURGE RECYCLEBIN;

* As a DBA all objects;

PURGE DBA_RECYCLEBIN;

Some important notes related to this subject are;

* When you flashback a table the triggers and indexes are not returned with their original
names. This can be fixed by running an extra alter index or alter trigger statement.
* Not only you may want to flashback a table that is dropped, like Versions query a whole table
can be flashbacked in time;

FLASHBACK TABLE RECYCLETEST TO SCN 2202666520;

* If there are tables with same names in Recyclebin they can be restores with different names;

FLASHBACK TABLE TEST TO BEFORE DROP RENAME TO TEST2;


FLASHBACK TABLE TEST TO BEFORE DROP RENAME TO TEST1;
Pseudocolumn Name Description
VERSIONS_STARTSCN Starting System Change Number (SCN) or TIMESTAMP
when the row version was created. This pseudocolumn
VERSIONS_STARTTIM identifies the time when the data first had the values
E reflected in the row version. Use this pseudocolumn to
identify the past target time for Oracle Flashback Table or
Oracle Flashback Query.

If this pseudocolumn is NULL, then the row version was


created before start.
VERSIONS_ENDSCN SCN or TIMESTAMP when the row version expired.

VERSIONS_ENDTIME If this pseudocolumn is NULL, then either the row version


was current at the time of the query or the row
corresponds to a DELETE operation.
VERSIONS_XID Identifier of the transaction that created the row version.
VERSIONS_OPERATIO Operation performed by the transaction: I for insertion, D
N for deletion, or U for update. The version is that of the row
that was inserted, deleted, or updated; that is, the row
after an INSERT operation, the row before a DELETE
operation, or the row affected by an UPDATE operation.

For user updates of an index key, Oracle Flashback Version


Query might treat an UPDATE operation as two operations,
DELETE plus INSERT, represented as two version rows
with a Dfollowed by an I VERSIONS_OPERATION.
Using Oracle Flashback Transaction Query with Oracle
Flashback Version Query
This example uses simple versions of the employees and departments tables in
the sample HR schema.

In this example, a database administrator uses SQL*Plus to do the following:

CREATE TABLE emp


(empno NUMBER PRIMARY KEY,
empname VARCHAR2(16)
salary NUMBER);
INSERT INTO emp VALUES (111, 'Mike', 555);
COMMIT;

CREATE TABLE dept


(deptno NUMBER,
deptname VARCHAR2(32));
INSERT INTO dept VALUES (10, 'Accounting');
COMMIT;

Now emp and dept have one row each. In terms of row versions, each table has one
version of one row. Suppose that an erroneous transaction deletes empno 111 from
table emp:

UPDATE emp SET salary = salary + 100 WHERE empno = 111;


INSERT INTO dept VALUES (20, 'Finance');
DELETE FROM emp WHERE empno = 111;
COMMIT;

Next, a transaction reinserts empno 111 into the emp table with a new employee
name:

INSERT INTO emp VALUES (111, 'Tom', 777);


UPDATE emp SET salary = salary + 100 WHERE empno = 111;
UPDATE emp SET salary = salary + 50 WHERE empno = 111;
COMMIT;

The database administrator detects the application error and must diagnose the
problem. The database administrator issues the following query to retrieve versions of
the rows in the emp table that correspond to empno 111. The query uses Oracle
Flashback Version Query pseudocolumns:
SELECT versions_xid XID, versions_startscn START_SCN,
versions_endscn END_SCN, versions_operation OPERATION,
empname, salary FROM hr.emp
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE
where empno = 111;

XID START_SCN END_SCN OPERATION EMPNAME


SALARY
---------------- ---------- --------- ---------- ----------
----------
0004000700000058 113855 I Tom
927
000200030000002D 113564 D Mike
555
000200030000002E 112670 113564 I Mike
555
3 rows selected

The results table rows are in descending chronological order. The third row corresponds
to the version of the row in the table emp that was inserted in the table when the table
was created. The second row corresponds to the row in emp that the erroneous
transaction deleted. The first row corresponds to the version of the row in emp that
was reinserted with a new employee name.

The database administrator identifies transaction 000200030000002D as the


erroneous transaction and uses Oracle Flashback Transaction Query to audit all changes
made by this transaction:

SELECT xid, start_scn START, commit_scn COMMIT, operation


OP, logon_user USER, undo_sql
FROM flashback_transaction_query
WHERE xid = HEXTORAW('000200030000002D');

XID START COMMIT OP USER UNDO_SQL


---------------- ----- ------ -- ----
---------------------------
000200030000002D 195243 195244 DELETE HR insert
into "HR"."EMP"
("EMPNO","EMPNAME","SALARY") values ('111','Mike','655');

000200030000002D 195243 195244 INSERT HR delete


from "HR"."DEPT"
where ROWID = 'AAAKD4AABAAAJ3BAAB';
000200030000002D 195243 195244 UPDATE HR update
"HR"."EMP"
set "SALARY" = '555' where ROWID = 'AAAKD2AABAAAJ29AAA';

000200030000002D 195243 113565 BEGIN HR

4 rows selected

To see the details of the erroneous transaction and all subsequent transactions, the
database administrator performs the following query:

SELECT xid, start_scn, commit_scn, operation, table_name,


table_owner
FROM flashback_transaction_query
WHERE table_owner = 'HR' AND
start_timestamp >=
TO_TIMESTAMP ('2002-04-16 11:00:00','YYYY-MM-DD
HH:MI:SS');

XID START_SCN COMMIT_SCN OPERATION TABLE_NAME


TABLE_OWNER
---------------- --------- ---------- --------- ----
-----------
0004000700000058 195245 195246 UPDATE EMP
HR
0004000700000058 195245 195246 UPDATE EMP
HR
0004000700000058 195245 195246 INSERT EMP
HR
000200030000002D 195243 195244 DELETE EMP
HR
000200030000002D 195243 195244 INSERT DEPT
HR
000200030000002D 195243 195244 UPDATE EMP
HR

6 rows selected
Using ORA_ROWSCN
ORA_ROWSCN is a pseudocolumn of any table that is not fixed or external. It
represents the SCN of the most recent change to a given row; that is, the latest
COMMIT operation for the row. For example:

SELECT ora_rowscn, last_name, salary


FROM employees
WHERE employee_id = 7788;

ORA_ROWSCN NAME SALARY


---------- ---- ------
202553 Fudd 3000

The latest COMMIT operation for the row took place at approximately SCN 202553. To
convert an SCN to the corresponding TIMESTAMP value, use the function
SCN_TO_TIMESTAMP.

ORA_ROWSCN is a conservative upper bound of the latest commit time—the actual


commit SCN can be somewhat earlier. ORA_ROWSCN is more precise (closer to the
actual commit SCN) for a row-dependent table (created using CREATE TABLE with
the ROWDEPENDENCIES clause).

Uses of ORA_ROWSCN in application development include concurrency control and


client cache invalidation.
CONNECT TO SYS as SYSDBA

SQL> shutdown immediate;


Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.

Total System Global Area 184549376 bytes


Fixed Size 1300928 bytes
Variable Size 157820480 bytes
Database Buffers 25165824 bytes
Redo Buffers 262144 bytes
Database mounted.

SQL> alter database archivelog;


Database altered.

SQL> alter system set DB_FLASHBACK_RETENTION_TARGET=4320;


System altered.

SQL> alter system set DB_RECOVERY_FILE_DEST_SIZE=536870912;


System altered.

SQL> alter system set DB_RECOVERY_FILE_DEST='/u02/fra';


System altered.

SQL> alter database flashback on;


Database altered.

SQL> alter database open;


Database altered.

CONNECT TO Other Users

SQL> create table test_table


(
id number(2),
name varchar2(30)

);

Table created.

SQL> insert into test_table values (1, 'Ben Rockwood');


1 row created.

SQL> insert into test_table values (2, 'Tamarah Rockwood');


1 row created.
SQL> insert into test_table values (3, 'Nova Rockwood');
1 row created.

SQL> insert into test_table values (4, 'Hunter Rockwood');


1 row created.

SQL> select * from test_table;


ID NAME
---------- ------------------------------
1 Ben Rockwood
2 Tamarah Rockwood
3 Nova Rockwood
4 Hunter Rockwood

SQL> drop table test_table;


Table dropped.

SQL> select * from test_table;


select * from test_table
*
ERROR at line 1:
ORA-00942: table or view does not exist

SQL> flashback table "test_table" to before drop;


flashback table "test_table" to before drop
*
ERROR at line 1:
ORA-38305: object not in RECYCLE BIN

SQL> flashback table "TEST_TABLE" to before drop;

Flashback complete.

SQL> select * from test_table;

ID NAME
---------- ------------------------------
1 Ben Rockwood
2 Tamarah Rockwood
3 Nova Rockwood
4 Hunter Rockwood

También podría gustarte