truncate table test1;
alter table test1 move tablespace tp2;
select object_id,data_object_id from dba_objects where object_name='TEST1';
OBJECT_ID DATA_OBJECT_ID
---------- --------------
22959 23144
truncate和移动到不同表空间时DATA_OBJECT_ID会变化。
但是当表内无数据时,truncate不会导致DATA_OBJECT_ID会加一。
I. 从数据字典dba_segments找到 段头,
段头:在段头读取两样信息:高高水点、Extent Map(区地图)(Auxillary Map)
II. 根据段头中的Auxillary Map,依次读每个区的数据。无序,可以多块读
未打开闪回时没有不同。
TRUNCATE和DROP-打开闪回时,具体做了哪些操作???
DROP-打开闪回时:改数据字典表中相应字段tab$,seg$,ext$,col$,将表系统命名bin$开头的,空间并未释放。打开闪回时此时查询可用区的方法是全部扫描位图区。附带会有删除索引约束触发器等,也可能会慢。
此时,可以查询到闪回DROP之前的数据。
TRUNCATE :修改表所有区对应的二进制位--位图区变为1变为0
使用游标,exec open :x时先进行解析,print :x时提取数据
BYS@ bys3>var x refcursor
BYS@ bys3>exec open :x for select count(*) from test6;
PL/SQL procedure successfully completed.
BYS@ bys3>print :x
COUNT(*)
----------
2
BYS@ bys3>exec open :x for select count(*) from test6;
PL/SQL procedure successfully completed.
此时在会话2执行BYS@ bys3>drop table test6;
在会话1查看游标
BYS@ bys3>print :x
COUNT(*)
----------
2
因为开启回收站时,DROP 表只是将表改名-修改数据字典表tab$,seg$,ext$,在数据文件中并未改变数据块头OBJ的、标记,所以可以查到
#######
会话2把表闪回DROP
BYS@ bys3>flashback table test6 to before drop;
Flashback complete.
会话一:执行游标:
BYS@ bys3>exec open :x for select count(*) from test6;
PL/SQL procedure successfully completed.
会话二:
BYS@ bys3>truncate table test6;
Table truncated.
会话一:查询游标
BYS@ bys3>print :x
ERROR:
ORA-08103: object no longer exists
no rows selected
报错是因为:TRUNCATE删除数据,修改数据字典表,同时将数据块头的OBJ清除,所以查询时报对象不存在。