1. 程式人生 > >Oracle學習(十三):閃回

Oracle學習(十三):閃回

any pool dsm pan 開啟 num ber 表示 tween

1.知識點:能夠對比以下的錄屏進行閱讀

SQL> --1. 錯誤地刪除了記錄
SQL> --2. 錯誤地刪除了表
SQL> --3. 查詢歷史記錄
SQL> --4. 怎樣撤銷一個已經提交的事務
SQL> 
SQL> --閃回的類型
SQL> --1. 閃回表:將表回退到過去的一個時間上
SQL> --2. 閃回刪除:Oracle回收站
SQL> --3. 閃回版本號查詢:全部歷史記錄
SQL> --4. 閃回事務查詢:通過select語句得到一個 undo_sql

SQL> --5. 閃回數據庫
SQL> --6. 閃回歸檔日誌
--------------------------------------------------------------------------
須要考慮的事情
FLASHBACK TABLE命令作為單一的事務運行,會得到一個單一的DML鎖
表的統計數據不會被閃回
當前的索引和從屬的對象會被維持
閃回表操作:1、系統表不能被閃回2、不能跨越DDL操作3、會被寫入警告日誌4、產生撤銷和重做的數據

--------------------------------------------------------------------------
語法:
FLASHBACK TABLE[achema.]<table_name>
TO
{[BEFORE DROP[RENAME TO table]]
[SCN|TIMESTAMP]expr
[ENABLE|DISABLE]TRIGGERS}
schema:模式名。一般為username
TO TIMESTAMP:系統郵戳,包括年月日時分秒
TO SCN:系統更改號
ENABLE TRIGGERS:表示觸發器恢復以後為enable狀態,而默覺得disable狀態
TO BEFORE DROP:表示恢復到刪除前
RENAME TO table:表示更換表名
--------------------------------------------------------------------------
--SCN:系統改變號(時間)
SQL> select to_char(systimestamp,‘yyyy-mm-dd hh24:mi:ss*ff‘) time,
  2         timestamp_to_scn(systimestamp) SCN
  3  from dual;

--scope的取值: momery  spfile  both
--momery:僅僅改當前內存(即數據庫),不改參數文件。重新啟動數據庫後恢復原樣
--spfile:僅僅改參數文件。不改數據庫;重新啟動數據庫後變為改動後的
--both:數據庫,參數都改

--授予閃回權限:grant flashback any table to scott;
--授予事務查詢權限:grant select any transaction to scott;

SQL> -- 1.閃回表:將表回退到過去的一個時間上
SQL> flashback table  flashback_table to scn 3784220;

SQL> --開啟表的行移動
SQL> alter table flashback_table enable row movement;

SQL> --2.閃回刪除
SQL> flashback table testseq to before drop;
SQL> --閃回重名的表
SQL> flashback table testseq to before drop rename to testseq_old;

SQL> --查看回收站,管理員沒有回收站
SQL> show recyclebin
SQL> --清空回收站
SQL> purge recyclebin;
SQL> --通過回收站的名字查看表要加雙引號
SQL> select * from "BIN$UhseqyX1Reyl5iurpupyEg==$0";

SQL> /*
SQL> 小結:
SQL> 基本概念: 1. SCN   2. 900秒  3. 權限 flashback any tables
SQL> 閃回表:將表回退到過去的一個時間
SQL>          1. 行移動
SQL>          2. 運行閃回表
SQL>         註意: 系統表不能閃回;不能跨越DDL
SQL>         問題: 怎樣得到離該操作近期的一個時間??
SQL> 閃回刪除: Oracle的回收站
SQL>         1. 運行閃回刪除
SQL>         2. 通過回收站中的名字閃回(雙引號)
SQL>         3. 重名的表
SQL>         4. 觸發器(disable)
SQL> */

SQL> --3.閃回版本號查詢
SQL> --運行閃回版本號查詢
SQL> select tid,tname,versions_operation 操作,versions_starttime 起始時間,
  2             versions_endtime 結束時間,versions_xid 事務號
  3  from versions_table
  4  versions between TIMESTAMP MINVALUE and MAXVALUE
  5  order by 1,4;

