分类: Oracle
2011-05-10 16:35:32
flashback table是一个对付drop table很好的手段。在一个表被drop的以后,这个表并没有真正的从表空间里drop掉,我们可以再recyclebin里找到。show recyclebin我们可以找到我们已经drop的表,并且通过flashback table xxx to before drop,我们可以恢复已经drop掉的表,这里虽然用的是flashback的命令,但是原理却和flashback有着非常大的差别。 flashback是用的flashback log作为恢复的基础,而flashback table却不是这样的。
先查看recyclebin的参数
SQL> show parameter recyclebin;
NAME TYPE VALUE
———————————— ———– ——————————
recyclebin string on
下面建立表test
SQL>conn crm/crm
SQL>create table test(id int);
然后drop test
SQL>drop table test;
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
—————- —————————— ———— ——————-
TEST BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0 TABLE 2010-04-12:09:43:14
在recyclebin里可以找到这个表。
这个recyclebin究竟是什么叻
这个table究竟还在不在呢。
test表已经不在了
SQL> select * from dba_tables where table_name=’TEST’;
OWNER TABLE_NAME TABLESPACE_NAME
已经没有了。
SQL> select * from dba_objects where object_name = ‘BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0′;
OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME TIMESTAMP STATUS TEMPORARY GENERATED SECONDARY
—————————— ——————————————————————————– —————————— ———- ————– ——————- ———– ————- ——————- ——- ——— ——— ———
CRM BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0
不过这个recyclebin里的还是存在的,并没有消失,
不过在table里是找不到了。
不过col还存在。
SQL> select OWNER,TABLE_NAME, COLUMN_NAME from dba_tab_cols where table_name = ‘BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0′;
OWNER TABLE_NAME COLUMN_NAME
—————————— —————————— ——————————
CRM BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0 ID
其col的定义也同样存在
这个对象对应的segment也存在。
SQL> select * from dba_segments where segment_name=’BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0′;
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE FREELISTS FREELIST_GROUPS RELATIVE_FNO BUFFER_POOL
—————————— ——————————————————————————– —————————— —————— —————————— ———– ———— ———- ———- ———- ————– ———– ———– ———– ———— ———- ————— ———— ———–
CRM BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0
通过这个可以看到,其实在一个table别drop掉以后,这里的对象并没有被删除掉,只是改了一个名字,从table的数据字典里去掉了,但是该 表对应的segment仍然存在。所以这里只是在drop的table上标识了一下。
下面我们把data block dump出来看看。
SQL>select header_file, header_block from dba_segments where segment_name=’BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0′;
HEADER_FILE HEADER_BLOCK
———– ————
6 11SQL> select gettracename from dual;
GETTRACENAME
——————————————————————————–
/u01/app/oracle/admin/soldb/udump/soldb1_ora_16514.trcSQL> alter system dump datafile 6 block 11;
发现这里的block和普通的table也没有什么区别
SQL> select OWNER,OBJECT_NAME,ORIGINAL_NAME from dba_recyclebin where original_name = ‘TEST’;
OWNER OBJECT_NAME ORIGINAL_NAME
—————————— —————————— ——————————–
CRM BIN$hAFEtZjSWsrgRAAMKZ5POQ==$0 TEST
确实这里drop的动作,只是在数据字典里做了一定的变化。
我们下面用10046来最终一下sql
先恢复表先
SQL> flashback table crm.test to before drop;
使用10046事件追踪sql
SQL> alter session set events ‘10046 trace name context forever,
level 1′;
使用tkprof查看trc文件
可以再其中找到
delete from obj$
where
obj# = :1
insert into RecycleBin$ (obj#, owner#, original_name, operation,
type#, droptime, dropscn, flags, related, bo, purgeobj, con#, ts#,
file#, block#, space)
values
(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15,
:16)
insert into obj$(owner#,name,namespace,obj#,type#,ctime,mtime,stime,status,
remoteowner,linkname,subname,dataobj#,flags,oid$,spare1,spare2)
values
(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16, :17)
当然里面还有一些比较复杂的动作。这里就不列举了,不过通过10046我们也可以大致了解到drop table的过程了。
这里需要注意的几点
drop table purge就会直接的drop。
system表空间里的table drop也是直接drop的。