--==============================================
-- Oracle 閃回特性 (FLASHBACK DROP & RECYCLEBIN)
--==============================================
?
??? FLASHBACK DROP 特性允許在不丟失任何數據庫的情況下將指定的表恢復至其被刪除的時間點,并保持數據庫為當前狀態。閃回刪除并不是
真正的刪除表,而是把該表重命名并放入回收站,類似于 Windows 的回收站一樣。當某個活動對象需要使用該表所占用的空間時,該表才會被真
正刪除。只要空間未被復用,該表即可恢復。本文主要講述了 FLASHBACK DROP 特性以及閃回特性中回收站 (RECYCLEBIN) 的管理。
?
一、 FLASHBACK DROP 的功能
??? 將先前刪除的表恢復到刪除之前的狀態
??? 恢復該表的索引以及觸發器,授權
??? 恢復該表的約束,包括唯一約束、主鍵約束、非空約束。外鍵約束不可恢復
??? 可以實現基于系統和基于會話的 flash drop 操作
??????? alter system set recyclebin = on | off ;
??????? alter session set recyclebin = on | off ;
???
??? drop table ( oracle 10g ) 命令并不真正刪除表 , 在內部被映射為 rename 命令 , 即是將其重命名之后放入回收站。 ???
?
二、理解表重名的過程
??? scott@ORCL > create table tb_emp as select * from emp ; ????? -- 基于 emp 表來創建表 tb_emp
?
??? scott@ORCL > alter table tb_emp add constraint empno_pk ???? -- 添加主鍵約束 , 將產生主鍵索引
??? ? 2 ? primary key ( empno );
??? ?
??? scott@ORCL > alter table tb_emp add constraint ename_uk ???? -- 添加唯一約束 , 將產生唯一索引
??? ? 2 ? unique ( ename );
??? ?
??? scott@ORCL > alter table tb_emp add constraint sal_ck check ( sal > 0 ); ???? -- 添加 check 約束
?
??? scott@ORCL > alter table tb_emp modify job constraint job_nn not null; ? -- 添加非空約束
?
??? scott@ORCL > alter table tb_emp add constraint dept_fk ????????????????? -- 添加外鍵約束
??? ? 2 ? foreign key ( deptno ) references dept ( deptno ) on delete cascade ;
?
??? scott@ORCL > select constraint_name , constraint_type ?????????? -- 查看 tb_emp 表上的所有約束
??? ? 2 ? from user_constraints where table_name = 'TB_EMP' ;
?
??? CONSTRAINT_NAME C
??? --------------- -
??? EMPNO_PK ??????? P
??? ENAME_UK ??????? U
??? SAL_CK ????????? C
??? JOB_NN ????????? C
??? DEPT_FK ???????? R ??????
???
??? -- 下面查看表 tb_emp 所在文件的 id, 塊的起始 id, 大小 , 以及該對象的對象 id 等
??? sys@ORCL > select file_id , block_id , bytes from dba_extents where segment_name = 'TB_EMP' ;
?
??? ?? FILE_ID ?? BLOCK_ID ????? BYTES
??? ---------- ---------- ----------
??????????? ? 4 ??????? 393 ????? 65536
??????????? ?
??? sys@ORCL > select object_name , object_id from dba_objects ? -- 查看表 tb_emp 的對象 ID
??? ? 2 ? where object_name = 'TB_EMP' ;
?
??? OBJECT_NAME ?????????? OBJECT_ID
??? -------------------- ----------
??? TB_EMP ??????????????????? 54493 ????
???
??? -- 對表進行重命名
??? scott@ORCL > alter table tb_emp rename to tb_employees ;
?
??? sys@ORCL > select file_id , block_id , bytes from dba_extents ? -- 重命名后所在文件的 id, 塊的起始 id, 大小沒有發生變化
??? ? 2 ? where segment_name = 'TB_EMPLOYEES' ;
?
??? ?? FILE_ID ?? BLOCK_ID ????? BYTES
??? ---------- ---------- ----------
??????????? ? 4 ??????? 393 ????? 65536
??????? ?
??? sys@ORCL > select object_name , object_id from dba_objects ? -- 重命名后對象 ID 沒有發生變化
??? ? 2 ? where object_name = 'TB_EMPLOYEES' ;
?
??? OBJECT_NAME ?????????? OBJECT_ID
??? -------------------- ----------
??? TB_EMPLOYEES ????????????? 54493
?
??? scott@ORCL > select index_name , index_type ????????????? -- 重命名后索引和約束也沒有發生變化
??? ? ? 2 ? from user_indexes where table_name = 'TB_EMPLOYEES'
??? ? 3 ? union all
??? ? 4 ? select constraint_name , constraint_type
??? ? 5 ? from user_constraints where table_name = 'TB_EMPLOYEES' ;
?
??? INDEX_NAME ???????????????????? INDEX_TYPE
??? ------------------------------ ---------------------------
??? EMPNO_PK ?????????????????????? NORMAL
??? ENAME_UK ?????????????????????? NORMAL
??? EMPNO_PK ?????????????????????? P
??? ENAME_UK ?????????????????????? U
??? SAL_CK ???????????????????????? C
??? JOB_NN ???????????????????????? C
??? DEPT_FK ???????? ??????????????? R
???
??? 從上面的演示可以看出對于表的重命名僅僅是修改了表名,而對于表對象的 ID ,以及表存放的位置,塊的起始,大小等并未發生實質
??? 性的變化。
???
三、刪除表并實施閃回
??? 1. 刪除表 tb_employees 并查看回收站的信息
??????? scott@ORCL > drop table tb_employees ;
?
??????? scott@ORCL > select object_name , original_name , can_undrop ,
??????? ? 2 ? base_object from user_recyclebin ;
?
??????? OBJECT_NAME ??????????????????? ORIGINAL_NAME ??????????????????? CAN BASE_OBJECT
??????? ------------------------------ -------------------------------- --- -----------
??????? BIN$k1zC3yEiwZvgQAB / AQBRVw == $0 TB_EMPLOYEES ???????????????????? YES 54493
??????? BIN$k1zC3yEhwZvgQAB / AQBRVw == $0 ENAME_UK ???????????????????????? NO ? 54493
??????? BIN$k1zC3yEgwZvgQAB / AQBRVw == $0 EMPNO_PK ???????????????????????? NO ? 54493
?
??????? scott@ORCL > select count ( 1 ) from "BIN$k1zC3yEiwZvgQAB/AQBRVw==$0" ; ? -- 可以使用回收站名來訪問對象,但要對對象加雙引號
?
??????? ? COUNT ( 1 )
??????? ----------
??????????????? 13
???
??? 2. 實施閃回并查看閃回后的情況
??????? scott@ORCL > flashback table tb_employees to before drop ; ?? -- 進行閃回
?
??????? Flashback complete .
?
??????? scott@ORCL > select count ( 1 ) from tb_employees ; ???????????? -- 閃回后表存在并且可以訪問
?
??????? ? COUNT ( 1 )
??????? ----------
??????????????? 13
?
??????? scott@ORCL > select index_name , index_type ?????????????????? -- 查看閃回后索引,約束的情況,發現其名稱仍然為 BIN$ 名稱
??????? ? 2 ? from user_indexes where table_name = 'TB_EMPLOYEES'
??????? ? 3 ? union all
??????? ? 4 ? select constraint_name , constraint_type
??????? ? 5 ? from user_constraints where table_name = 'TB_EMPLOYEES' ;
?
??????? INDEX_NAME ???????????????????? INDEX_TYPE
??????? ------------------------------ ---------------------------
??????? BIN$k1zC3yEgwZvgQAB / AQBRVw == $0 NORMAL
??????? BIN$k1zC3yEhwZvgQAB / AQBRVw == $0 NORMAL
??????? BIN$k1zC3yEcwZvgQAB / AQBRVw == $0 P
??????? BIN$k1zC3yEdwZvgQAB / AQBRVw == $0 U
??????? BIN$k1zC3yEewZvgQAB / AQBRVw == $0 C
??????? BIN$k1zC3yEfwZvgQAB / AQBRVw == $0 C ???????
???????
??????? 從上面的查詢可以看出閃回之后索引約束的名字還是使用了以 BIN 開頭,由系統生成的名字,可以將其改回,但外鍵約束已經不存在了。
???
??? 3. 嘗試對表 DML 操作
??????? scott@ORCL > insert into tb_employees ( empno , ename , job , sal , deptno )
??????? ? 2 ? select 9999 , 'Robinson' , 'DBA' , 3000 , 50 from dual ;
?
??????? 1 row created . ????? -- 可以成功插入, deptno 列的外鍵約束已經被刪除,故 deptno 為號成功插入
?
??????? scott@ORCL > alter index "BIN$k1zC3yEgwZvgQAB/AQBRVw==$0" rename to EMPNO_PK ;
?
??????? Index altered . ????? -- 將 BIN 開頭的索引改回原來的名字,其余的約束名修改在此省略
???????
??? 4. 下面演示表空間不足時無法閃回表刪除的問題 ?
??????? sys@ORCL > select tablespace_name , sum ( bytes / 1024 / 1024 ) || ' M'
??????? ? 2 ? from dba_free_space where tablespace_name = 'TBS1'
??????? ? 3 ? group by tablespace_name ; ???? -- 表空間 tbs1 的可用空間為 M
?
??????? TABLESPACE_NAME ??????????????? SUM ( BYTES / 1024 / 1024 )|| 'M'
??????? ------------------------------ ---------------------------------
??????? TBS1 ?????????????????????????? .9375 M ?
?
??????? flasher@ORCL > create table tb1 tablespace tbs1 as select * from dba_objects
??????? ? 2 ? where rownum < 6000 ;
?
??????? sys@ORCL > select tablespace_name , sum ( bytes / 1024 / 1024 ) || ' M'
??????? ? 2 ? from dba_free_space where tablespace_name = 'TBS1'
??????? ? 3 ? group by tablespace_name ; ? -- 在該表空間創建表 tb1 之后,可用空間為 .25M
?
??????? TABLESPACE_NAME ??????????????? SUM ( BYTES / 1024 / 1024 )|| 'M'
??????? ------------------------------ ---------------------------------
??????? TBS1 ?????????????????????????? .25 M
???????
??????? flasher@ORCL > drop table tb1 ; ?? -- 將表 tb1 刪除
?
??????? flasher@ORCL > show recyclebin ; ? -- 刪除后的對象位于回收站中
??????? ORIGINAL NAME ??? RECYCLEBIN NAME ??????????????? OBJECT TYPE ? DROP TIME
??????? ---------------- ------------------------------ ------------ -------------------
??????? TB1 ????????????? BIN$k2oZsEiaG7LgQAB / AQAZMA == $0 TABLE ??????? 2010 - 10 - 25 : 12 : 05 : 18 ???
?
??????? flasher@ORCL > select object_name , original_name , can_undrop ,
??????? ? 2 ? base_object from user_recyclebin ;
?
??????? OBJECT_NAME ??????????????????? ORIGINAL_N CAN BASE_OBJECT
??????? ------------------------------ ---------- --- -----------
??????? BIN$k2oZsEiaG7LgQAB / AQAZMA == $0 TB1 ??????? YES ?????? 54531
???????
??????? sys@ORCL > select tablespace_name , sum ( bytes / 1024 / 1024 ) || ' M'
??????? ? 2 ?? from dba_free_space where tablespace_name = 'TBS1'
??????? ? 3 ?? group by tablespace_name ; ?? -- 表空間 tbs1 顯示的可用空間已返還為 1M
??????????????????? ????????????????????? -- 但并不是真正為 M, 在需要表空間時 , 將自動清除回收站最老的對象 , 以滿足當前空間需求
??????? TABLESPACE_NAME ??????????????? SUM ( BYTES / 1024 / 1024 )|| 'M'
??????? ------------------------------ -------------------------------
??????? TBS1 ?????????????????????????? .9375 M
???????
??????? sys@ORCL > select tablespace_name , autoextensible ?? -- 這個查詢可以看出表空間 tbs1 不能自動擴展
??????? ? 2 ? from dba_data_files where tablespace_name = 'TBS1' ;
?
??????? TABLESPACE_NAME AUT
??????? --------------- ---
??????? TBS1 ??????????? NO
?
??????? flasher@ORCL > create table tb2 tablespace tbs1 as select * from dba_objects ? -- 再次在表空間創建新表 tb2
??????? ? 2 ? where rownum < 6000 ; ??
?
??????? flasher@ORCL > show recyclebin ; ? -- 此時回收站中原來的表 tb1 記錄被自動清除
???????
??????? flasher@ORCL > select object_name , original_name , can_undrop ,
??????? ? 2 ? base_object from user_recyclebin ;
?
??????? no rows selected
?
??????? flasher@ORCL > flashback table tb1 to before drop ; ? -- 此時表 tb1 不能被閃回
??????? flashback table tb1 to before drop
??????? *
??????? ERROR at line 1 :
??????? ORA - 38305 : object not in RECYCLE BIN
???????
四、回收站的管理
??? 每個用戶都擁有自己的回收站,且可以查看在自己模式中刪除的表
??? 使用 purge 命令可以永久刪除對象,回收空間
??? purge 命令的幾種常用形式
??????? drop table tbname purge ??? -- 直接刪除表,而不置于回收站
??????? purge table tbname ???????? -- 清除回收站中的 tbname 表
??????? purge index idx_name ?????? -- 清除回收站中的索引 idx_name
??????? purge tablespace tablespace_name ?? -- 清除該表空間中所有已刪除的對象
??????? purge tablespace tablespace_name user user_name ? -- 清除表空間中指定用戶刪除的對象
??????? purge user_recyclebin ????? -- 清除指定用戶已刪除的所有對象
??????? purge dba_recyclebin ?????? -- 清除所有已刪除的對象
?
五、總結
??? 通過對上述表的刪除及空間分配情況,總結如下:
??? 1. 表的刪除被映射為將表的重命名,然后將其置于回收站
??? 2. 表的索引 , 觸發器 , 授權閃回后將不受到影響 . 索引 , 觸發器名字可以根據需要進行更改回原來名稱
??? 3. 對于約束,如果是外鍵約束,表刪除之后將不可恢復,其余的約束不受影響
??? 4. 如果要查詢回收站中的對象,建議將對象名使用雙引號括起來
??? 5. 閃回的實質并不能撤銷已提交的事務,而是構造倒退原有事務影響的另一個事務
??? 6. 對于已經刪除的表如果在所在的表空間新增對象由于空間不足的壓力而被重用將導致閃回失敗
??? 7. 對于表空間不足時,系統會自動清除回收站中最老的對象,以滿足當前需求,即采用 FIFO 原則
??? 8. 閃回表的常用方法
??????? flashback table tbname to before drop ;
??????? flashback table tbname to before drop rename to newtbname;
??????? 第二條語句用于被刪除的表名已經被再次重用 , 故閃回之前必須將其改名為新表名 ,schema 不變化
??? 9. 如回收站中存在兩個相同的原表名,則閃回時總是閃回最近的版本,如果閃回特定的表,需要指定
??????? 該表在回收站中的名稱。如
??????? flashback table "BIN$k1zC3yEiwZvgQAB/AQBRVw==$0" to before drop;
??? 10.flashback drop 不能閃回 truncate 命令截斷的表,而是只能恢復 drop 之后的表
??? 11.flashback drop 不能閃回 drop user scott cascade 刪除方案的操作 , 此只能用 flashback database
??? 12. 在 system 表空間中存儲的表無法啟用 flashback drop ,且這些表會被立即刪除
?
??? 與回收站相關兩個重要的視圖
??????? dba_recyclebin
??????? user_recyclebin ????
?
六、 更多參考 ???
有關基于用戶管理的備份和備份恢復的概念請參考:
??????? Oracle 冷備份
??????? Oracle 熱備份
??????? Oracle 備份恢復概念
??????? Oracle 實例恢復
??????? Oracle 基于用戶管理恢復的處理 ( 詳細描述了介質恢復及其處理 )
???????
??? 有關 RMAN 的恢復與管理請參考:
??????? RMAN 概述及其體系結 構
??????? RMAN 配置、監控與管理
??????? RMAN 備份詳解
??????? RMAN 還原與恢復
???????
??? 有關 Oracle 體系結構請參考:
??????? Oracle 實例和Oracle 數據庫(Oracle 體系結構)
??????? Oracle 表空間與數據文件
??????? Oracle 密碼文件
??????? Oracle 參數文件
??????? Oracle 聯機重做日志文件(ONLINE LOG FILE)
??????? Oracle 控制文件(CONTROLFILE)
??????? Oracle 歸檔日志
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