SQL> --4.閃回事務查詢
SQL> --視圖flashback_transaction_query
SQL> desc flashback_transaction_query

SQL> --得到XID
SQL> select tid,tname,versions_operation 操作,versions_starttime 起始時間,
  2             versions_endtime 結束時間,versions_xid 事務號
  3  from transaction_table
  4  versions between TIMESTAMP MINVALUE and MAXVALUE
  5  order by 事務號;

SQL> --通過XID查詢事務信息。再利用undo_sql撤銷事務操作
SQL> select operation,undo_sql
  2  from flashback_transaction_query
  3  where xid=‘080029005C050000‘;
2.在Sqlplus下實際運行的結果錄屏
SQL> host cls

SQL> /*
SQL> 1. 錯誤地刪除了記錄
SQL> 2. 錯誤地刪除了表
SQL> 3. 查詢歷史記錄
SQL> 4. 怎樣撤銷一個已經提交的事務
SQL> 
SQL> 閃回的類型
SQL> 1. 閃回表:將表回退到過去的一個時間上
SQL> 2. 閃回刪除:Oracle回收站
SQL> 3. 閃回版本號查詢:全部歷史記錄
SQL> 4. 閃回事務查詢: 通過select語句得到一個 undo_sql
SQL> 
SQL> 5. 閃回數據庫
SQL> 6. 閃回歸檔日誌
SQL> */
SQL> --SCN系統改變號(時間)
SQL> select to_char(systimestamp,‘yyyy-mm-dd hh24:mi:ss*ff‘) 時間,
  2         timestamp_to_scn(systimestamp) SCN
  3  from dual;

時間                                 SCN                                        
----------------------------- ----------                                        
2012-10-25 10:31:02*000000       3783972                                        

SQL> /*
SQL> SQL> show parameter undo
SQL> 
SQL> NAME                                 TYPE        VALUE
SQL> ------------------------------------ ----------- --------------------
SQL> undo_management                      string      AUTO
SQL> undo_retention                       integer     1200
SQL> undo_tablespace                      string      UNDOTBS1
SQL> SQL> --scope的取值: momery  spfile both
SQL> SQL> alter system set undo_retention=900 scope=both;
SQL> */
SQL> --權限  grant flashback any table to scott;
SQL> create table flashback_table
  2  (fid number,fname varchar2(20));

表已創建。

SQL> insert into flashback_table values(1,‘Tom‘);

已創建 1 行。

SQL> insert into flashback_table values(2,‘Mary‘);

已創建 1 行。

SQL> insert into flashback_table values(3,‘Mike‘);

已創建 1 行。

SQL> commit;

提交完畢。

SQL> --當前時間 SQL> select to_char(systimestamp,‘yyyy-mm-dd hh24:mi:ss*ff‘) 時間, 2 timestamp_to_scn(systimestamp) SCN 3 from dual; 時間 SCN ----------------------------- ---------- 2012-10-25 10:36:22*046000 3784220 SQL> select * from flashback_table; FID FNAME ---------- -------------------- 1 Tom 2 Mary 3 Mike SQL> --刪除mary SQL> delete from flashback_table where fid =2; 已刪除 1 行。

