You are on page 1of 15

Flashback Query

Flashback Query allows the contents of a table to be queried with


reference to a specific point in time, using the AS OF clause.
The query explicitly references a past time using a timestamp or SCN. It
returns committed data that was current at that point in time.
Potential uses of Flashback Query include:
Recovering lost data or undoing incorrect, committed changes. For
example, if you mistakenly delete or update rows, and then commit them,
you can immediately repair the mistake.
Comparing current data with the corresponding data at some time in the
past. For example, you might run a daily report that shows the change in
data from yesterday. You can compare individual rows of table data, or
find intersections or unions of sets of rows.
Checking the state of transactional data at a particular time. For example,
you could verify the account balance of a certain day.
Simplifying application design, by removing the need to store some kinds
of temporal data. Using a Flashback Query, you can retrieve past data
directly from the database.
Applying packaged applications, such as report generation tools, to past
data.
Providing self-service error correction for an application, enabling users
to undo and correct their errors.

CREATE TABLE flashback_query_test (


id NUMBER(10)
);

SELECT current_scn, TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD


HH24:MI:SS') FROM v$database;

CURRENT_SCN TO_CHAR(SYSTIMESTAM
----------- -------------------
722452 2004-03-29 13:34:12

INSERT INTO flashback_query_test (id) VALUES (1);


COMMIT;

SELECT COUNT(*) FROM flashback_query_test;

COUNT(*)
----------
1
SELECT COUNT(*) FROM flashback_query_test AS OF TIMESTAMP
TO_TIMESTAMP('2004-03-29 13:34:12', 'YYYY-MM-DD
HH24:MI:SS');

COUNT(*)
----------
0

SELECT COUNT(*) FROM flashback_query_test AS OF SCN 722452;

COUNT(*)
----------
0

Examining Past Data: Example

This example uses a Flashback Query to examine the state of a table at a


previous time. Suppose, for instance, that a DBA discovers at 12:30 PM
that data for employee JOHN had been deleted from the employee table,
and the DBA knows that at 9:30AM the data for JOHN was correctly
stored in the database. The DBA can use a Flashback Query to examine
the contents of the table at 9:30, to find out what data had been lost. If
appropriate, the DBA can then re-insert the lost data in the database.
The following query retrieves the state of the employee record
for JOHN at 9:30AM, April 4, 2003:
SELECT * FROM employee AS OF TIMESTAMP
TO_TIMESTAMP('2003-04-04 09:30:00', 'YYYY-MM-DD
HH:MI:SS')
WHERE name = 'JOHN';

This update then restores John's information to the employee table:


INSERT INTO employee
(SELECT * FROM employee AS OF TIMESTAMP
TO_TIMESTAMP('2003-04-04 09:30:00', 'YYYY-MM-DD
HH:MI:SS')
WHERE name = 'JOHN');

Flashback Version Query

Flashback version query allows the versions of a specific row to be


tracked during a specified time period using the VERSIONS
BETWEEN clause.
CREATE TABLE flashback_version_query_test (
id NUMBER(10),
description VARCHAR2(50)
);

INSERT INTO flashback_version_query_test (id, description) VALUES


(1, 'ONE');
COMMIT;

SELECT current_scn, TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD


HH24:MI:SS') FROM v$database;

CURRENT_SCN TO_CHAR(SYSTIMESTAM
----------- -------------------
725202 2004-03-29 14:59:08

UPDATE flashback_version_query_test SET description = 'TWO'


WHERE id = 1;
COMMIT;
UPDATE flashback_version_query_test SET description = 'THREE'
WHERE id = 1;
COMMIT;

SELECT current_scn, TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD


HH24:MI:SS') FROM v$database;

CURRENT_SCN TO_CHAR(SYSTIMESTAM
----------- -------------------
725219 2004-03-29 14:59:36

COLUMN versions_startscn FORMAT 99999999999999999


COLUMN versions_starttime FORMAT A24
COLUMN versions_endscn FORMAT 99999999999999999
COLUMN versions_endtime FORMAT A24
COLUMN versions_xid FORMAT A16
COLUMN versions_operation FORMAT A1
COLUMN description FORMAT A11
SET LINESIZE 200

SELECT versions_startscn, versions_starttime,


versions_endscn, versions_endtime,
versions_xid, versions_operation,
description
FROM flashback_version_query_test
VERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP('2004-
03-29 14:59:08', 'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP('2004-03-29 14:59:36', 'YYYY-MM-DD
HH24:MI:SS')
WHERE id = 1;

VERSIONS_STARTSCN VERSIONS_STARTTIME
VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID
V DESCRIPTION
------------------ ------------------------ ------------------ ------------------------
---------------- - -----------
725212 29-MAR-04 02.59.16 PM
02001C0043030000 U THREE
725209 29-MAR-04 02.59.16 PM 725212 29-MAR-04
02.59.16 PM 0600030021000000 U TWO
725209 29-MAR-04 02.59.16 PM
ONE
SELECT versions_startscn, versions_starttime,
versions_endscn, versions_endtime,
versions_xid, versions_operation,
description
FROM flashback_version_query_test
VERSIONS BETWEEN SCN 725202 AND 725219
WHERE id = 1;

VERSIONS_STARTSCN VERSIONS_STARTTIME
VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID
V DESCRIPTION
------------------ ------------------------ ------------------ ------------------------
---------------- - -----------
725212 29-MAR-04 02.59.16 PM
02001C0043030000 U THREE
725209 29-MAR-04 02.59.16 PM 725212 29-MAR-04
02.59.16 PM 0600030021000000 U TWO
725209 29-MAR-04 02.59.16 PM
ONE
The available pseudocolumn meanings are:
VERSIONS_STARTSCN or VERSIONS_STARTTIME - Starting SCN
and TIMESTAMP when row took on this value. The value of NULL is
returned if the row was created before the lower bound SCN ot
TIMESTAMP.
VERSIONS_ENDSCN or VERSIONS_ENDTIME - Ending SCN and
TIMESTAMP when row last contained this value. The value of NULL is
returned if the value of the row is still current at the upper bound SCN ot
TIMESTAMP.
VERSIONS_XID - ID of the transaction that created the row in it's
current state.
VERSIONS_OPERATION - Operation performed by the transaction
((I)nsert, (U)pdate or (D)elete)

Flashback Transaction Query

Flashback transaction query can be used to get extra information about


the transactions listed by flashback version queries.
The VERSIONS_XID column values from a flashback version query can
be used to query the FLASHBACK_TRANSACTION_QUERY view.
SELECT xid, operation, start_scn,commit_scn, logon_user, undo_sql
FROM flashback_transaction_query
WHERE xid = HEXTORAW('0600030021000000');

XID OPERATION START_SCN COMMIT_SCN


---------------- -------------------------------- ---------- ----------
LOGON_USER
------------------------------
UNDO_SQL
-----------------------------------------------------------------------------------------
-----------
0600030021000000 UPDATE 725208 725209
SCOTT
update "SCOTT"."FLASHBACK_VERSION_QUERY_TEST" set
"DESCRIPTION" = 'ONE' where ROWID = 'AAAMP9AAEAAAA
AYAAA';

0600030021000000 BEGIN 725208 725209


SCOTT

XID OPERATION START_SCN COMMIT_SCN


---------------- -------------------------------- ---------- ----------
LOGON_USER
------------------------------
UNDO_SQL
-----------------------------------------------------------------------------------------
-----------
2 rows selected.

Flashback Transaction Query and Flashback Version Query:


Example

This example demonstrates the use of a Flashback Transaction Query in


conjunction with a Flashback Version Query. The example assumes
simple variations of the employee and departmentstables in the
sample hr schema.
In this example, a DBA carries out the following series of actions in
SQL*Plus:
connect hr/hr
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;

At this point, emp and dept have one row each. In terms of row versions,


each table has one version of one row. Next, suppose that an erroneous
transaction deletes employee id 111 from tableemp:
UPDATE emp SET salary = salary + 100 where empno = 111;
INSERT INTO dept VALUES (20, 'Finance');
DELETE FROM emp WHERE empno = 111;
COMMIT;

Subsequently, a new transaction reinserts employee id 111 with a new


employee name into the emp table.
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;

At this point, the DBA detects the application error and needs to diagnose
the problem. The DBA issues the following query to retrieve versions of
the rows in the emp table that correspond to empno 111. The query uses
Flashback Version Query pseudocolumns.
connect dba_name/password
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 reads chronologically, from bottom to top. The third row
corresponds to the version of the row in emp that was originally inserted
in the table when the table was created. The second row corresponds to
the row in emp that was deleted by the erroneous transaction. The first
row corresponds to the version of the row in emp that was reinserted with
a new employee name.
The DBA identifies transaction 000200030000002D as the erroneous
transaction and issues the following 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

The rightmost column (undo_sql) contains the SQL code that will undo
the corresponding change operation. The DBA can execute this code to
undo the changes made by that transaction. TheUSER column
(logon_user) shows the user responsible for the transaction.
A DBA might also be interested in knowing all changes made in a certain
time window. In our scenario, the DBA performs the following query to
view the details of all transactions that executed since the erroneous
transaction identified earlier (including the erroneous transaction itself):
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

Flashback Tips - Performance

For better performance, generate statistics on all tables involved in a


Flashback Query by using the DBMS_STATS package, and keep the
statistics current. Flashback Query always uses the cost-based optimizer,
which relies on these statistics.
The performance of a query into the past depends on how much undo
data must be accessed. For better performance, use queries to select small
sets of past data using indexes, not to scan entire tables. If you must do a
full table scan, consider adding a parallel hint to the query.
The performance cost in I/O is the cost of paging in data and undo blocks
that are not already in the buffer cache. The performance cost in CPU use
is the cost of applying undo information to affected data blocks. When
operating on changes in the recent past, flashback features essentially
CPU bound.
Use index structures for Flashback Version Query: the database keeps
undo data for index changes as well as data changes. Performance of
index lookup-based Flashback Version Query is an order of magnitude
faster than the full table scans that are otherwise needed.
In a Flashback Transaction Query, the type of the xid column is RAW(8).
To take advantage of the index built on the xid column, use
the HEXTORAW conversion function: HEXTORAW(xid).
Flashback Query against a materialized view does not take advantage of
query rewrite optimizations.

Flashback Table

The FLASHBACK TABLE command allows point in time recovery of


individual tables subject to the following requirements.
You must have either the FLASHBACK ANY TABLE system privilege
or have FLASHBACK object privilege on the table.
You must have SELECT, INSERT, DELETE, and ALTER privileges on
the table.
There must be enough information in the undo tablespace to complete the
operation.
Row movement must be enabled on the table (ALTER TABLE tablename
ENABLE ROW MOVEMENT;).
The following example creates a table, inserts some data and flashbacks
to a point prior to the data insertion. Finally it flashbacks to the time after
the data insertion.
CREATE TABLE flashback_table_test (
id NUMBER(10)
);

ALTER TABLE flashback_table_test ENABLE ROW MOVEMENT;

SELECT current_scn FROM v$database;

CURRENT_SCN
-----------
715315

INSERT INTO flashback_table_test (id) VALUES (1);


COMMIT;
SELECT current_scn FROM v$database;

CURRENT_SCN
-----------
715340

FLASHBACK TABLE flashback_table_test TO SCN 715315;

SELECT COUNT(*) FROM flashback_table_test;

COUNT(*)
----------
0

FLASHBACK TABLE flashback_table_test TO SCN 715340;

SELECT COUNT(*) FROM flashback_table_test;

COUNT(*)
----------
1
Flashback of tables can also be performed using timestamps.
FLASHBACK TABLE flashback_table_test TO TIMESTAMP
TO_TIMESTAMP('2004-03-03 10:00:00', 'YYYY-MM-DD HH:MI:SS');

Performing Flashback Table


The following SQL*Plus statement performs a FLASHBACK
TABLE operation on the table employee:
FLASHBACK TABLE employee TO TIMESTAMP
TO_TIMESTAMP('2003-04-04 09:30:00', `YYYY-MM-DD
HH24:MI:SS');

The employee table is restored to its state when the database was at the


time specified by the timestamp.
You can also specify the target point in time for the FLASHBACK
TABLE operation using an SCN:
FLASHBACK TABLE employee TO SCN 123456;

The default for a FLASHBACK TABLE operation is for triggers on a


table to be disabled. The database disables triggers for the duration of the
operation, and then returns them to the state that they were in before the
operation was started. If you wish for the triggers to stay enabled, then
use the ENABLE TRIGGERS clause of the FLASHBACK
TABLE statement, as shown in this example:
FLASHBACK TABLE t1 TO TIMESTAMP '2003-03-03 12:05:00'
ENABLE TRIGGERS;

The following scenario is typical of the kind of logical corruption where


Flashback Table could be used:
At 17:00 an HR administrator discovers that an employee "JOHN" is
missing from the EMPLOYEE table. This employee was present at 14:00,
the last time she ran a report. Someone accidentally deleted the record for
"JOHN" between 14:00 and the present time. She uses Flashback Table to
return the table to its state at 14:00, as shown in this example:
FLASHBACK TABLE EMPLOYEES TO TIMESTAMP
TO_TIMESTAMP('2003-04-04 14:00:00','YYYY-MM-DD
HH:MI:SS')
ENABLE TRIGGERS;

Flashback Drop (Recycle Bin)

In Oracle 10g the default action of a DROP TABLE command is to move


the table to the recycle bin (or rename it), rather than actually dropping it.
The DROP TABLE ... PURGE option can be used to permanently drop a
table.
DROP TABLE my_table PURGE;
The recycle bin is a logical collection of previously dropped objects, with
access tied to the DROP privilege. This feature does not use flashback
logs or undo, so it is independent of the other flashback technologies. The
contents of the recycle bin can be shown using the SHOW
RECYCLEBIN command and purged using the PURGE
TABLE command. As a result, a previously dropped table can be
recovered from the recycle bin.
CREATE TABLE flashback_drop_test (
id NUMBER(10)
);

INSERT INTO flashback_drop_test (id) VALUES (1);


COMMIT;

DROP TABLE flashback_drop_test;

SHOW RECYCLEBIN
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE
DROP TIME
---------------- ------------------------------ ------------ -------------------
FLASHBACK_DROP_T BIN$TstgCMiwQA66fl5FFDTBgA==$0
TABLE 2004-03-29:11:09:07
EST

FLASHBACK TABLE flashback_drop_test TO BEFORE DROP;

SELECT * FROM flashback_drop_test;

ID
----------
1
Tables in the recycle bin can be queried like any other table.
DROP TABLE flashback_drop_test;

SHOW RECYCLEBIN

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE


DROP TIME
---------------- ------------------------------ ------------ -------------------
FLASHBACK_DROP_T BIN$TDGqmJZKR8u+Hrc6PGD8kw==$0
TABLE 2004-03-29:11:18:39
EST

SELECT * FROM "BIN$TDGqmJZKR8u+Hrc6PGD8kw==$0";

ID
----------
1
If an object is dropped and recreated multiple times all dropped versions
will be kept in the recycle bin, subject to space. Where multiple versions
are present it's best to reference the tables via
the RECYCLEBIN_NAME. For any references to
the ORIGINAL_NAME it is assumed the most recent object is drop
version in the referenced question. During the flashback operation the
table can be renamed.
FLASHBACK TABLE flashback_drop_test TO BEFORE DROP
RENAME TO flashback_drop_test_old;
Several purge options exist.
PURGE TABLE tablename; -- Specific table.
PURGE INDEX indexname; -- Specific index.
PURGE TABLESPACE ts_name; -- All tables in a specific
tablespace.
PURGE TABLESPACE ts_name USER username; -- All tables in a
specific tablespace for a specific user.
PURGE RECYCLEBIN; -- The current users entire recycle
bin.
PURGE DBA_RECYCLEBIN; -- The whole recycle bin.
Several restrictions apply relating to the recycle bin.
Only available for non-system, locally managed tablespaces.
There is no fixed size for the recycle bin. The time an object remains in
the recycle bin can vary.
The objects in the recycle bin are restricted to query operations only (no
DDL or DML).
Flashback query operations must reference the recycle bin name.
Tables and all dependent objects are placed into, recovered and purged
from the recycle bin at the same time.
Tables with Fine Grained Access policies aer not protected by the recycle
bin.
Partitioned index-organized tables are not protected by the recycle bin.
The recycle bin does not preserve referential integrity.
This feature can be disabled/enabled at the session or system level.
-- Session level.
ALTER SESSION SET recyclebin = OFF;
ALTER SESSION SET recyclebin = ON;

-- System level.
ALTER SYSTEM SET recyclebin = OFF;
ALTER SYSTEM SET recyclebin = ON;
Viewing and Querying Objects in the Recycle Bin
You can view the contents of the recycle bin using the SQL*Plus
command SHOW RECYCLEBIN.
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT
TYPE DROP TIME
---------------- --------------------------------- ------------ -------------------
EMPLOYEE_DEMO BIN$gk3lsj/3akk5hg3j2lkl5j3d==$0 TABLE
2003-06-11:17:08:54

The ORIGINAL NAME column shows the orignal name of the object,


while the RECYCLEBIN NAME column shows the name of the object as
it exists in the recycle bin. Use the RECYCLEBIN NAMEwhen issuing
queries against tables in the recycle bin.
Flashback Database

The FLASHBACK DATABASE command is a fast alternative to


performing an incomplete recovery. In order to flashback the database
you must have SYSDBA privilege and the flash recovery area must have
been prepared in advance.
If the database is in NOARCHIVELOG it must be switched
to ARCHIVELOG mode.
CONN sys/password AS SYSDBA
ALTER SYSTEM SET
log_archive_dest_1='location=d:\oracle\oradata\DB10G\archive\'
SCOPE=SPFILE;
ALTER SYSTEM SET log_archive_format='ARC%S_%R.%T'
SCOPE=SPFILE;
SHUTDOWN IMMEDIATE
STARTUP MOUNT
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
Flashback must be enabled before any flashback operations are
performed.
CONN sys/password AS SYSDBA
SHUTDOWN IMMEDIATE
STARTUP MOUNT EXCLUSIVE
ALTER DATABASE FLASHBACK ON;
ALTER DATABASE OPEN;
With flashback enabled the database can be switched back to a previous
point in time or SCN without the need for a manual incomplete recovery.
In the following example a table is created, the database is then
flashbacked to a time before the table was created.
-- Create a dummy table.
CONN scott/tiger
CREATE TABLE flashback_database_test (
id NUMBER(10)
);

-- Flashback 5 minutes.
CONN sys/password AS SYSDBA
SHUTDOWN IMMEDIATE
STARTUP MOUNT EXCLUSIVE
FLASHBACK DATABASE TO TIMESTAMP SYSDATE-(1/24/12);
ALTER DATABASE OPEN RESETLOGS;

-- Check that the table is gone.


CONN scott/tiger
DESC flashback_database_test
Some other variations of the flashback database command include.
FLASHBACK DATABASE TO TIMESTAMP my_date;
FLASHBACK DATABASE TO BEFORE TIMESTAMP my_date;
FLASHBACK DATABASE TO SCN my_scn;
FLASHBACK DATABASE TO BEFORE SCN my_scn;
The window of time that is available for flashback is determined by
the DB_FLASHBACK_RETENTION_TARGET parameter. The
maximum flashback can be determined by querying
the V$FLASHBACK_DATABASE_LOG view. It is only possible to
flashback to a point in time after flashback was enabled on the database
and since the last RESETLOGS command.
Flashback Query Functions
The TIMESTAMP_TO_SCN and SCN_TO_TIMESTAMP functions
have been added to SQL and PL/SQL to simplify flashback operations.
SELECT *
FROM emp AS OF SCN TIMESTAMP_TO_SCN(SYSTIMESTAMP -
1/24);

SELECT *
FROM emp AS OF TIMESTAMP SCN_TO_TIMESTAMP(993240);

DECLARE
l_scn NUMBER;
l_timestamp TIMESTAMP;
BEGIN
l_scn := TIMESTAMP_TO_SCN(SYSTIMESTAMP - 1/24);
l_timestamp := SCN_TO_TIMESTAMP(l_scn);
END;
/

You might also like