Does Flashback Query require undo tablespace?
Jeremy Smith, October 24, 2002 - 5:42 pm UTC
From what I understand, Flashback query requires that you use undo tablespaces, or at least setting the UNDO_RETENTION parameter does. Is that true?
If it is, doesn't using flashback imply that you're going to be using UNDO tablespaces vs. RBS? Or that you'd potentially be keeping undo around a lot longer than you'd normally have to just to handle consistent reads. Can either of these two changes can affect application performance? (the second, obviously, means greater disk usage)
October 24, 2002 - 6:58 pm UTC
Nope -- not true.
With UNDO tablespaces you can deterministically say for how long you will be able to flash back (undo_retention seconds ago at least)
with RBS's (old fashioned ones), it is a crap-shoot. Maybe you can flashback 1/2 hour -- maybe not.
It was this section that makes it ambiguous...
Jeremy Smith, October 24, 2002 - 7:20 pm UTC
From the 9i Application Developer's Guide, section 7:
<quote>
Setting Up the Database for Flashback Query
Before you can perform flashback queries, enlist the help of your DBA. Ask them to:
Use automatic undo management to maintain read consistency, rather than the older technique using rollback segments. In particular, the DBA should:
Set the UNDO_RETENTION initialization parameter to a value that represents how far in the past you might want to query. The value depends on your needs. If you only need to recover data immediately after a mistaken change is committed, the parameter can be set to a small value. If you need to recover deleted data from days before, you might need several days worth of data.
Set the initialization parameter UNDO_MANAGEMENT=AUTO.
Create an UNDO tablespace, with enough space to keep the required data. The more often the data is updated, the more space is required. Calculating the space requirements is a job for the DBA; you can find the formula in the Oracle9i Database Administrator's Guide.
</quote>
It's unclear as to whether they're saying it's just a good idea or required to use auto-undo-management. That ambiguity has caused at least a few people to declare it's required. Of course, anyone writing an article should have checked, but...
Thanks for clearing things up as usual.
October 25, 2002 - 5:58 am UTC
Yes, that would be the best way (so you KNOW how far you can flash) but it is not the ONLY way:
ops$tkyte@ORA920.US.ORACLE.COM> show parameter undo_m
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string MANUAL
ops$tkyte@ORA920.US.ORACLE.COM> connect scott/tiger
scott@ORA920.US.ORACLE.COM> update emp set sal = sal * 1.5;
14 rows updated.
scott@ORA920.US.ORACLE.COM> commit;
Commit complete.
scott@ORA920.US.ORACLE.COM> select a.ename, a.sal new_sal, b.sal old_sal
2 from emp a, <b>emp as of timestamp sysdate-5/24/60 b</b>
3 where a.empno = b.empno
4 /
ENAME NEW_SAL OLD_SAL
---------- ---------- ----------
SMITH 1200 800
ALLEN 2400 1600
WARD 1875 1250
JONES 4462.5 2975
MARTIN 1875 1250
BLAKE 4275 2850
CLARK 3675 2450
SCOTT 4500 3000
KING 7500 5000
TURNER 2250 1500
ADAMS 1650 1100
JAMES 1425 950
FORD 4500 3000
MILLER 1950 1300
14 rows selected.
scott@ORA920.US.ORACLE.COM> update emp
2 set sal = ( select sal from emp <b>as of timestamp</b> sysdate-5/24/60 b where b.empno = emp.empno )
3 /
14 rows updated.
scott@ORA920.US.ORACLE.COM> commit;
Commit complete.
scott@ORA920.US.ORACLE.COM> select ename, sal from emp;
ENAME SAL
---------- ----------
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300
14 rows selected.
scott@ORA920.US.ORACLE.COM>
shows that using old fashioned RBS works as well.
Sagi, October 25, 2002 - 6:11 am UTC
Hi Tom,
Would this work in 8i?
Because TIMESTAMP exists only in 9.
Regards,
Sagi
October 26, 2002 - 11:32 am UTC
and so does flashback (only exists in 9i) so the question is somewhat moot. No, it will not work in 8i because flashback query didn't exist back then
excellent
A reader, July 09, 2003 - 6:49 pm UTC
May be I am confusing things but how does this differ
from the workspace management ability to go to any
point of time and do a select.I know that workspace
offers much more but in terms of the ability to go back
in time and select records, are there any differences.
If we need to maintain history of table data can
we just use flashback. As I am typing in one thing that
comes to my mind is that flashback probably depends on
the undo retention periof where as WM does not?
Please elaborate.
And hats off to you for your awesome support to all of us!
July 09, 2003 - 8:18 pm UTC
flashback = hours, maybe days at most (but hours is practical)
flashback relies on undo being there.
workspace mgmt = the sky be the limit, the data is versioned in the table, keep it for as long as you like.
one difference between workspace and flashback
A reader, July 09, 2003 - 7:12 pm UTC
is that with workspace you could go back forever?
Is that true, Tom?
Thanx!
July 09, 2003 - 8:25 pm UTC
yes.
workspace management
Reader, July 10, 2003 - 8:22 am UTC
Could you please provide a link to learn how to implement using workspace management? Thanks.
flashback for CLOB and BLOB?
Reader, October 27, 2003 - 12:45 pm UTC
Tom, does flashback work for CLOB and BLOB also? Can I flashback to sometime if somebody deleted rows containing BLOBs and CLOBs? Thanks.
October 28, 2003 - 8:27 am UTC
yes, as long as the prior versions of the clobs exist. lobs support read consistency.
What about ALL_SOURCE?
Andrew Clarke, November 25, 2003 - 5:55 am UTC
Someone on the OTN Forums suggested using Flashback Query against ALL_SOURCE as a way of retrieving the text of an accidentally (and not backed-up) procedure. However, it doesn't seem to work.
I would hazard that this is because ALL_SOURCE isn't really a table and data wasn't deleted as such: it was erased as a side effect of an act of DDL. Flashback query is not going to work in this case because the source code of the procedure is not written to the undo tablespace.
Is this correct or do you have a better expalnation?
Cheers, APC
November 25, 2003 - 7:56 am UTC
ops$tkyte@ORA920PC> select text from all_source where name = 'HK_ANALYZE';
TEXT
-----------------------------------------------------------------------------------------------------------------------------------
procedure hk_analyze
(v_schema in varchar2,
v_estimate_pct in number default 0,
....
DBMS_OUTPUT.PUT_LINE('Analysointi alkoi: ' || start_time);
DBMS_OUTPUT.PUT_LINE('Analysointi loppui: ' || stop_time);
end hk_analyze;
43 rows selected.
ops$tkyte@ORA920PC> drop procedure hk_analyze;
Procedure dropped.
ops$tkyte@ORA920PC> @connect "/ as sysdba"
sys@ORA920PC> select text from all_source where name = 'HK_ANALYZE';
no rows selected
sys@ORA920PC> select text from all_source as of timestamp sysdate-5/24/60 where name = 'HK_ANALYZE';
TEXT
-----------------------------------------------------------------------------------------------------------------------------------
procedure hk_analyze
(v_schema in varchar2,
v_estimate_pct in number default 0,
v_degree in number default 1)
...
DBMS_OUTPUT.PUT_LINE('Analysointi alkoi: ' || start_time);
DBMS_OUTPUT.PUT_LINE('Analysointi loppui: ' || stop_time);
end hk_analyze;
43 rows selected.
<b>what issue did you encounter?</b>
ALL_SOURCE revisited
A P Clarke, November 25, 2003 - 7:05 am UTC
Apparently using Flashback Query against ALL_SOURCE works with SYSDBA accounts but not mere mortals. So my guess was wrong.
Does this mean the contents of data dictionary tables are written to UNDO when we execute DDL?
Cheers, APC
November 25, 2003 - 8:10 am UTC
absolutely -- 100%
Can we filter a set of records ?
Sanjaya Balasuriya, January 26, 2004 - 10:56 pm UTC
Tom,
With flashback queries, can filter a set of records ?
For example, at 14.00 can I select the records inserted between 08.00 and 11.00 ?
Thanks in advance.
-San
January 27, 2004 - 8:42 am UTC
in 10g -- yes, easily, using the versions between clause in SQL.
In 9i, sort of. You can detect "new primary keys" (using minus -- you can find all of the keys as of 11am that did not exist at 8am) and then retrieve the rest of the data.
Thanks
Sanjaya Balasuriya, January 27, 2004 - 11:46 pm UTC
Thanks Tom.
I read the documentation and identified that I can identify insertions and deletion with simple queries using minus.
And to identify updates I can check some key with some other data.
I'd like to know that is flashback query is a solid method for such a thing ?
Currently, we use triggers to identify data changes (updates, inserts, deleles). But these triggers slows downs the operations.
Is it a good idea to replace this trigger system with flashback query system ? Is it reliable ?
Thanks in advance.
And when are you going to release 10g ?
January 28, 2004 - 8:23 am UTC
flashback is not forever. there is always the chance that the data you want to flashback won't be in undo anymore (well, until 10g when you can "guarantee" the undo retention)
first qtr of 2004
Flashback forever?
Cefers.br, March 02, 2004 - 6:55 am UTC
[...well, until 10g when you can "guarantee" the undo retention...]
About the statement above, how exactally will this "undo guarantee" work? In 10g, will it be possible to flashback to any time in the past? (I heard something about, but I´m not sure).
Thank you.
March 02, 2004 - 7:50 am UTC
the undo retention is still "5 days max" but you can now say "guarantee the undo retention I set is met. do not prematurely expire undo extents"
Where does it take it information
Arangaperumal, April 28, 2004 - 6:51 am UTC
Hi Tom,
FLASHBACK query gives the information at specified time.
1.where does it store those information?
2.How does oracle get it?
flashback table 10g new feature
Marcio, May 18, 2004 - 2:06 pm UTC
By default flashback table is enable -- Is it possible disable flashback table?
Always to drop (real drop) do I must "drop table t purge;"?
Isn't it an overhead?
May 18, 2004 - 9:16 pm UTC
by default, flashback table actually isn't "on", you need to generally alter table enable row movement first
but, if you have the ability to modify the table, you can pretty much flashback. I mean:
delete from t;
insert into t select * from t as of sysdate-1;
is a poor mans flashback table, it is just SQL after all under the covers.
the recycle bin is not overhead, you will be overjoyed with it someday, I am 100% sure on that. see
</code>
http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:18064818873846#18419474537343 <code>
it is intelligently implemented, it will not cause your tablespaces to grow, just saves your butt big time when you mess up.
there is a purge command itself to clean out the recycle bin if you want.
Where did i do ERROR- oracle 8.1.7
Arangaperumal, July 27, 2004 - 7:33 am UTC
Hi Tom,
SQL> select ename,sal from emp;
ENAME SAL
---------- ----------
KING 5000
BLAKE 2850
CLARK 2450
JONES 2975
FORD 3000
SMITH 800
ALLEN 1600
WARD 1250
MARTIN 1250
SCOTT 3000
TURNER 1500
ENAME SAL
---------- ----------
ADAMS 1100
JAMES 950
MILLER 1300
14 rows selected.
SQL> update emp set sal=sal*1.5
2 /
14 rows updated.
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7839 KING PRESIDENT 17-NOV-81 7500 10
7698 BLAKE MANAGER 7839 01-MAY-81 4275 30
7782 CLARK MANAGER 7839 09-JUN-81 3675 10
7566 JONES MANAGER 7839 02-APR-81 4462.5 20
7902 FORD ANALYST 7566 03-DEC-81 4500 20
7369 SMITH CLERK 7902 17-DEC-80 1200 20
7499 ALLEN SALESMAN 7698 20-FEB-81 2400 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1875 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1875 1400 30
7788 SCOTT ANALYST 7566 09-DEC-82 4500 20
7844 TURNER SALESMAN 7698 08-SEP-81 2250 0 30
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7876 ADAMS CLERK 7788 12-JAN-83 1650 20
7900 JAMES CLERK 7698 03-DEC-81 1425 30
7934 MILLER CLERK 7782 23-JAN-82 1950 10
14 rows selected.
SQL> commit
2 /
Commit complete.
SQL> select a.ename,a.sal new_sal,b.sal old_sal from
2 emp a, emp b as of timestamp sysdate-26-JUL-04
3 /
emp a, emp b as of timestamp sysdate-26-JUL-04
*
ERROR at line 2:
ORA-00933: SQL command not properly ended
SQL> select sysdate from dual;
SYSDATE
---------
27-JUL-04
SQL> select a.ename, a.sal new_sal, b.sal old_sal
2 from emp a, emp as of timestamp sysdate-26/JUL/04 b
3 where a.empno = b.empno
4 /
from emp a, emp as of timestamp sysdate-26/JUL/04 b
*
ERROR at line 2:
ORA-00933: SQL command not properly ended
SQL>
July 27, 2004 - 7:48 am UTC
what is sysdate-26-jul-04
that is nothing ???
that is a function (sysdate) minus 26 minus JUL -- but there is no column JUL -- minus 4
maybe you meant something like:
sysdate-(1/24/60*5)
(5 minutes ago)?
for Mr Arangaperumal above
Shailendra, July 28, 2004 - 9:26 am UTC
They are on 8.1.7. so even if they corrected the syntax , flashback would not work.
July 28, 2004 - 1:05 pm UTC
good point :)
You said...
A reader, July 29, 2004 - 12:42 am UTC
Hi Tom,
<quote>
Surprise -- flashback query has been enabled in the database for many many many years.
</quote>
Why contradiction?
July 29, 2004 - 8:06 am UTC
every query you ever ran in Oracle was a flashback query -- it is called multi-versioning and read consistency.
If you want to flashback in say "version 7", just do this:
a) log into sqlplus at 9am.
b) set transaction read only;
c) minimize that window
d) come back 2 hours later and run a query
it'll "flashback to 9am"
we *exposed* it more in 9i so that you can easily pick the point in time at which the query runs "as of"...
Does Flashback Query survive a database bounce?
Ken Naim, October 15, 2004 - 2:42 pm UTC
Does Flashback Query survive a database bounce?
October 15, 2004 - 5:50 pm UTC
yes, you can flashback over a bounce. in fact, you can extend the theoretical limit of the flashback from 5 days to whatever you want using that....
shutdown for a year, startup, you can flashback a year and 5 days instead of just 5 days.
How does it work?
A reader, November 05, 2004 - 5:52 pm UTC
In 9iR2, I was pleasantly surprised to see that I can do
select * from complex_view as of timestamp sysdate - interval '5' hour and it just works!
How is this implemented? Does it see if it can find blocks to satisfy the query during the parse phase? Does it need only the minimum set of blocks that my query needs i.e. after applying all the filters and predicates in the query? Or would need the entire table to exist as of that time?
Can you shed some light on this? Thanks
November 05, 2004 - 6:21 pm UTC
This feature has always been in Oracle -- just exposed to you.
If you did this at 9am:
sql> variable x refcursor
sql> exec open :x for select * from a_50_billion_row_table;
it would happen "immediately" -- no io is performed, it just set the SCN for the query and set up the cursor area. We didn't copy the data or anything like that.
Now, you go away for 5 hours and when you come back you:
sql> print x
the data will come out "as it existed at 9am". That is read consistency, supported by our multi-versioning.
The "as of timestamp" takes your date and within about 5 minutes (the timestamp is about +/- 2.5 minutes in 9i, +/- 3 seconds in 10g -- the SCN one is precise) finds the SCN that was current then and opens your query with THAT scn instead of the SCN as of right now.
You could also (at 9am)
SQL> set transaction read only;
go away for 5 hours -- and when you come back, every query you run will be "as of 5 hours ago"
(this has been true since about v4 -- all queries are done read consistent and as of a point in time)
We use the undo to reconstuct the blocks -- the concepts guide has a good chapter on this (and i cover it in Expert one on one Oracle). It is THE difference between Oracle and the others in my opinion. Perhaps the most important thing to learn about Oracle.
ORA-8180
A reader, November 05, 2004 - 5:57 pm UTC
I tried as of timestamp sysdate - interval '2' day and got
08180, 00000, "no snapshot found based on specified time"
// *Cause: Could not match the time to an SCN from the mapping table.
// *Action: try using a larger time.
I thought I would get a ORA-1555? What does the above error mean by "try using a larger time"?
Thanks
November 05, 2004 - 6:26 pm UTC
by "larger" they meant one "greater than sysdate- 2 days"
1555 comes when we cannot find undo from 2 days ago, this is saying "sorry the smon scn to time table doesn't have an entry from 2 days ago, we don't know what SCN therefore to use"
A reader, November 05, 2004 - 8:16 pm UTC
What is the name of that smon scn to time mapping table?
"by "larger" they meant one "greater than sysdate- 2 days""
That means the mapping table only has 1 days worths of data and I am asking for something older than that? So I guess the error mesasge is a little misleading, it should say "try using a more recent timestamp"
November 06, 2004 - 10:20 am UTC
sys@ORA9IR2> desc smon_scn_time
Name Null? Type
---------------------------------------- -------- ----------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
it is a mapping of TIME to SCN maintained by SMON.
A reader, March 15, 2005 - 11:58 am UTC
Flashback schema
A reader, March 16, 2005 - 2:00 pm UTC
Can this flashback feature be used to rollback changes(DML and DDL ) in all tables in a schema? or the hot backup restore to a certain time is a better option?
March 17, 2005 - 7:46 am UTC
In 9ir2, flashback query is available. You can query tables as of a previous point in time (assuming undo exists) but not over DDL changes (so no to DDL).
You can "rollback" a table to a prior point in time by:
create table temp as select * from T as of scn|timestamp :x;
if that succeeds, truncate table t, insert /*+ append */ into t select * from temp;
that'll put the table "back" the way it was.
In 10g, you have
o flashback query
o flashback table (automates the above and does minimal work to restore the table)
o flashback drop (undrop a table)
o flashback row history (see all versions of a row(s) between two times)
o flashback transaction (give me dml to undo a specific transaction)
o flashback database (put the database back the way it was N minutes ago)
A reader, June 21, 2005 - 7:56 pm UTC
Tom,
In this POST I noticed two places where you mention about old rollback segments...
<Quote>
with RBS's (old fashioned ones), it is a crap-shoot. Maybe you can flashback 1/2 hour -- maybe not.
</Quote>
and
<Quote>
shows that using old fashioned RBS works as well
</Quote>
What I am confused about is, in version 9.2.0.4 FLASHBACK-QUERY works OK with old style rollback segments???
If yes, then are there any limitations as compared to datbases using AUM??? I have RETENTION_PERIOD set to a value of 900. My other question is, that is FLASHBACK functionality enabled by default, when a new database is created, or it needs some setup?
here are the parameter setup,
SQL> sho parameter undo
NAME TYPE VALUE
------------------------------------ ------- ------
undo_management string MANUAL
undo_retention integer 900
undo_suppress_errors boolean FALSE
undo_tablespace string null
Thanks for your help.
June 21, 2005 - 11:55 pm UTC
they work "OK" but as stated it is more of a "crap shoot", you don't have the undo_retention parameter to help you out -- undo_retention works with AUM only.
flashback query is always there.
A reader, June 22, 2005 - 12:48 am UTC
So let me try to paraphrase this, it is not gauranteed that you can recover the data for sure with MANUAL (as it is in AUM) but only if you are lucky and changes are still sitting in the same RBS(no other transaction has overridden those changes in the RBS), you can recover the changes...and all the undo_xxxx.. parameters are useless.
Thanks
June 22, 2005 - 6:40 am UTC
no, there is less chance you can with manual RBS's since you don't have undo_retention.
Until 10g when undo_retention can be a mandate -- not just a request, you are not gauranteed with AUM either, but it is much easier to be a lot more sure you can. Using undo_retention will try to keep the undo you want as long as there is disk space to do so.
A reader, June 22, 2005 - 12:52 am UTC
So let me try to paraphrase this, it is not gauranteed that you can recover the data for sure with MANUAL (as it is in AUM) but only if you are lucky and changes are still sitting in the same RBS(no other transaction has overridden those changes in the RBS), you can recover the changes...and all the undo_xxxx.. parameters are useless with the MANUAL rollbacks.
Thanks
flashback question
Menon, July 27, 2005 - 6:40 pm UTC
Hi Tom
I am working on database version 9.2.0.3.
I am trying to write test cases where I run
a procedure which updates a bunch of tables.
Is it possible for me to do the following:
1. Run the procedure and commit changes
2. Get the relevant data of the table before the procedure ran (i.e. of the data before this transaction)
This can not be done on the basis of timestamp since
the procedure may be too fast.
This way I can compare the before and after images
to find out exactly which columns were changed
for each table.
One workaround could be to capture the before
and after images in a different table of course
but if we can do it with flashback, it would
be neat.
Thank you.
July 27, 2005 - 8:42 pm UTC
flashback query does just exactly that.
get the SCN (dbms_flashback.get_system_change_number)
run and commit your transaction.
select * from table, table as of scn :x where key = key
Hmmm..
Menon, July 27, 2005 - 6:47 pm UTC
May be I can use "as of SCN" for resolving the above
issue...
thanx!
Menon, July 27, 2005 - 9:28 pm UTC
That is what I did :)
flashback in automating tests
Menon, July 29, 2005 - 10:43 am UTC
Well, I think flashback can be used to automate tests
or to have a framework where you dont have to re-invent
the wheel.
Most of our code is about changing table data by running some code. We can compare the before and after images of our code changes. This can also be automated of course. The process would be:
1. For a use case, create data in tables
2. Get SCN before you run your test case (before_scn)
3. Run your code
4. Get SCN after your run (after_scn)
5. Compare all affected table records for before_scn and after_scn.
You can also do this for your earlier version of code and the new version of code to see the differences. Automating this also would be a natural step.
I am curious if people use flashback in this way. What do you guys (Tom and others) think?
July 29, 2005 - 2:39 pm UTC
You just described the demo I use to show how flashback works and how you can use it in a web environment to show the user what they just did to the data
"before the update we had this, after the update we have that"
I've mostly used it to recovery from "whoops" operations so far.
But yes, it is definition a testing tool as well.
Thanx Tom!
Menon, July 29, 2005 - 7:25 pm UTC
diff between from t1 and from t1 as of timestamp sysdate ?
Shiju, August 17, 2005 - 9:01 am UTC
Tom,
Flash back query is giving only COMMITTED/Rollbacked data ,even from the same session.
Why "from t1 as of timestamp sysdate" is different from "from t1", if we don't commit/rollback our transaction?
eg.
create table t1 ( X int)
DevDB> select * from t1 ;
X
----------
0
1
2
4
34
Elapsed: 00:00:00.08
DevDB> select * from t1 as of timestamp sysdate;
X
----------
0
1
2
4
34
Elapsed: 00:00:00.08
DevDB> delete from t1;
5 rows deleted.
Elapsed: 00:00:00.04
DevDB> select * from t1 ;
no rows selected
Elapsed: 00:00:00.04
DevDB> select * from t1 as of timestamp sysdate;
X
----------
0
1
2
4
34
Elapsed: 00:00:00.08
DevDB> commit;
Commit complete.
Elapsed: 00:00:00.04
DevDB> select * from t1 ;
no rows selected
Elapsed: 00:00:00.04
DevDB>
DevDB> select * from t1 as of timestamp sysdate;
no rows selected
Elapsed: 00:00:00.04
DevDB>
August 17, 2005 - 1:52 pm UTC
sigh, no version :(
9i -- as of timestamp is within +- 5minutes
10g -- as of timestamp is within +- 3seconds
but flashback query is as if it were in another session, it is a read consistent query as of that point in time.
Thanks.
Shiju, August 18, 2005 - 3:34 am UTC
Version is 10g.
Thanks for the clarification.
August 18, 2005 - 3:59 pm UTC
same answer as above. the sigh was rhetorical...
Flashback
Nikunj Thaker, September 30, 2005 - 7:54 am UTC
Dear Tom,
I had try through below way but i can't get my data back.
scott@NIKUNJ> select * from test;
no rows selected
scott@NIKUNJ> insert into test select * from tab;
5 rows created.
scott@NIKUNJ> insert into test select * from tab;
5 rows created.
scott@NIKUNJ> insert into test select * from tab;
5 rows created.
scott@NIKUNJ> delete from tab;
delete from tab
*
ERROR at line 1:
ORA-01031: insufficient privileges
scott@NIKUNJ> delete from test;
15 rows deleted.
scott@NIKUNJ> commit;
Commit complete.
scott@NIKUNJ> select * from test as of timestamp SYSDATE;
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-5/24/60;
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-5/24/60;
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-10/24/60
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-11/24/60
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-2/24/60;
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-1/24/60;
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-5/24/60;
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-15/24/60
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-20/24/60
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-25/24/60
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-30/24/60
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BONUS TABLE
DEPT TABLE
EMP TABLE
SALGRADE TABLE
TEST TABLE
scott@NIKUNJ> select * from test as of timestamp sysdate-5/24/60;
no rows selected
scott@NIKUNJ> select * from test as of timestamp sysdate-5/24/60;
no rows selected.
Why ?
which timestamp i need to define if i realised after firing delete from test;
commit;
immediatly.
Regards,
September 30, 2005 - 10:04 am UTC
the data never existed in any committed form. It was "never there", it never actually existed.
Therefore, there is nothing to flash back to.
is flashback is dependent upon multi-versioning
reader, March 19, 2006 - 12:52 pm UTC
Hi Tom,
Is flashback is dependent upon multi-versioning.
I think it is [ Please correct me if I am wrong ] ..
As per my knowldge no other database DB2,Teradata,Informix,MS SQl Server,Sybase ... is supporting this as of now ...
So, they can not have this functionality ... right ?
March 19, 2006 - 2:16 pm UTC
flashback query
flashback table to SCN/TIME
flashback transaction
flashback row history
are all based on UNDO (multi-versioning)
flashback table to before drop (undrop a table) is not - it uses a recycle bin of dropped objects.
flashback database is not - it used redo and pre-checkpoint block images.
thanks for update
reader, March 19, 2006 - 8:43 pm UTC
Thanks for your response ..
Is there any other database supporting flashback ?
March 20, 2006 - 7:07 am UTC
not that I am personally aware of.
Flashback Versions Query return undesired result
Jay, July 12, 2006 - 4:07 pm UTC
I was testing Flashback Versions Query in 10gR2 and found it returns very old records besides those I specified in the VERSIONS range. For example on a table which we haven't changed any data for more than a month, flashback query with versions in the past 5 minutes would return all rows back. The following is just the first 10 rows.
1 select versions_startscn, versions_endscn,
2 versions_operation,
3 effort_id, created_dt, updated_dt
4 from effort versions between timestamp
5 systimestamp - interval '5' minute and systimestamp
6* where rownum < 11
SQL> /
VERSIONS_STARTSCN VERSIONS_ENDSCN V EFFORT_ID CREATED_DT UPDATED_DT
----------------- --------------- - ---------- -------------- --------------
201 20060607 15:20 20060607 15:20
202 20060607 15:20 20060607 15:20
203 20060607 15:20 20060607 15:20
204 20060607 15:20 20060607 15:20
205 20060607 15:20 20060607 15:20
206 20060607 15:20 20060607 15:20
207 20060607 15:20 20060607 15:20
208 20060607 15:20 20060607 15:20
209 20060607 15:20 20060607 15:20
210 20060607 15:20 20060607 15:20
10 rows selected.
You can see all their Versions_% peudo columns are null, which makes sense for records whose undo info is gone. I can easily work around it (specifying "where versions_startscn is not null") but this is quite annoying. My question is is this a known issue to Oracle or just I mis-understood something here?
Thanks
July 12, 2006 - 5:25 pm UTC
the behaviour does not seem to be documented - for this, we will have to file a tar and have them track down the expected behaviour (you have an "ok" workaround for such a short interval - the is null)
Flashback retention gaurantee in 10g
GS, November 27, 2006 - 9:49 pm UTC
Very userful thread I was trying to find out whether I can use flashback for my integration application and I found the information in the thread very useful.
But I have query on how gaurantee a retention period in 10g , is it a combination of setting the retention parameter, plus the space to undo tablespace using some algorithm?
How does it account for some mass updates on a odd day ?
Will it throw some error messages when the DB has run out of physical space or will it just start reusing the undo extents silently.
Does the maximum limit of 5 days still apply in 10g and if yes why is the maximum limit for undo_retention 2 raise to the power 32?
Flashback query is not seeing rows that were inserted and "quickly" deleted.
Andre, May 27, 2009 - 3:09 am UTC
Hi Tom
When inserting and quickly deleting a row, FBQ seems unable to see the changes.
Why is this? Is there any way to make the flashback query more reliable?
I have a test script taking a sleep time parameter:
DROP TABLE x;
CREATE TABLE x ( x VARCHAR2(22) );
INSERT INTO x VALUES ( 'aa' );
COMMIT;
host sleep &1
DELETE FROM x;
COMMIT;
host sleep &1
INSERT INTO x VALUES ( 'bb' );
COMMIT;
host sleep &1
SELECT TO_CHAR(versions_starttime,'YYYY/MM/DD HH24:MI:SS') AS start_tm,
versions_startscn AS scn,
versions_operation AS op,
x.*
FROM x versions BETWEEN TIMESTAMP MINVALUE AND MAXVALUE
ORDER BY versions_starttime;
With a sleep time of about 6 or more seconds or so I get expected output:
START_TM SCN O X
--------------------------------------------------------------------------- ---------- - ----------------------
2009/05/27 08:33:58 5046724723 D aa
2009/05/27 08:34:07 5046724793 I bb
aa
With a shorter sleep time it seems unable to pick up the deleted row:
START_TM SCN O X
--------------------------------------------------------------------------- ---------- - ----------------------
bb
> show parameter undo
NAME TYPE VALUE
------------------------------------ -------------------------------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
This was tested using version 10.2.0.1 and on 10.2.0.3.
Thanks
May 27, 2009 - 10:31 am UTC
don't use minvalue/maxvalue in this case - the time slots are too small - flashback query is 100% reliable - timestamps however are within +- 3 seconds. The min/maxvalue wouldn't be reliable in such a SMALL timeframe. Use a wider range of time - or use an SCN range (which is 100% precise)
using a pre-existing table:
ops$tkyte%ORA10GR2> desc t
Name Null? Type
------------------------------------ -------- -------------------------
DATA VARCHAR2(80)
ops$tkyte%ORA10GR2> set linesize 1000
ops$tkyte%ORA10GR2> delete from t;
0 rows deleted.
ops$tkyte%ORA10GR2> commit;
Commit complete.
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> column s new_val START
ops$tkyte%ORA10GR2> select dbms_flashback.get_system_change_number S from dual;
S
----------
84586136
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> begin
2 for i in 1 .. 10
3 loop
4 insert into t values ( 'inserted ' || i );
5 commit;
6 delete from t;
7 commit;
8 end loop;
9 end;
10 /
PL/SQL procedure successfully completed.
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> column s new_val STOP
ops$tkyte%ORA10GR2> select dbms_flashback.get_system_change_number S from dual;
S
----------
84586169
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> select data,
2 versions_operation,
3 versions_starttime,
4 versions_endtime from t versions between scn &START and &STOP
5 where data like 'inserted %'
6 order by versions_startscn nulls first
7 /
old 4: versions_endtime from t versions between scn &START and &STOP
new 4: versions_endtime from t versions between scn 84586136 and 84586169
DATA V VERSIONS_STARTTIME VERSIONS_ENDTIME
-------------------- - ------------------------------ ------------------------------
inserted 1 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 1 D 27-MAY-09 10.09.12 AM
inserted 2 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 2 D 27-MAY-09 10.09.12 AM
inserted 3 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 3 D 27-MAY-09 10.09.12 AM
inserted 4 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 4 D 27-MAY-09 10.09.12 AM
inserted 5 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 5 D 27-MAY-09 10.09.12 AM
inserted 6 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 6 D 27-MAY-09 10.09.12 AM
inserted 7 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 7 D 27-MAY-09 10.09.12 AM
inserted 8 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 8 D 27-MAY-09 10.09.12 AM
inserted 9 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 9 D 27-MAY-09 10.09.12 AM
inserted 10 I 27-MAY-09 10.09.12 AM 27-MAY-09 10.09.12 AM
inserted 10 D 27-MAY-09 10.09.12 AM
20 rows selected.
Using VERSIONS BETWEEN TIMESTAMP and AS OF TIMESTAMP in a query
Ravishankar, March 03, 2011 - 7:37 am UTC
Hi Tom,
Thanks for your patiency in clarifying our doubts.
We are facing performance issue when executing the below query built using flashback. Can you please help in finding a optimized solution to fine tune this flashback query. so that we can use this feature.
SELECT CREATE_DT, LISTING_KEY FROM DIRECTORY_LISTING
AS OF TIMESTAMP TO_TIMESTAMP ('02-03-11 00:00:01', 'DD-MM-YY HH24:MI:SS') WHERE LISTING_KEY IN
((SELECT LISTING_KEY from directory_listing
VERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP('27-02-11 00:00:01', 'DD-MM-YY HH24:MI:SS')
AND TO_TIMESTAMP('02-03-11 00:00:01', 'DD-MM-YY HH24:MI:SS')
WHERE LISTING_STATUS_CD = 'A' AND LAST_UPDATE_DT BETWEEN TO_DATE('27-02-11 00:00:01', 'DD-MM-YY HH24:MI:SS')
AND TO_DATE ('02-03-11 00:00:01', 'DD-MM-YY HH24:MI:SS')))
the query time is around 110 Seconds for this.
Flashback not enabled
A reader, July 24, 2012 - 10:42 pm UTC
If the flashback isn't enabled and the retention time for undo has aleady passed in case of procedure drop/change.
Is there a way to get back the changed/dropped procedure.
July 30, 2012 - 9:24 am UTC
restore a backup.
get it from an export.
undo_retention
Al, July 04, 2013 - 3:23 pm UTC
Hi Tom,
I think I've misunderstood the use of undo_retention for flashback as discussed above. On my 11.2.0.3 database undo_retention is set to 900 (the default) but I can query data from up to 5 days ago. What governs how far you can flashback?
Thanks
July 16, 2013 - 1:22 pm UTC
undo-retention is what we strive to keep. So you have it set to keep 900 seconds. If in 900 seconds you generate more undo then we have space for - we would try to autoextend the undo tablespace datafiles. If we cannot - then we let you know that we are prematurely expiring some undo and will overwrite it (we cannot hold 900 seconds worth, we tried but failed). You could set a guarantee on the undo retention in which case - we would hold the last 900 seconds - but would prevent other transactions from generating undo until some of the undo could be expired or we have more space.
On the other hand, if in 5 days you haven't generated enough undo to fill up the undo tablespace - we'll keep it all.
the 900 seconds should be considered a lower bound - it says "we will TRY to keep AT LEAST 900 seconds of undo, but if we have space - we'll keep lots more"
Will Flashback return the right records?
Tom, January 23, 2014 - 10:58 pm UTC
Hi Tom, hope life is going well for you :). I have spent the last couple of hours reading through all of the posts related to SCNs and Flashback Query and I appreciate the Ask Tom website for educating me on these subjects. Unfortunately it did not leave me completely comfortable that my requirement can be met without exposure to possible incorrect data retrieval from the Flashback Query supplied by Oracle (11.2.0.3).
The requirement appears to be simple and I would think that this would be a primary usage of the Flashback Query:
We have an applications table with typical child tables like contacts, addresses, … The applications go through a flow of status changes (initial, active, pending, complete,…) We will have all of the tables under flashback archive. Below is a script to demonstrate how we thought this would work:
Crete table put under flashback and add a record:
create table applications_fb
( id number
, status varchar2(25)
, status_timestamp timestamp(6)
, constraint applications_fb_pk
primary key
( id )
enable validate
);
Table created.
alter table applications_fb flashback archive fb_arch;
Table altered.
insert
into applications_fb
( id
, status
, status_timestamp
)
values( 1
, ‘Initial’
, systimestamp
);
commit;
1 row created.
Commit complete.
Show data from table and flashback table:
select * from applications_fb;
ID STATUS STATUS_TIMESTAMP
1 Initial 1/23/2014 3:59:39.987184 PM
select applications_fb.status
, applications_fb.status_timestamp
, versions_operation
, versions_startscn
, versions_starttime
, versions_endscn
, versions_endtime
from applications_fb
versions between scn minvalue and maxvalue
order
by versions_startscn;
STATUS STATUS_TIMESTAMP VERSIONS_OPERATION VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME
Initial 1/23/2014 3:59:39.987184 PM I 10602156766721 1/23/2014 3:59:38.000000000 PM
Create child table add data and show data from table and flashback:
create table application_contacts_fb
( application_id number
, contact_id number
, time_stamp timestamp(6)
, constraint application_contacts_fb_pk
primary key
( application_id
, contact_id
)
enable validate
);
Table created.
alter table application_contacts_fb flashback archive fb_arch;
Table altered.
insert
into application_contacts_fb
values( 1
, 102
, systimestamp
);
commit;
1 row created.
Commit complete.
select * from application_contacts_fb;
APPLICATION_ID CONTACT_ID TIME_STAMP
1 102 1/23/2014 4:07:12.638690 PM
select application_contacts_fb.application_id
, application_contacts_fb.contact_id
, versions_operation
, versions_startscn
, versions_starttime
, versions_endscn
, versions_endtime
from application_contacts_fb
versions between scn minvalue and maxvalue
order
by versions_startscn;
APPLICATION_ID CONTACT_ID VERSIONS_OPERATION VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME
1 102 I 10602156970347 1/23/2014 4:07:12 PM
Update status of application 1 to Active, wait 10 seconds and then update it to Pending.
update applications_fb
set status = 'Active'
, status_timestamp = systimestamp
where id = 1;
commit;
execute dbms_lock.sleep(10);
update applications_fb
set status = 'Pending'
, status_timestamp = systimestamp
where id = 1;
update application_contacts_fb
set contact_id = 3
, time_stamp = systimestamp
where application_id = 1;
commit;
1 row updated.
Commit complete.
PL/SQL procedure successfully completed.
1 row updated.
1 row updated.
Commit complete.
Show results:
select * from applications_fb;
ID STATUS STATUS_TIMESTAMP
1 Pending 1/23/2014 4:09:40.812000 PM
select applications_fb.status
, applications_fb.status_timestamp
, versions_operation
, versions_startscn
, versions_starttime
, versions_endscn
, versions_endtime
from applications_fb
versions between scn minvalue and maxvalue
order
by versions_startscn;
STATUS STATUS_TIMESTAMP VERSIONS_OPERATION VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME
Initial 1/23/2014 3:59:39.987184 PM I 10602156766721 1/23/2014 3:59:38.000000000 PM 10602157023623 1/23/2014 4:09:27.000000000 PM
Active 1/23/2014 4:09:30.165902 PM U 10602157023623 1/23/2014 4:09:27.000000000 PM 10602157023630 1/23/2014 4:09:39.000000000 PM
Pending 1/23/2014 4:09:40.812000 PM U 10602157023630 1/23/2014 4:09:39.000000000 PM
This is where the application will ask “What did my application table and all of the child table records look like at the time I saved the status as Pending”. The flashback query uses the timestamp from the applications table that was saved with the status “Pending”. As you can see the query brought back unexpected results. We got the Active record when using the Pending status timestamp and flashback. ??
select applications_fb.id as app_id
, applications_fb.status as app_status
, applications_fb.status_timestamp as app_ts
, application_contacts_fb.application_id as ac_app_id
, application_contacts_fb.contact_id as ac_contact_id
, application_contacts_fb.time_stamp as ac_time_stamp
, application_contacts_fb.*
from applications_fb as of timestamp to_timestamp('1/23/2014 4:09:40.812000 PM', 'mm/dd/yyyy HH:MI:SS:FF PM')
, application_contacts_fb as of timestamp to_timestamp('1/23/2014 4:09:40.812000 PM', 'mm/dd/yyyy HH:MI:SS:FF PM')
where application_contacts_fb.application_id = applications_fb.id;
APP_ID APP_STATUS APP_TS AC_APP_ID AC_CONTACT_ID AC_TIME_STAMP APPLICATION_ID CONTACT_ID TIME_STAMP
1 Active 1/23/2014 4:09:30.165902 PM 1 102 1/23/2014 4:07:12.638690 PM 1 102 1/23/2014 4:07:12.638690 PM
A second test:
update application_contacts_fb
set contact_id = 103
where application_id = 1;
commit;
1 row updated.
Commit complete.
select * from application_contacts_fb;
APPLICATION_ID CONTACT_ID TIME_STAMP
1 103 1/23/2014 4:09:40.831592 PM
update applications_fb
set status = 'Complete'
, status_timestamp = systimestamp
where id = 1;
commit;
select * from applications_fb;
ID STATUS STATUS_TIMESTAMP
1 Complete 1/23/2014 4:24:10.172672 PM
select applications_fb.id as app_id
, applications_fb.status as app_status
, applications_fb.status_timestamp as app_ts
, application_contacts_fb.application_id as ac_app_id
, application_contacts_fb.contact_id as ac_contact_id
, application_contacts_fb.time_stamp as ac_time_stamp
, application_contacts_fb.*
from applications_fb as of timestamp to_timestamp('1/23/2014 4:24:10.172672 PM', 'mm/dd/yyyy HH:MI:SS:FF PM')
, application_contacts_fb as of timestamp to_timestamp('1/23/2014 4:24:10.172672 PM', 'mm/dd/yyyy HH:MI:SS:FF PM')
where application_contacts_fb.application_id = applications_fb.id;
Updated the status to complete ran the Flashback query for the status complete timestamp from the applications table and got back the results that we expected.
APP_ID APP_STATUS APP_TS AC_APP_ID AC_CONTACT_ID AC_TIME_STAMP APPLICATION_ID CONTACT_ID TIME_STAMP
1 Complete 1/23/2014 4:24:10.172672 PM 1 103 1/23/2014 4:09:40.831592 PM 1 103 1/23/2014 4:09:40.831592 PM
Clearly I don’t understand how to utilize the flashback table to fulfill this requirement. My questions are:
1. How can I use flashback to ensure I get back the correct data records that were effective at the time of the application status/timestamp change?
2. Given the +/- 3 second delay is it possible that my query could bring back an incorrect child record that got saved during the 3 second time period? In other words could another SCN be closer to the status table timestamp due to the +/- 3 seconds for a change that may have occurred in one of the related child tables?
3. The oracle documentation “General Guidelines for Oracle Flashback Technology” says: To query past data at a precise time, use an SCN. If you use a timestamp, the actual time queried might be up to 3 seconds earlier than the time you specify. Oracle Database uses SCNs internally and maps them to timestamps at a granularity of 3 seconds. How can I use SCN if there is no documented way to grab and save the SCN that matches my status change commit transaction?
Greatly appreciate your help since we have a lot riding on this solution.
Sorry for the length of the post.
Cost of FB
Tom, January 30, 2014 - 4:47 pm UTC
I am trying to introduce Flashback to the whole enterprise but at this time we are only trying to use it for 1 application 1 schema. Yet since we have a clustered database Oracle wants us to pay almost a million dollars. Is there no way to specify the Flashback for one schema? Management will force me to write custom code before they pay this amount of money. We are on 11.2.0.3.0 and can not upgrade to 11.2.0.4.0 for the free Flashback since that release has many documented issues for our shareplex.
Any suggestions would be appreciated.
update
Tom, March 11, 2014 - 5:49 pm UTC
Looks like we may proceed with the 11.2.0.4.0 upgrade to the cluster and apply patches to the shareplex product.
what stats are used by optimizer in flashback query?
Chris Gould, July 01, 2015 - 2:48 pm UTC
When the optimizer builds an execution plan for a flashback query, what stats does it use? (Are there historical stats available, or does it use the current stats and assume the tables are roughly the same now as for the time when the query is executed)?
As of timestamp using between?
A reader, January 16, 2023 - 7:10 am UTC
Hi,
Was wondering that it is possible to use flashback query with "as of timestamp between tmpstmpval1 and tmpstmpval2?
Could not find it anywhere so I suppose it is not supported (tried it as well on our 19c DB and got an error as expected.
One approach I could think of was:
Select col from tab as of timestamp systimestamp-2/14
MINUS
Select col from tab as of timestamp systimestamp-1/14.
Your thoughts?
Thank you :o)
January 16, 2023 - 1:43 pm UTC
I'm guessing the syntax you're looking for is
select ... from ... versions between timestamp ts1 and ts2
Not "version" :)
A reader, January 17, 2023 - 6:42 am UTC
Hi Chris,
Thank you for the reply.
But not "version" as it will give what were the operations done on the table between a window.
I guess it is not possible for now.
Thanks for your help though :)
Cheers!
January 17, 2023 - 4:10 pm UTC
What exactly is it you want to see? Please provide an example.