SQL> commit; 提交完畢。 SQL> select * from flashback_table; FID FNAME ---------- -------------------- 1 Tom 3 Mike SQL> --運行閃回表 SQL> flashback table flashback_table to scn 3784220; flashback table flashback_table to scn 3784220 * 第 1 行出現錯誤: ORA-08189: 由於未啟用行移動功能, 不能閃回表 SQL> --開啟表的行移動 SQL> alter table flashback_table enable row movement; 表已更改。 SQL> flashback table flashback_table to scn 3784220; 閃回完畢。 SQL> select * from flashback_table; FID FNAME ---------- -------------------- 1 Tom 2 Mary 3 Mike SQL> --問題:怎樣獲取近期的一個時間? SQL> host cls SQL> --閃回刪除 SQL> select * from tab; TNAME TABTYPE CLUSTERID ------------------------------ ------- ---------- DEPT TABLE EMP TABLE BONUS TABLE SALGRADE TABLE EMP20 TABLE TESTSAVEPOINT TABLE TEST2 TABLE MYPERSON TABLE EMP10 TABLE EMPINCOME TABLE VIEW1 VIEW TNAME TABTYPE CLUSTERID ------------------------------ ------- ---------- VIEW2 VIEW TESTSEQ TABLE HREMP SYNONYM MSG1 TABLE TEST1 TABLE PM_CI TABLE PM_STU TABLE FLASHBACK_TABLE TABLE SYS_TEMP_FBT TABLE 已選擇20行。 SQL> drop table test1; 表已刪除。 SQL> show recyclebin ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ ------------------- TEST1 BIN$Rn2qG7V+SO2k+aNrG/oYww==$0 TABLE 2012-10-25:10:45:11 SQL> purge recyclebin; 回收站已清空。 SQL> --管理員沒有回收站 SQL> select * from TESTSEQ; TID TNAME ---------- -------------------- 3 aaa 4 aaa 5 aaa 8 aaa SQL> drop table TESTSEQ; 表已刪除。 SQL> show recyclebin ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ ------------------- TESTSEQ BIN$UhseqyX1Reyl5iurpupyEg==$0 TABLE 2012-10-25:10:47:38 SQL> select * from TESTSEQ; select * from TESTSEQ * 第 1 行出現錯誤: ORA-00942: 表或視圖不存在 SQL> select * from tab; TNAME TABTYPE CLUSTERID ------------------------------ ------- ---------- DEPT TABLE EMP TABLE BONUS TABLE SALGRADE TABLE EMP20 TABLE TESTSAVEPOINT TABLE TEST2 TABLE MYPERSON TABLE EMP10 TABLE EMPINCOME TABLE VIEW1 VIEW TNAME TABTYPE CLUSTERID ------------------------------ ------- ---------- VIEW2 VIEW HREMP SYNONYM MSG1 TABLE BIN$UhseqyX1Reyl5iurpupyEg==$0 TABLE PM_CI TABLE PM_STU TABLE FLASHBACK_TABLE TABLE SYS_TEMP_FBT TABLE 已選擇19行。

SQL> select * from BIN$UhseqyX1Reyl5iurpupyEg==$0; select * from BIN$UhseqyX1Reyl5iurpupyEg==$0 * 第 1 行出現錯誤: ORA-00933: SQL 命令未正確結束 SQL> select * from "BIN$UhseqyX1Reyl5iurpupyEg==$0"; TID TNAME ---------- -------------------- 3 aaa 4 aaa 5 aaa 8 aaa SQL> host cls SQL> show recyclebin ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ ------------------- TESTSEQ BIN$UhseqyX1Reyl5iurpupyEg==$0 TABLE 2012-10-25:10:47:38 SQL> --運行閃回刪除 SQL> flashback table testseq to before drop; 閃回完畢。

SQL> show recyclebin SQL> select * from testseq; TID TNAME ---------- -------------------- 3 aaa 4 aaa 5 aaa 8 aaa SQL> host cls SQL> drop table testseq; 表已刪除。

SQL> create table testseq(tid number); 表已創建。

SQL> drop table testseq; 表已刪除。 SQL> show recyclebin ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ ------------------- TESTSEQ BIN$ZsXHtmHLTLu40DAC6jiKqg==$0 TABLE 2012-10-25:10:51:22 TESTSEQ BIN$hBllsvl5Tum9hHaSvtQhag==$0 TABLE 2012-10-25:10:51:01 SQL> flashback table testseq to before drop; 閃回完畢。 SQL> show recyclebin ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ ------------------- TESTSEQ BIN$hBllsvl5Tum9hHaSvtQhag==$0 TABLE 2012-10-25:10:51:01 SQL> select * from testseq; 未選定行 SQL> flashback table testseq to before drop; flashback table testseq to before drop * 第 1 行出現錯誤: ORA-38312: 原始名稱已被現有對象使用 SQL> --閃回重名的表 SQL> flashback table testseq to before drop rename to testseq_old; 閃回完畢。

