OracleMove命令总结
  Oracle Move命令总结
  从8i开始,oracle开始提供Move的命令。我们通常使⽤这个命令,将⼀个table segment从⼀个tablespace移动到另⼀个tablespace。Move实际上是在block之间物理的copy数据,那么,我们可以通过这种⽅式来降低table的HWM。我们先通过⼀个实验来看看move是如何移动数据的。
  1.建表并插⼊数据:
  SQL> create st1(id int) tablespaceusers;
  表已创建。
  SQL> insert st1 values(1);
  已创建 1 ⾏。
  SQL> insert st1 values(2);
  已创建 1 ⾏。
  SQL> insert st1 values(3);
  已创建 1 ⾏。
  SQL> insert st1 values(4);
  已创建 1 ⾏。
  SQL> insert st1 values(5);
  已创建 1 ⾏。
  SQL> insert st1 values(6);
  已创建 1 ⾏。
  SQL> insert st1 values(7);
  已创建 1 ⾏。
  SQL> insert st1 values(8);
  已创建 1 ⾏。
  S QL> commit;
  提交完成。
  SQL> select * st1;
  已选择8⾏。
  2.查看表的rowid信息和block id信息:
  SQL> select rowid,id st1;
  已选择8⾏。
  SQL> select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS
  --8条记录都在⼀个块上(AAAABH)
  这⾥简单介绍⼀下ROWID的知识:ROWID在磁盘上需要10个字节的存储空间并使⽤18个字符来显⽰它包含下列组件:
  数据对象编号:每个数据对象如表或索引在创建时都分配有此编号,并且此编号在数据库中是唯⼀的;
  相关⽂件编号:此编号对于⼀个表空间中的每个⽂件是唯⼀的;
  块编号:表⽰包含此⾏的块在⽂件中的位置;
  ⾏编号:标识块头中⾏⽬录位置的位置;
  在内部数据对象编号需要32 位,相关⽂件编号需要10 位,块编号需要22,位⾏编号需要16 位,加起来总共是80 位或10 个字
节,ROWID使⽤以64 为基数的编码⽅案来显⽰该⽅案将六个位置⽤于数据对象,编号三个位置⽤于相关⽂件编号六个位置⽤于块编号三个位置⽤于⾏编号以64 为基数的编码⽅案使⽤字符A-Z a-z 0-9 + 和/共64 个字符,
  如下例所⽰:AAAMlQAAE AAAABH AAA
  3.做⼀些DML操作,再观察ROWID有没有发⽣变化:
  SQL> delete st1 where id=1;
  已删除 1 ⾏。
  SQL> delete st1 where id=3;
  已删除 1 ⾏。
  SQL> delete st1 where id=5;
  已删除 1 ⾏。
  SQL> commit;
  提交完成。
  SQL> select rowid,id st1;
  --我们看到ROWID保持不变。
  4.做MOVE操作,然后观察ROWID的情况:
  SQL> alter st1 move;
  表已更改。
  SQL> select rowid,id st1;
  --ROWID发⽣变化BLOCK_ID由原来的65变为73,BLOCK的编号由原来的AAAABH变为AAAABM
  5.move对HWM的影响:
  这⾥引⽤⽹友yjz0065的⼀个例⼦:
  SQL> create table my_objects tablespace HWM
  SQL> delete from my_objects where rownum<10000;
  9999 rows deleted
  SQL> select count(*) from my_objects;
  COUNT(*)
  ----------
  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
  然后对tableMY_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)
  我们可以看到,tableMY_OBJECTS的HWM从423移动到290,table的HWM降低了!(show_space是⾃定义的⼀个过程)。  Move的⼀些⽤法:
  以下是altertable 中move⼦句的完整语法,我们介绍其中的⼏点:
  MOVE [ONLINE]
  [segment_attributes_clause]
  [data_segment_compression]
  [index_org_table_clause]
  [ { LOB_storage_clause | varray_col_properties }
  �0�2�0�2�0�2 [ { 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中delete用法  SQL> select index_name,status from user_indexeswhere index_name='I_MY_OBJECTS';
  从这⾥可以看到,当tableMY_OBJECTS进⾏move操作后,该table上的inedx的状态为UNUSABLE,这时,我们可以使⽤alterindex I_MY_OBJECTS rebuild online的命令,对index I_MY_OBJECTS进⾏在线rebuild。
  b. move时对table的锁定
  当我们对tableMY_OBJECTS进⾏move操作时,查询v$locked_objects视图可以发现,tableMY_OBJECTS上加了exclusivelock:
  SQL>select OBJECT_ID, SESSION_ID,ORACLE_USERNAME,LOCKED_MODE from v$locked_objects;
  SQL> select object_id from user_objects whereobject_name = 'MY_OBJECTS';
  OBJECT_ID
  ----------
  这就意味着,table在进⾏move操作时,我们只能对它进⾏select的操作。反过来说,当我们的⼀个session对table进⾏DML操作且没有commit时,在另⼀个session中是不能对这个table进⾏move操作的,否则oracle会返回这样的错误信息:ORA-00054: 资源正忙,要求指定 NOWAIT。
  c. 关于move时空间使⽤的问题:
  当我们使⽤altertable move来降低table的HWM时,有⼀点是需要注意的,这时,当前的tablespace中需要有1倍于table的空闲空间以供使⽤:
  SQL> CREATE TABLESPACE TEST1 DATAFILE 'D:\ORACLE\ORADATA\ORACLE9I\TEST1.dbf' SIZE 5M UNIFORMSIZE 128K ;
  SQL> create table my_objects tablespace test1 asselect * from all_objects;
  表已创建。
  SQL> select bytes/1024/1024 from user_segmentswhere segment_name='MY_OBJECTS';
  BYTES/1024/1024
  ---------------
  SQL> alter table MY_OBJECTS move;
  alter table MY_OBJECTS move
  ERROR 位于第 1 ⾏:
  ORA-01652: ⽆法通过16(在表空间TEST1中)扩展 temp 段
  SQL> ALTER DATABASE DATAFILE 'D:\ORACLE\ORADATA\ORACLE9I\TEST1.DBF' RESIZE7M;
  数据库已更改。
  SQL> alter table MY_OBJECTS move;
  表已更改。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。