1
Connor McDonald
2
Me
youtube bit.ly/youtube-connor
blog connor-mcdonald.com
twitter @connor_mc_d
400+ posts mainly on database & development
300+ technical videos, new uploads every week
rants and raves on tech and the world :-)
3
etc...
facebook bit.ly/facebook-connor
linkedin bit.ly/linkedin-connor
instagram bit.ly/instagram-connor
slideshare bit.ly/slideshare-connor
4 4https://asktom.oracle.com
Flashback - not just for DBAs
Connor McDonald
Database Advocate
8
modern IT methodologies
9
flashback
10
several different technologies
11
flashback query
flashback table
flashback drop
flashback database
flashback transaction
flashback data archive
12
flashback query
13
controversy
14
you have always
15
been using flashback query
16
revision
17
SQL> update EMP
2 set SAL = SAL * 1.10
3 /
14 rows updated.
SQL> rollback;
Rollback complete.
how ?
17
18
we remember stuff
19
SQL> update EMP
2 set SAL = SAL * 1.10
3 where ename = 'SMITH'
undo header
smith $1,0001
block 2754
jones $9002
brown $1,5003
wells $2,0004
wilson $1,0005
block 2754, row 1,
sal $1000
uba 5 5
$1,100
uba 5.1
20
SQL> rollback;
20
21
SQL> rollback;
undo header
smith $1,0001
block 2754
jones $9002
brown $1,5003
wells $2,0004
wilson $1,0005
block 2754, row 1,
sal $1000
uba 5
5
$1,100
uba 5.1
22
we can use this stuff for queries!
(Oracle version 4)
22
23
read consistency
23
24
select * from emp
where hiredate > '01/01/2004'
update emp set ename = 'SUE'
where ename = 'JOHN';
Block 3217
"I need block 3217…
… as it was at 9:00"
9:00
9:03
9:05
session 1 session 2
...and time = scn
25
system change number
26
Session 1
Request
Block 3217,
SCN 192
Block 3217,
SCN 234
"SUE"
Block 3217,
SCN 003,
change SUE => JOHN
undo segment block(s)
No good..too new
take a copy of the block
Locate
apply undo
Block 3217,
SCN 234
" SUE"
Block 3217,
SCN 234
" SUE"
Block 3217,
SCN 003
" JOHN"
Block 3217,
SCN 003
"JOHN"
Session 2
update emp
set ename = 'SUE'
where ename = 'JOHN'
commit;
Done !
27
stress: vast simplification
in-memory undo
throwaway undo
slots
expiry
wrap#
28
every query = locked at a SCN
29
go back further....
30
flashback query = choose the SCN
31
v9
2001
32
SQL> select * from DEPT;
DEPTNO DNAME LOC
---------- -------------- -------------
10 UNKNOWN NEW YORK
20 UNKNOWN DALLAS
30 UNKNOWN CHICAGO
40 UNKNOWN BOSTON
33
SQL> select * from DEPT AS OF SCN 995401;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
34
less geeky
35
SQL> select * from DEPT
2 AS OF TIMESTAMP systimestamp -
3 interval '20:00' minute to second;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
39
SQL> select TIMESTAMP_TO_SCN(systimestamp)
2 from DUAL;
TIMESTAMP_TO_SCN(SYSTIMESTAMP)
------------------------------
998332
SQL> select SCN_TO_TIMESTAMP(998314) from DUAL;
SCN_TO_TIMESTAMP(998314)
-----------------------------------------------
16-SEP-19 09.12.48.000000000 PM
42
use in "normal" queries
SQL> select e.empno, e.ename, d.dname
2 from emp e,
3 dept AS OF TIMESTAMP '16-SEP-19' d
3 where d.deptno = e.deptno;
EMPNO ENAME DNAME
---------- ---------- --------------
7782 CLARK "PREVIOUS NAME"
7839 KING "PREVIOUS NAME"
7934 MILLER "PREVIOUS NAME"
7566 JONES RESEARCH
7902 FORD RESEARCH
7876 ADAMS RESEARCH
7369 SMITH RESEARCH
7788 SCOTT RESEARCH
44
"What is in it for me?"
45
1) unit testing
before vs after
SQL> select case
2 when d1.deptno is null then 'DELETE'
3 when d2.deptno is null then 'INSERT'
4 end action,
5 d1.deptno, d2.deptno, d1.dname, d1.loc
6 from DEPT d1 full outer join
7 DEPT AS OF TIMESTAMP '16-SEP-19 11.51.02 PM' d2
8 on d1.deptno = d2.deptno;
ACTION DEPTNO DEPTNO DNAME LOC
------ ---------- ---------- -------------- ----------
10 10 ACCOUNTING NEW YORK
20 20 RESEARCH DALLAS
30 30 SALES CHICAGO
DELETE 40
INSERT 50 MARKETING PERTH
47
2) not just your data
48
SQL> drop procedure debug_msg;
Procedure dropped.
SQL> connect / as sysdba
Connected.
SQL> select text
2 from dba_source
3 as of timestamp systimestamp - interval '5' minute
4 where name='DEBUG_MSG' order by line;
TEXT
---------------------------------------------------------------------
procedure debug_msg(m varchar2) is
begin
dbms_output.put_line(m);
dbms_application_info.set_client_info(m);
end;
5 rows selected.
49
3) functionality diagnosis
50
SQL> select * from DEPT;
DEPTNO DNAME LOC
---------- -------------- -------------
10 UNKNOWN NEW YORK
SQL> select * from DEPT
2 as of TIMESTAMP SYSTIMESTAMP -
3 INTERVAL '20:00' MINUTE TO SECOND;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
1 change ?
10 changes ?
51
flashback row versions
SQL> SELECT deptno, dname
2 FROM dept
3 VERSIONS BETWEEN
4 TIMESTAMP SYSTIMESTAMP –
5 INTERVAL '20:00' MINUTE TO SECOND
6 AND SYSTIMESTAMP
7 WHERE deptno = 10;
DEPTNO DNAME
---------- --------------
10 ACCOUNTING
10 MONEY GRABBERS
10 FINANCE
10 BEAN COUNTERS
10 UNKNOWN
1 row
5 versions
53
versions_starttime
versions_startscn
versions_endtime
versions_endscn
versions_xid
versions_operation
SQL> SELECT deptno, dname,
2 VERSIONS_STARTTIME
3 ,VERSIONS_XID
4 ,VERSIONS_OPERATION
5 FROM dept
6 VERSIONS BETWEEN TIMESTAMP
7 SYSTIMESTAMP - INTERVAL '20:00' MINUTE TO SECOND
8 AND SYSTIMESTAMP
9 WHERE deptno = 10;
DEPTNO DNAME VERSIONS_STARTTIME VERSIONS_XID V
--------- -------------- ---------------------- ---------------- -
10 UNKNOWN 16-SEP-19 11.53.45 PM 0200100060040000 U
10 MONEY GRABBERS 16-SEP-19 11.53.36 PM 0600050065040000 U
10 FINANCE 16-SEP-19 11.53.24 PM 09000D001D050000 U
10 BEAN COUNTERS 16-SEP-19 11.53.12 PM 01001A00EA030000 U
10 ACCOUNTING
57
it might be expensive
58
grant flashback to ...
59
session level
60
dbms_flashback.enable_at_time(systimestamp-1/24);
select * from emp;
select * from dept;
etc etc
63
just how far ?
64
undo_retention
65
SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------ ----------- --------
undo_retention integer 900
~
66
SQL> desc v$undostat
Name Null? Type
----------------------------- -------- -----------
BEGIN_TIME DATE
END_TIME DATE
...
...
TUNED_UNDORETENTION NUMBER
CON_ID NUMBER
68
much much further
flashback data archive
71
flashback transaction
72
SQL> SELECT deptno, dname,
2 VERSIONS_STARTTIME
3 ,VERSIONS_XID
4 ,VERSIONS_OPERATION
5 FROM dept VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;
DEPTNO DNAME VERSIONS_STARTTIME VERSIONS_XID V
--------- --------- ----------------------- ---------------- -
50 UNKNOWN 16-SEP-19 11.08.15 PM 04000700EA030000 U
30 UNKNOWN 16-SEP-19 11.08.15 PM 04000700EA030000 U
20 NERDS 16-SEP-19 11.07.57 PM 090016001D050000 U
20 R&D 16-SEP-19 11.07.48 PM 05000B0074040000 U
...
73
XID ?
SQL> desc V$TRANSACTION
Name Null? Type
----------------------------- -------- -------
XIDUSN NUMBER
XIDSLOT NUMBER
XIDSQN NUMBER
...
75
SQL> select
2 XIDUSN, XIDSLOT, XIDSQN
3 from v$transaction
XIDUSN XIDSLOT XIDSQN
---------- ---------- ----------
1 31 674
SQL> select versions_xid from ...
VERSIONS_XID
-------------------
01 001F 00A202 0000
SQL> desc FLASHBACK_TRANSACTION_QUERY
Name Null? Type
----------------------- -------- --------------
XID RAW(8)
START_SCN NUMBER
START_TIMESTAMP DATE
COMMIT_SCN NUMBER
COMMIT_TIMESTAMP DATE
LOGON_USER VARCHAR2(30)
UNDO_CHANGE# NUMBER
OPERATION VARCHAR2(32)
TABLE_NAME VARCHAR2(256)
TABLE_OWNER VARCHAR2(32)
ROW_ID VARCHAR2(19)
UNDO_SQL VARCHAR2(4000)
SQL> update dept
2 set DNAME = 'FINANCE'
2 where deptno = 10;
SQL> commit;
SQL> select xid, undo_sql
2 from flashback_transaction_query
3 where xid = hextoraw('09000d001d050000');
XID UNDO_SQL
---------------- ------------------------------------
09000D001D050000 update "SCOTT"."DEPT"
set "DNAME" = 'BEAN COUNTERS'
where ROWID = 'AAAQ+hAAEAAAAAOAAA';
79
be careful
SQL> select text from dba_views
2 where view_name
3 = 'FLASHBACK_TRANSACTION_QUERY';
TEXT
------------------------------------------------
select xid, start_scn, start_timestamp,
decode(commit_scn,
0, commit_scn,
281474976710655, NULL, commit_scn)
commit_scn, commit_timestamp,
logon_user, undo_change#, operation,
table_name, table_owner,
row_id, undo_sql
from SYS.X$KTUQQRY
81
do not query without predicates ...
SQL> select xid, undo_sql
2 from flashback_transaction_query
3 where xid = hextoraw('09000d001d050000');
82
do not forget hextoraw
SQL> select xid, undo_sql
2 from flashback_transaction_query
3 where xid = hextoraw('09000d001d050000');
83
84
SQL> select xid, undo_sql
2 from flashback_transaction_query
3 where xid = hextoraw('09000d001d050000');
-----------------------------------------------------
| Id | Operation | Name |
-----------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | FIXED TABLE FIXED INDEX| X$KTUQQRY (ind:1) |
-----------------------------------------------------
85
SQL> select xid, undo_sql
2 from flashback_transaction_query
3 where xid = '09000d001d050000';
--------------------------------------
| Id | Operation | Name |
--------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | FIXED TABLE FULL| X$KTUQQRY |
--------------------------------------
86
column UNDO_SQL
87
rollback committed transaction
88
flashback transaction
89
"What is in it for me?"
90
1) accidents
91
three words
92
delete
uh-oh...
commit
9393
97
SQL> delete from DEPT where DEPTNO = 10;
1 row deleted.
SQL> commit;
Commit complete.
SQL> SELECT VERSIONS_XID
2 FROM dept
3 VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;
VERSIONS_XID
----------------
080017006C040000
98
SQL> BEGIN
2 DBMS_FLASHBACK.TRANSACTION_BACKOUT(
3 numtxns=> 1,
4 xids => sys.xid_array('080017006C040000')
5 );
6 END;
7 /
BEGIN
*
ERROR at line 1:
ORA-55510: Mining could not start
ORA-06512: at "SYS.DBMS_FLASHBACK", line 37
ORA-06512: at "SYS.DBMS_FLASHBACK", line 70
ORA-06512: at line 2
99
SQL> ALTER DATABASE ADD
2 SUPPLEMENTAL LOG DATA
3 (PRIMARY KEY) COLUMNS;
Database altered.
SQL> delete from DEPT where DEPTNO = 10;
1 row deleted.
SQL> commit;
Commit complete.
SQL> SELECT VERSIONS_XID
2 FROM dept
3 VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;
VERSIONS_XID
----------------
080017006C040000
SQL> BEGIN
2 DBMS_FLASHBACK.TRANSACTION_BACKOUT(
3 numtxns => 1,
4 xids => sys.xid_array('080017006C040000')
5 );
6 END;
7 /
SQL> select * from DEPT;
DEPTNO DNAME LOC
---------- -------------- ----------
20 RESEARCH DALLAS
30 SALES CHICAGO
50 MARKETING PERTH
40 HR US
102
KEEP CALM
AND
DON'T PANIC
103
SQL> SELECT COMPENSATING_XID
2 FROM DBA_FLASHBACK_TXN_STATE
3 WHERE xid = '080017006C040000';
COMPENSATING_XID
----------------
03001C0072040000
104
SQL> SELECT xid_report
2 FROM DBA_FLASHBACK_TXN_REPORT
3 WHERE compensating_xid = '03001C0072040000';
XID_REPORT
--------------------------------------------------------
<COMP_XID_REPORT XID="03001C0072040000">
<TRANSACTION XID="080017006C040000">
<UNDO_SQL>
<USQL exec="yes">
insert into "SCOTT"."DEPT"("DEPTNO","DNAME","LOC")
values ('10','ACCOUNTING','NEW YORK')
</USQL>
</UNDO_SQL>
</TRANSACTION>
<EXECUTED_UNDO_SQL>
<EXEC_USQL>
insert into "SCOTT"."DEPT"("DEPTNO","DNAME","LOC")
values ('10','ACCOUNTING','NEW YORK')
</EXEC_USQL>
</EXECUTED_UNDO_SQL>
</COMP_XID_REPORT>
105
SQL> commit;
Commit complete.
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- ----------
20 RESEARCH DALLAS
30 SALES CHICAGO
50 MARKETING PERTH
40 HR US
10 ACCOUNTING NEW YORK
106
2) unit tests
107
run test ... capture XID
108
commit... validate... undo transaction
109
flashback drop
110
delete
uh-oh...
commit
111
flashback transaction
112
three words
two
113
drop
uh-oh...
114
SQL> desc EMP
ERROR:
ORA-04043: object EMP does not exist
115
"undrop"
116
not cool enough
117
flashback table to before drop
118
SQL> desc USER_RECYCLEBIN
Name Null? Type
----------------------------- -------- ----------------
OBJECT_NAME NOT NULL VARCHAR2(30)
ORIGINAL_NAME VARCHAR2(32)
OPERATION VARCHAR2(9)
TYPE VARCHAR2(25)
TS_NAME VARCHAR2(30)
CREATETIME VARCHAR2(19)
DROPTIME VARCHAR2(19)
DROPSCN NUMBER
PARTITION_NAME VARCHAR2(32)
CAN_UNDROP VARCHAR2(3)
CAN_PURGE VARCHAR2(3)
RELATED NOT NULL NUMBER
BASE_OBJECT NOT NULL NUMBER
PURGE_OBJECT NOT NULL NUMBER
SPACE NUMBER
SQL> select OBJECT_NAME, ORIGINAL_NAME,
2 CAN_UNDROP, CAN_PURGE
3 from USER_RECYCLEBIN;
OBJECT_NAME ORIGINAL_NAME CAN CAN
-------------------------------- --------------- --- ---
BIN$CmYCdNcITL6hp9l266nskA==$0 PK_EMP NO YES
BIN$b/W75+c/Q/CeFMBIK7cXfw==$0 EMP YES YES
121
SQL> show RECYCLEBIN
123
SQL> flashback table EMP to before drop;
Flashback complete.
124
SQL> flashback table EMP to before drop
2 rename to OLD_EMP;
Flashback complete.
126
how long ?
127
128
SQL> PURGE RECYCLEBIN;
SQL> PURGE DBA_RECYCLEBIN;
SQL> PURGE TABLE emp;
SQL> PURGE TABLE "BIN$xyWe0+q+SniItJ0pn/u54A==$0";
SQL> PURGE TABLESPACE user1;
SQL> PURGE TABLESPACE user1 USER fred;
SQL> PURGE INDEX "BIN$FTX34MN88J7==$0";
129
no untruncate
130
flashback table
131
132
flashback table
133
SQL> FLASHBACK TABLE DEPT
2 TO TIMESTAMP TIMESTAMP '2019-09-16 12:05:00'
134
"undrop"
135
"What is in it for me?"
136
repeatable tests without cleanup scripts
137
test ... commit ... flashback to start point
138
deletes modified rows since SCN
inserts fresh rows as of SCN
... busy
142
single transaction
... multiple tables allowed
143
tables locked
144
constraints (FK, etc) must still be valid
147
most DDL is a time boundary
148
SQL> flashback table DEPT to scn ...;
ORA-01466: unable to read data - table definition has changed
152
flashback database
153
154
155
flashback database
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. |
AUTHORISED
DATABASE
ADMINSTRATORS
ONLY !
157
SQL> alter database flashback on;
Database altered.
158
data
changes
"new" blocks
to disk
changes
to disk
"old" blocks
to disk
redo fbdadbwr
159
SQL> FLASHBACK DATABASE TO '2:05PM'
160
SQL> create restore point OK_SO_FAR;
...
SQL> flashback database to
2 restore point OK_SO_FAR;
161
what does it cost ?
SQL> desc V$FLASHBACK_DATABASE_STAT
Name Null? Type
----------------------------- -------- ---------
BEGIN_TIME DATE
END_TIME DATE
FLASHBACK_DATA NUMBER
DB_DATA NUMBER
REDO_DATA NUMBER
ESTIMATED_FLASHBACK_SIZE NUMBER
166
a good compromise
167
guaranteed restore points
168
flashback logging starts as needed
169
"What is in it for me?"
170
1) safer deployment
171
scenario: "My New Application"
172
2) repeatable end to end testing
173
173
174
flashback pluggable database
175
3) production data for developers
176
"secret" flashback database
177
5:00am
11:30pm
standby recovery
convert to snapshot
revert to physical
182
flashback data archive
183
less flashback, more archive
185
SQL> CREATE FLASHBACK ARCHIVE longterm
2 TABLESPACE space_for_archive
3 RETENTION 1 YEAR;
Flashback archive created.
186
SQL> ALTER TABLE EMP FLASHBACK ARCHIVE LONGTERM;
Table altered.
[lots of DML on EMP]
187
187
SQL> select * from EMP;
--------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
--------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 518 |
| 1 | TABLE ACCESS FULL| EMP | 14 | 518 |
--------------------------------------------------
188
SQL> select * from EMP
2 AS OF TIMESTAMP SYSDATE-1/24;
--------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
--------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 518 |
| 1 | TABLE ACCESS FULL| EMP | 14 | 518 |
--------------------------------------------------
189
3 days later...
190
SQL> select * from EMP
2 AS OF TIMESTAMP SYSDATE-3;
-----------------------------------------------------------------
| Id | Operation | Name | Rows |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 446 |
| 1 | VIEW | | 446 |
| 2 | UNION-ALL | | |
|* 3 | FILTER | | |
| 4 | PARTITION RANGE ITERATOR| | 445 |
|* 5 | TABLE ACCESS FULL | SYS_FBA_HIST_69539 | 445 |
|* 6 | FILTER | | |
|* 7 | HASH JOIN OUTER | | 1 |
|* 8 | TABLE ACCESS FULL | EMP | 1 |
|* 9 | TABLE ACCESS FULL | SYS_FBA_TCRV_69539 | 14 |
------------------------------------------------------------------
191
SQL> select table_name
2 from user_tables
3 /
TABLE_NAME
---------------------------
SYS_FBA_HIST_71036
SYS_FBA_TCRV_71036
SYS_FBA_DDL_COLMAP_71036
EMP
192
SQL> select dbms_metadata.get_ddl(
2 'TABLE',
3 'SYS_FBA_TCRV_71036') from dual;
DDL
------------------------------------
CREATE TABLE "SCOTT"."SYS_FBA_TCRV_71036"
( "RID" VARCHAR2(4000),
"STARTSCN" NUMBER,
"ENDSCN" NUMBER,
"XID" RAW(8),
"OP" VARCHAR2(1)
)
SEGMENT CREATION IMMEDIATE
TABLESPACE "SPACE_FOR_ARCHIVE"
193
SQL> select dbms_metadata.get_ddl(
2 'TABLE',
3 'SYS_FBA_HIST_71036') from dual;
DDL
------------------------------------------
CREATE TABLE "SCOTT"."SYS_FBA_HIST_71036"
( "RID" VARCHAR2(4000),
"STARTSCN" NUMBER,
"ENDSCN" NUMBER,
"XID" RAW(8),
"OPERATION" VARCHAR2(1),
"EMPNO" NUMBER(4,0), "ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9), "MGR" NUMBER(4,0),
"HIREDATE" DATE, "SAL" NUMBER(7,2),
"COMM" NUMBER(7,2), "DEPTNO" NUMBER(2,0)
) COMPRESS FOR OLTP
TABLESPACE "SPACE_FOR_ARCHIVE"
PARTITION BY RANGE ("ENDSCN")
( PARTITION "HIGH_PART" VALUES LESS THAN (MAXVALUE) )
196
"What is in it for me?"
197
"I dont care what EMP looked like in June"
198198
why talk about it ?
199
SQL> select * from EMP AS OF "JUNE";
SQL> select * from EMP AS OF "MARCH";
SQL> select * from EMP AS OF "2pm Wednesday";
SQL> select * from EMP AS OF etc etc etc
200200
every historical version...
201201
... of every row
202202
sound familiar ?
203203
audit history
204204
we've all done it
205205
SQL> desc T
Name Null? Type
------------------------ -------- -------------
OWNER NOT NULL VARCHAR2(30)
OBJECT_NAME NOT NULL VARCHAR2(30)
SQL> desc T_AUDIT
Name Null? Type
------------------------ -------- --------------
AUDIT_DATE DATE
AUDIT_ACTION CHAR(1)
OWNER NOT NULL VARCHAR2(30)
OBJECT_NAME NOT NULL VARCHAR2(30)
206206
SQL> create or replace
2 trigger AUDIT_TRG
3 after insert or update or delete on T
4 for each row
5 declare
6 v_action varchar2(1) :=
7 case when updating then 'U'
8 when deleting then 'D' else 'I' end;
9 begin
10 if updating or inserting then
11 insert into T_AUDIT
12 values (sysdate
13 ,v_action
14 ,:new.owner
15 ,:new.object_name);
16 else
17 insert into T_AUDIT
18 values (sysdate
19 ,v_action
20 ,:old.owner
21 ,:old.object_name);
22 end if;
23 end;
209
a better, faster, robust version ...
210
flashback data archive
211
SQL> select empno, ename, job, sal, comm,
2 nvl(VERSIONS_STARTTIME,LAST_MOD) TS
3 ,nvl(VERSIONS_OPERATION,'I') op
4 from EMP
5 versions between timestamp
6 timestamp '2019-09-16 20:12:00' and systimestamp
7 order by empno, ts;
EMPNO ENAME JOB SAL COMM TS O
---------- ---------- --------- -------- ---------- ------------ -
7369 SMITH CLERK 806 08.10.51 PM I
7369 SMITH SALES 8060 1000 08.12.10 PM U
7499 ALLEN SALESMAN 1606 300000000 08.10.51 PM I
7521 WARD SALESMAN 1256 500000000 08.10.51 PM I
7566 JONES MANAGER 2981 08.10.51 PM I
...
7900 JAMES CLERK 956 08.10.51 PM I
7902 FORD ANALYST 3006 08.10.51 PM I
7934 MILLER CLERK 1306 08.10.51 PM I
7934 MILLER CLERK 1306 08.12.10 PM D
212
so why didn't we ?
217
218
separately licensed
232
flashback data archive is now …
232
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. | 233
234
not a typo
234
235
compression option
235
237
so think about FDA
237
238
secure
read only
239
efficient
fdba
243
dbms_flashback_archive.import_history
258
wrap up
259
flashback query
flashback table
flashback drop
flashback database
flashback transaction
flashback data archive
260
all cool for modern development
261
all included in EE
262
Thank you!
youtube bit.ly/youtube-connor
blog connor-mcdonald.com
twitter @connor_mc_d

Flashback ITOUG