SQL> select * from testseq_old; TID TNAME ---------- -------------------- 3 aaa 4 aaa 5 aaa 8 aaa SQL> host cls SQL> /* SQL> 小結: SQL> 基本概念: 1. SCN 2. 900秒 3. 權限 flashback any tables SQL> 閃回表:將表回退到過去的一個時間 SQL> 1. 行移動 SQL> 2. 運行閃回表 SQL> 註意: 系統表不能閃回;不能跨越DDL SQL> 問題: 怎樣得到離該操作近期的一個時間?? SQL> 閃回刪除: Oracle的回收站 SQL> 1. 運行閃回刪除 SQL> 2. 通過回收站中的名字閃回(雙引號) SQL> 3. 重名的表 SQL> 4. 觸發器(disable) SQL> */ SQL> host cls SQL> --閃回版本號查詢 SQL> create table versions_table 2 (tid number,tname varchar2(20)); 表已創建。

SQL> insert into versions_table values(1.‘Tom‘); insert into versions_table values(1.‘Tom‘) * 第 1 行出現錯誤: ORA-00917: 缺失逗號 SQL> insert into versions_table values(1,‘Tom‘); 已創建 1 行。 SQL> commit; 提交完畢。 SQL> insert into versions_table values(2,‘Mary‘); 已創建 1 行。 SQL> commit; 提交完畢。

SQL> insert into versions_table values(3,‘Mike‘); 已創建 1 行。

SQL> commit; 提交完畢。 SQL> update versions_table set tname=‘MaryNew‘ where tid=2; 已更新 1 行。 SQL> commit; 提交完畢。 SQL> select * from versions_table; TID TNAME ---------- -------------------- 1 Tom 2 MaryNew 3 Mike SQL> --怎樣查詢Mary? SQL> --運行閃回版本號查詢 SQL> select tid,tname 2 from versions_table 3 versions between TIMESTAMP MINVALUE and MAXVALUE 4 order by 1; TID TNAME ---------- -------------------- 1 Tom 2 MaryNew 2 Mary 3 Mike SQL> select tid,tname,versions_operation 操作,versions_starttime 起始時間, 2 versions_endtime 結束時間,versions_xid 事務號 3 from versions_table 4 versions between TIMESTAMP MINVALUE and MAXVALUE 5 order by 1,4; TID TNAME ---------- -------------------- - 起始時間 --------------------------------------------------------------------------- 結束時間 --------------------------------------------------------------------------- 事務號 ---------------- 1 Tom I 25-10月-12 11.17.28 上午 03002E005A050000 TID TNAME ---------- -------------------- - 起始時間 --------------------------------------------------------------------------- 結束時間 --------------------------------------------------------------------------- 事務號 ---------------- 2 Mary I 25-10月-12 11.17.37 上午 25-10月-12 11.18.16 上午 02000D0064050000 TID TNAME ---------- -------------------- - 起始時間 --------------------------------------------------------------------------- 結束時間 --------------------------------------------------------------------------- 事務號 ---------------- 2 MaryNew U 25-10月-12 11.18.16 上午 0600030065050000 TID TNAME ---------- -------------------- - 起始時間 --------------------------------------------------------------------------- 結束時間 --------------------------------------------------------------------------- 事務號 ---------------- 3 Mike I 25-10月-12 11.17.46 上午 0400130061050000 SQL> set linesize 150 SQL> col tid for 99 SQL> col tname for a10 SQL> col 操作 for a8 SQL> col 起始時間 for a40 SQL> col 結束時間 for a40 SQL> select tid,tname,versions_operation 操作,versions_starttime 起始時間, 2 versions_endtime 結束時間,versions_xid 事務號 3 from versions_table 4 versions between TIMESTAMP MINVALUE and MAXVALUE 5 order by 1,4; TID TNAME 操作 起始時間 結束時間 事務號 --- ---------- -------- ---------------------------------------- ---------------------------------------- ---------------- 1 Tom I 25-10月-12 11.17.28 上午 03002E005A050000 2 Mary I 25-10月-12 11.17.37 上午 25-10月-12 11.18.16 上午 02000D0064050000 2 MaryNew U 25-10月-12 11.18.16 上午 0600030065050000 3 Mike I 25-10月-12 11.17.46 上午 0400130061050000 SQL> col 起始時間 for a30 SQL> col 結束時間 for a30 SQL> col 操作 for a4 SQL> select tid,tname,versions_operation 操作,versions_starttime 起始時間, 2 versions_endtime 結束時間,versions_xid 事務號 3 from versions_table 4 versions between TIMESTAMP MINVALUE and MAXVALUE 5 order by 1,4; TID TNAME 操作 起始時間 結束時間 事務號 --- ---------- ---- ------------------------------ ------------------------------ ---------------- 1 Tom I 25-10月-12 11.17.28 上午 03002E005A050000 2 Mary I 25-10月-12 11.17.37 上午 25-10月-12 11.18.16 上午 02000D0064050000 2 MaryNew U 25-10月-12 11.18.16 上午 0600030065050000 3 Mike I 25-10月-12 11.17.46 上午 0400130061050000 SQL> host cls SQL> --閃回事務查詢 SQL> create table transaction_table 2 (tid number,tname varchar2(20)); 表已創建。 SQL> --第一個事務 SQL> insert into transaction_table values(1,‘Tom‘); 已創建 1 行。

