oracle move long,oracle中的move命令简介

从8i开始,oracle开始提供Move的命令。我们通常使用这个命令,将一个table segment从一个tablespace移动到另一个tablespace。Move实际上是在block之间物理的copy数据,那么,我们可以通过这种方式来降低table的HWM。我们先通过一个实验来看看move是如何移动数据的。

1.建表并插入数据:

SQL> create table sjh.test1(id int) tablespace users;

表已创建。

SQL> insert into sjh.test1 values(1);

已创建 1 行。

SQL> insert into sjh.test1 values(2);

已创建 1 行。

SQL> insert into sjh.test1 values(3);

已创建 1 行。

SQL> insert into sjh.test1 values(4);

已创建 1 行。

SQL> insert into sjh.test1 values(5);

已创建 1 行。

SQL> insert into sjh.test1 values(6);

已创建 1 行。

SQL> insert into sjh.test1 values(7);

已创建 1 行。

SQL> insert into sjh.test1 values(8);

已创建 1 行。

SQL> commit;

提交完成。

SQL> select * from sjh.test1;

ID

----------

1

2

3

4

5

6

7

8

已选择8行。

2.查看表的rowid信息和block id信息:

SQL> select rowid,id from sjh.test1;

ROWID                      ID

------------------ ----------

AAAMlQAAEAAAABHAAA          1

AAAMlQAAEAAAABHAAB          2

AAAMlQAAEAAAABHAAC          3

AAAMlQAAEAAAABHAAD          4

AAAMlQAAEAAAABHAAE          5

AAAMlQAAEAAAABHAAF          6

AAAMlQAAEAAAABHAAG          7

AAAMlQAAEAAAABHAAH          8

已选择8行。

SQL> select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS

2  from dba_extents  where segment_name='TEST1';

EXTENT_ID    FILE_ID RELATIVE_FNO   BLOCK_ID     BLOCKS

---------- ---------- ------------ ---------- ----------

0          4            4         65          8

--8条记录都在一个块上(AAAABH)

这里简单介绍一下ROWID的知识:

ROWID 在磁盘上需要10 个字节的存储空间并使用18 个字符来显示它包含下列组件:

数据对象编号:每个数据对象如表或索引在创建时都分配有此编号,并且此编号在数据库中是唯一的;

相关文件编号:此编号对于一个表空间中的每个文件是唯一的;

块编号:表示包含此行的块在文件中的位置;

行编号:标识块头中行目录位置的位置;

在内部数据对象编号需要32 位,相关文件编号需要10 位,块编号需要22,位行编号需要16 位,加起来总共是80 位或10 个字节,ROWID 使用以64 为基数的编码方案来显示该方案将六个位置用于数据对象,编号三个位置用于相关文件编号六个位置用于块编号三个位置用于行编号以64 为基数的编码方案使用字符A-Z a-z 0-9 + 和/共64 个字符,如下例所示:

AAAMlQ AAE AAAABH AAA

在本例中

AAAMlQ   是数据对象编号

AAE      是相关文件编号

AAAABH   是块编号

AAA      是行编号

3.做一些DML操作,再观察ROWID有没有发生变化:

SQL> delete from sjh.test1 where id=1;

已删除 1 行。

SQL> delete from sjh.test1 where id=3;

已删除 1 行。

SQL> delete from sjh.test1 where id=5;

已删除 1 行。

SQL> commit;

提交完成。

SQL>  select rowid,id from sjh.test1;

ROWID                      ID

------------------ ----------

AAAMlQAAEAAAABHAAB          2

AAAMlQAAEAAAABHAAD          4

AAAMlQAAEAAAABHAAF          6

AAAMlQAAEAAAABHAAG          7

AAAMlQAAEAAAABHAAH          8

--我们看到ROWID保持不变。

4.做MOVE操作,然后观察ROWID的情况:

SQL> alter table sjh.test1 move;

表已更改。

SQL> select rowid,id from sjh.test1;

ROWID                      ID

------------------ ----------

AAAMlRAAEAAAABMAAA          2

AAAMlRAAEAAAABMAAB          4

AAAMlRAAEAAAABMAAC          6

AAAMlRAAEAAAABMAAD          7

AAAMlRAAEAAAABMAAE          8

SQL>  select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS

2   from dba_extents  where segment_name='TEST1';

EXTENT_ID    FILE_ID RELATIVE_FNO   BLOCK_ID     BLOCKS

---------- ---------- ------------ ---------- ----------

0          4            4         73          8

--ROWID发生变化BLOCK_ID由原来的65变为73,BLOCK的编号由原来的AAAABH变为AAAABM

5.move对HWM的影响:

这里引用网友yjz0065的一个例子:

SQL> create table my_objects tablespace HWM

2as 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 30knext 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_NAMESTATUS

------------------------------ --------

I_MY_OBJECTSUNUSABLE

从这里可以看到,当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_USERNAMELOCKED_MODE

---------- ---------- ------------------ -----------

324719 DLINGER6

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 ;

SQL> create table my_objects  tablespace test1 as select * from all_objects;

表已创建。

SQL> select bytes/1024/1024 from user_segments where segment_name='MY_OBJECTS';

BYTES/1024/1024

---------------

3.125

SQL> alter table MY_OBJECTS move;

alter table MY_OBJECTS move

*

ERROR位于第1行:

ORA-01652:无法通过16(在表空间TEST1中)扩展temp段

SQL> ALTER DATABASE

2  DATAFILE 'D:\ORACLE\ORADATA\ORACLE9I\TEST1.DBF' RESIZE  7M;

数据库已更改。

SQL> alter table MY_OBJECTS move;

表已更改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值