全部博文(323)
分类: Oracle
2008-06-18 16:41:21
SQL> create table my_objects tablespace HWM 2 as select * from all_objects; SQL> delete from my_objects where rownum<10000; 9999 rows deleted SQL> select count(*) from my_objects; COUNT(*) ---------- 21015 SQL> exec show_space(p_segname => 'MY_OBJECTS',p_owner => 'DLINGER',p_type => 'TABLE'); Total Blocks............................425 Total Bytes.............................3481600 Unused Blocks...........................3 Unused Bytes............................24576 Last Used Ext FileId....................11 Last Used Ext BlockId...................1294 Last Used Block.........................2 |
这里HWM=425 - 3 + 1 = 423
然后对table MY_OBJECTS进行move操作:
SQL> alter table MY_OBJECTS move; 表已更改。 SQL> exec show_space(p_segname => 'MY_OBJECTS',p_owner => 'DLINGER',p_type => 'TABLE'); Total Blocks............................290 Total Bytes.............................2375680 Unused Blocks...........................1 Unused Bytes............................8192 Last Used Ext FileId....................11 Last Used Ext BlockId...................1584 Last Used Block.........................4 |
我们可以看到,table MY_OBJECTS的HWM从423移动到290,table的HWM降低了!(show_space是自定义的一个过程)。
Move的一些用法:
以下是alter table 中move子句的完整语法,我们介绍其中的几点:
MOVE [ONLINE] [segment_attributes_clause] [data_segment_compression] [index_org_table_clause] [ { LOB_storage_clause | varray_col_properties } [ { LOB_storage_clause | varray_col_properties } ]... ] [parallel_clause]
a. 我们可以使用move将一个table从当前的tablespace上移动到另一个tablespace上,如:
alter table t move tablespace tablespace_name;
b. 我们还可以用move来改变table已有的block的存储参数,如:
alter table t move storage (initial 30k next 50k);
c.另外,move操作也可以用来解决table中的行迁移的问题。
使用move的一些注意事项:
a. table上的index需要rebuild:
在前面我们讨论过,move操作后,数据的rowid发生了改变,我们知道,index是通过rowid来fetch数据行的,所以,table上的index是必须要rebuild的。
SQL> create index i_my_objects on my_objects (object_id); Index created
SQL> alter table my_objects move; Table altered
SQL> select index_name,status from user_indexes where index_name='I_MY_OBJECTS';
INDEX_NAME STATUS ------------------------------ -------- I_MY_OBJECTS UNUSABLE |
从这里可以看到,当table MY_OBJECTS进行move操作后,该table 上的inedx的状态为UNUSABLE,这时,我们可以使用alter index I_MY_OBJECTS rebuild online的命令,对index I_MY_OBJECTS进行在线rebuild。
b. move时对table的锁定
当我们对table MY_OBJECTS进行move操作时,查询v$locked_objects视图可以发现,table MY_OBJECTS上加了exclusive lock:
SQL>select OBJECT_ID, SESSION_ID,ORACLE_USERNAME,LOCKED_MODE from v$locked_objects;
OBJECT_ID SESSION_ID ORACLE_USERNAME LOCKED_MODE ---------- ---------- ------------------ ----------- 32471 9 DLINGER 6 SQL> select object_id from user_objects where object_name = 'MY_OBJECTS';
OBJECT_ID ---------- 32471 |
这就意味着,table在进行move操作时,我们只能对它进行select的操作。反过来说,当我们的一个session对table进行DML操作且没有commit时,在另一个session中是不能对这个table进行move操作的,否则oracle会返回这样的错误信息:ORA-00054: 资源正忙,要求指定 NOWAIT。
c. 关于move时空间使用的问题:
当我们使用alter table move来降低table的HWM时,有一点是需要注意的,这时,当前的tablespace中需要有1倍于table的空闲空间以供使用:
SQL> CREATE TABLESPACE TEST1 2 DATAFILE 'D:\ORACLE\ORADATA\ORACLE9I\TEST1.dbf' SIZE 5M 3 UNIFORM SIZE 128K ;
表已创建。
--------------- 3.125
SQL> alter table MY_OBJECTS move;
* ERROR 位于第 1 行: ORA-01652: 无法通过16(在表空间TEST1中)扩展 temp 段
2 DATAFILE 'D:\ORACLE\ORADATA\ORACLE9I\TEST1.DBF' RESIZE 7M;
SQL> alter table MY_OBJECTS move; 表已更改。 |