1、閃回技術都包含哪些技術
- flashback query
- flashback data archive
- flashback transaction query
- flashback transaction
- flashback table
- flashback drop
- flashback database
2、flashback query【主要是利用undo查詢一段時間以前的數據】
- 閃回時間點查詢
select * from test as of timestamp to_timestamp('','') where object_id=100;
- 閃回版本查詢
3、flashback data archive【將原本只能保存在undo中的撤銷數據保存在普通表空間中,這樣可以查詢表很長時間以前的舊數據】
- 如何對表創建flashback data archive。
SQL> create flashback archive default fda_default tablespace fda retention 1 year; Flashback archive created. SQL> grant flashback archive on fda_default to dayu; Grant succeeded. SQL> alter table dayu.fda_test flashback archive; Table altered. SQL> select count(*) from dayu.fda_test as of timestamp (systimestamp -interval '7' month); select count(*) from dayu.fda_test as of timestamp (systimestamp -interval '7' month) * ERROR at line 1: ORA-08180: no snapshot found based on specified time SQL> select count(*) from dayu.fda_test as of timestamp (systimestamp -interval '1' day); select count(*) from dayu.fda_test as of timestamp (systimestamp -interval '1' day) * ERROR at line 1: ORA-01466: unable to read data - table definition has changed
- 在fda中,創建的flashback data archive是如何存儲的?
SEGMENT_NAME SEGMENT_TYPE --------------------------------------------------------------------------------- ------------------ FDA_TEST TABLE SYS_FBA_DDL_COLMAP_73240 TABLE SYS_FBA_TCRV_73240 TABLE SYS_FBA_HIST_73240 TABLE PARTITION --這個表存放的就是fda_test的歷史數據
SYS_FBA_TCRV_IDX_73240 INDEX
- 開起來flashback data archive的表如果有不被允許的ddl會怎么樣?
SQL> alter table dayu.fda_test shrink space; alter table dayu.fda_test shrink space * ERROR at line 1: ORA-55610: Invalid DDL statement on history-tracked table
- 哪些ddl可以在開啟歷史表的的表上操作?
1、對字段的add、drop、rename、modify修改 2、對約束的add、drop、rename修改 3、對分區的drop、truncate操作 4、對表的truncate和rename操作
4、flashback transaction query【需要開啟最小補充日志;查詢返回的結果是將當前數據修改為以前數據的撤銷sql】
5、flashback transaction【撤銷已經執行的事務】
- 查詢過去一段時間表上的事務
select distinct xid,commit_scn from flashback_transaction_query where table_name='TEST' and table_owner='DAYU' and commit_timestamp > systimestamp - interval '10' minute order by commit_scn; --沒有結果呢怎么?
以下為測試過程:
SQL> alter database add supplemental log data; --這個比較關鍵 Database altered. SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database; SUPPLEMENTAL_LOG_DATA_MI ------------------------ YES SQL> create user test identified by test; User created. SQL> grant connect, resource to test; Grant succeeded. SQL> create table test.emp as select * from scott.emp where 1=0; Table created. SQL> select * from test.emp; no rows selected SQL> desc test.emp; Name Null? Type ----------------------------------------- -------- ---------------------------- EMPNO NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) SQL> insert into test.emp values (10,'AAA','STF', null,sysdate-10000,1000,100,'10'); 1 row created. SQL> insert into test.emp values (20,'BBB','STF', 10,sysdate-10000,500,100,'10'); 1 row created. SQL> commit; Commit complete. SQL> select * from test.emp; EMPNO ENAME JOB MGR ---------- ------------------------------ --------------------------- ---------- HIREDATE SAL COMM DEPTNO ------------------ ---------- ---------- ---------- 10 AAA STF 13-APR-92 1000 100 10 20 BBB STF 10 13-APR-92 500 100 10 SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1138207 SQL> insert into test.emp values (30,'CCC','STF', 10,sysdate-10000,500,100,'10'); 1 row created. SQL> insert into test.emp values (40,'DDD','MANG', null,sysdate-10000,5000,1000,'10'); 1 row created. SQL> insert into test.emp values (50,'EEE','STF', 10,sysdate-10000,500,100,'10'); 1 row created. SQL> insert into test.emp values (60,'FFF','STF', null,sysdate-20000,5000,100,'10'); 1 row created. SQL> commit; Commit complete. SQL> update test.emp set comm=1000 where empno=50; 1 row updated. SQL> commit; Commit complete. SQL> update test.emp set comm=1000 where empno=60; 1 row updated. SQL> commit; Commit complete. SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1138277 SQL> create table changed_tables (table_name varchar2(256), xid raw(8), scn number); Table created. SQL> CREATE OR REPLACE PROCEDURE extract_txn_ids (lcrscn IN NUMBER, escn in number) AS lname VARCHAR2(256); vsql varchar2(2000); BEGIN dbms_logmnr.start_logmnr(startscn => lcrscn, endscn => escn, OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG+DBMS_LOGMNR.CONTINUOUS_MINE); insert into changed_tables select distinct seg_name,xid,scn from v$logmnr_contents where seg_owner = 'TEST' and scn >= lcrscn and scn<= escn; commit; END; / 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Procedure created. SQL> exec extract_txn_ids(1138207,1138277); PL/SQL procedure successfully completed. SQL> select * from changed_tables; SQL> col TABLE_NAME for a40 SQL> / TABLE_NAME XID SCN ---------------------------------------- ---------------- ---------- EMP 04001E0004030000 1138211 EMP 07001F00EB020000 1138273 EMP 04001E0004030000 1138214 EMP 04001E0004030000 1138210 EMP 050003006A040000 1138264 EMP 04001E0004030000 1138216 6 rows selected. SQL> create or replace procedure txn_backout(sscn in number) as txn_array sys.xid_array := sys.xid_array(); i number; begin i := 1; --initialize xid_array from changed_tables for txn in (select distinct xid from changed_tables) loop txn_array.extend; txn_array(i) := txn.xid; i := i + 1; end loop; i := i - 1; -- 3 input variables are passed to transaction_backout -- i number of txns -- txn_array array of txn ids -- sscn starting point to logminer dbms_flashback.transaction_backout ( numtxns => i, xids => txn_array, options => dbms_flashback.cascade, scnhint => sscn ); --issue commit as dbms_flashback.transaction_backout does not include commit and ----txn backout. commit; END; / 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Procedure created. SQL> exec txn_backout(sscn =>1138207); BEGIN txn_backout(sscn =>1138207); END; * 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 "SYS.TXN_BACKOUT", line 19 ORA-06512: at line 1 SQL> exec dbms_logmnr.end_logmnr; --這里測試過程中並沒有開啟logmnr,哪里打開的? PL/SQL procedure successfully completed. SQL> exec txn_backout(sscn =>1138207); PL/SQL procedure successfully completed.
6、flashback table【利用undo將表恢復到以前的狀態】
- 模擬測試
SQL> update scn_test set object_name='DY' where rownum < 20000; 19999 rows updated. SQL> commit; Commit complete. SQL> flashback table scn_test to timestamp (systimestamp -interval '10' miniute); flashback table scn_test to timestamp (systimestamp -interval '10' miniute) * ERROR at line 1: ORA-30089: missing or invalid <datetime field> SQL> flashback table scn_test to timestamp (systimestamp -interval '10' minute); flashback table scn_test to timestamp (systimestamp -interval '10' minute) * ERROR at line 1: ORA-08189: cannot flashback the table because row movement is not enabled SQL> alter table scn_test enable row movement; Table altered. SQL> flashback table scn_test to timestamp (systimestamp -interval '10' minute); Flashback complete. SQL> select object_name from scn_test where rownum< 10; OBJECT_NAME ------------------------------ V$RSRC_CONS_GROUP_HISTORY V_$RSRC_PLAN_HISTORY V$RSRC_PLAN_HISTORY V_$BLOCKING_QUIESCE V$BLOCKING_QUIESCE V_$PX_BUFFER_ADVICE V_$FLASHBACK_DATABASE_LOG V$FLASHBACK_DATABASE_LOG V_$FLASHBACK_DATABASE_STAT 9 rows selected.
- 開啟flashback table的幾個條件
- 對表開啟row movement
- undo要設置的合適
- 另外sys用戶的表是無法做flashback的。
7、flashback drop【從回收站中將表恢復】
8、flashback database【測試時必須要開啟閃回日志】
SQL> archive log list; Database log mode Archive Mode Automatic archival Enabled Archive destination USE_DB_RECOVERY_FILE_DEST Oldest online log sequence 47 Next log sequence to archive 49 Current log sequence 49 SQL> SQL> SQL> show parameter db_recovery_file_dest_size NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_recovery_file_dest_size big integer 4977M SQL> SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; Session altered. SQL> select oldest_flashback_scn,oldest_flashback_time from v$flashback_database_log; OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI -------------------- ------------------- 730972 2019-08-26 17:08:16 SQL> create table flash1 as select * from dba_objects; Table created. SQL> create table flash2 as select * from flash1; Table created. SQL> create table flash3 as select * from flash1; Table created. SQL> select sysdate from dual; SYSDATE ------------------- 2019-08-26 17:10:48 SQL> truncate table flash2; Table truncated. SQL> drop table flash3; Table dropped. SQL> shutdown immediate Database closed. Database dismounted. ORACLE instance shut down. SQL> startup mount exclusive; ORACLE instance started. Total System Global Area 592957440 bytes Fixed Size 2215544 bytes Variable Size 230687112 bytes Database Buffers 356515840 bytes Redo Buffers 3538944 bytes Database mounted. SQL> flashback database to timestamp(to_date('2019-08-26 17:10:48','yyyy-mm-dd hh24:mi:ss')); Flashback complete. SQL> alter database open resetlogs; Database altered.
在此過程中,主要使用了flashback log
-rw-r----- 1 oracle oinstall 8200192 8月 26 17:22 o1_mf_gp78d05s_.flb
[ocm1:oracle]:/oracle/app/oracle/flash_recovery_area/OCM1/flashback>pwd
/oracle/app/oracle/flash_recovery_area/OCM1/flashback
[ocm1:oracle]:/oracle/app/oracle/flash_recovery_area/OCM1/flashback>ls
o1_mf_gp78d05s_.flb
[ocm1:oracle]:/oracle/app/oracle/flash_recovery_area/OCM1/flashback>