SQL> insert into transaction_table values(2,‘Mary‘); 已創建 1 行。 SQL> insert into transaction_table values(3,‘Mike‘); 已創建 1 行。 SQL> commit; 提交完畢。 SQL> --第二個事務 SQL> update transaction_table set tname=‘MaryNew‘ where tid=2; 已更新 1 行。 SQL> delete from transaction_table where tid =3; 已刪除 1 行。

SQL> commit; 提交完畢。 SQL> --怎樣撤銷第二個事務?? SQL> --視圖flashback_transaction_query SQL> desc flashback_transaction_query 名稱 是否為空? 類型 ----------------------------------------------------------------------------------- -------- -------------------------------------------------------- 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> --得到XID SQL> select tid,tname,versions_operation 操作,versions_starttime 起始時間, 2 versions_endtime 結束時間,versions_xid 事務號 3 from transaction_table 4 versions between TIMESTAMP MINVALUE and MAXVALUE 5 order by 事務號; TID TNAME 操作 起始時間 結束時間 事務號 --- ---------- ---- ------------------------------ ------------------------------ ---------------- 3 Mike I 25-10月-12 11.29.38 上午 25-10月-12 11.30.23 上午 0100100060050000 2 Mary I 25-10月-12 11.29.38 上午 25-10月-12 11.30.23 上午 0100100060050000 1 Tom I 25-10月-12 11.29.38 上午 0100100060050000 2 MaryNew U 25-10月-12 11.30.23 上午 080029005C050000 3 Mike D 25-10月-12 11.30.23 上午 080029005C050000 SQL> select operation,undo_sql 2 from flashback_transaction_query 3 where xid=‘080029005C050000‘; OPERATION -------------------------------- UNDO_SQL ------------------------------------------------------------------------------------------------------------------------------------------------------ DELETE insert into "SCOTT"."TRANSACTION_TABLE"("TID","TNAME") values (‘3‘,‘Mike‘); UPDATE update "SCOTT"."TRANSACTION_TABLE" set "TNAME" = ‘Mary‘ where ROWID = ‘AAANpoAAEAAAAJvAAB‘; BEGIN SQL> insert into "SCOTT"."TRANSACTION_TABLE"("TID","TNAME") values (‘3‘,‘Mike‘) 2 ; 已創建 1 行。 SQL> update "SCOTT"."TRANSACTION_TABLE" set "TNAME" = ‘Mary‘ where ROWID = ‘AAANpoAAEAAAAJvAAB‘; 已更新 1 行。 SQL> commit; 提交完畢。

SQL> select * from transaction_table; TID TNAME --- ---------- 1 Tom 2 Mary 3 Mike SQL> spool off



Oracle學習(十三):閃回