测试3——探究shrink和move原理

shrink操作的机制:

我们接下来讨论一下shrink的实现机制,我们同样使用讨论move机制的那个实验来观察.
SQL> create table TEST_HWM (id int ,name char(2000)) tablespace ASSM;
Table created 往table test_hwm中插入如下的数据:
insert into TEST_HWM values (1,'aa');
insert into TEST_HWM values (2,'bb');
insert into TEST_HWM values (2,'cc');
insert into TEST_HWM values (3,'dd');
insert into TEST_HWM values (4,'ds');
insert into TEST_HWM values (5,'dss');
insert into TEST_HWM values (6,'dss');
insert into TEST_HWM values (7,'ess');
insert into TEST_HWM values (8,'es');
insert into TEST_HWM values (9,'es');
insert into TEST_HWM values (10,'es');

我们来看看这个table的rowid和block的ID和信息:
SQL> select rowid , id,name from TEST_HWM;

11 rows selected
SQL> select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS from dba_extents where segment_name='TEST_HWM';

 然后从table test_hwm中删除一些数据:
delete from TEST_HWM where id = 2; 

delete from TEST_HWM where id = 4; 

delete from TEST_HWM where id = 3; 

delete from TEST_HWM where id = 7; 

delete from TEST_HWM where id = 8;
观察table test_hwm的rowid和blockid的信息:
SQL> select rowid , id,name from TEST_HWM;

SQL> select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS from dba_extents where segment_name='TEST_HWM' ;

从以上的信息,我们可以看到,在table test_hwm中,剩下的数据是分布在
AAAAJD,AAAAJF,AAAAJG,AAAAJH这样四个连续的block中.
SQL> exec show_space_assm('TEST_HWM','ASSMTEST');
SQL> exec show_space_assm('TEST_HWM','ASSMTEST');
free space 0-25% Blocks:................0
free space 25-50% Blocks:...............1
free space 50-75% Blocks:...............3
free space 75-100% Blocks:..............1

Full Blocks:............................0
Unformatted blocks:.....................0

PL/SQL procedure successfully completed.


通过show_space_assm我们可以看到目前这四个block的空间使用状况,AAAAJF,AAAAJG,AAAAJH上各有一行数据,我们猜测free space为50-75%的3个block是这三个block,那么free space为25-50%的1个block就是AAAAJD了,剩下free space为 75-100% 的1个block,是HWM下已格式化的尚未使用的block.(关于assm下hwm的移动我们前面已经详细地讨论过了,在extent不大于16个block时,是以一个extent为单位来移动的)
然后,我们对table my_objects执行shtink的操作:
SQL> alter table test_hwm enable row movement;
Table altered
SQL> alter table test_hwm shrink space;
Table altered
SQL> select rowid ,id,name from TEST_HWM;

SQL> select EXTENT_ID,FILE_ID,RELATIVE_FNO,BLOCK_ID,BLOCKS
2 from dba_extents where segment_name='TEST_HWM' ;

当执行了shrink操作后,有意思的现象出现了.我们来看看oracle是如何移动行数据的,这里的情况和move已经不太一样了.我们知道,在move操作的时候,所有行的rowid都发生了变化,table所位于的block的区域也发生了变化,但是所有行物理存储的顺序都没有发生变化,

所以我们得到的结论是:oracle以block为单位,进行了block间的数据copy.那么shrink后,我们发现,部分行数据的rowid发生了变化,同时,部分行数据的物理存储的顺序也发生了变化,而table所位于的block的区域却没有变化,这就说明,shrink只移动了table其中一部分的行数据,来完成释放空间,而且,这个过程是在table当前所使用的block中完成的.

那么Oracle具体移动行数据的过程是怎样的呢 我们根据这样的实验结果,可以来猜测一下:
Oracle是以行为单位来移动数据的.Oracle从当前table存储的最后一行数据开始移动,从当前table最先使用的block开始搜索空间,所以,shrink之前,rownum=6的那行数据(6,dss),被移动到block AAAAJD上,写到(10,es)这行数据的后面,所以(6,dss)的rownum和rowid同时发生改变.然后是(5,dss)这行数据

,重复上述过程.发现数据块AAAAJE是没有被使用过的(有可能是因为之前的行被删除了),这个时候,(5,dss)这行就被移动到了AAAAJE这个数据块上,这是oracle从后向前移动行数据的大致遵循的规则,那么具体移动行数据的的算法是比较复杂的,包括向ASSM的table中insert数据使用block的顺序的算法也是比较复杂的,大家有兴趣的可以自己来研究,在这里我们不多做讨论.


我们还可以在shrink table的同时shrink这个table上的index:
alter table my_objects shrink space cascade;

同样地,这个操作只有当table上的index也是ASSM时,才能使用.



Shrink的几点问题:

a. shrink后index是否需要rebuild:

因为shrink的操作也会改变行数据的rowid,那么,如果table上有index时,shrink table后index会不会变为UNUSABLE呢?我们来看这样的实验,同样构建my_objects的测试表:

create table my_objects tablespace ASSM as select * from all_objects where rownum<20000;

create index i_my_objects on my_objects (object_id);

delete from my_objects where object_name like '%C%';

delete from my_objects where object_name like '%U%';

现在我们来shrink table my_objects:

SQL> alter table my_objects enable row movement;

Table altered

SQL> alter table my_objects shrink space;

Table altered

SQL> select index_name,status from user_indexes where index_name='I_MY_OBJECTS';

INDEX_NAME STATUS

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

I_MY_OBJECTS VALID

我们发现,table my_objects上的index的状态为VALID,估计shrink在移动行数据时,也一起维护了index上相应行的数据rowid的信息。我们认为,这是对于move操作后需要rebuild index的改进。但是如果一个table上的index数量较多,我们知道,维护index的成本是比较高的,shrink过程中用来维护index的成本也会比较高。

b. shrink时对table的lock

在对table进行shrink时,会对table进行怎样的锁定呢?当我们对table MY_OBJECTS进行shrink操作时,查询v$locked_objects视图可以发现,table MY_OBJECTS上加了row-X (SX) 的lock:

SQL>select OBJECT_ID, SESSION_ID,ORACLE_USERNAME,LOCKED_MODE from v$locked_objects;

OBJECT_ID SESSION_ID ORACLE_USERNAME LOCKED_MODE

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

55422 153 DLINGER 3

SQL> select object_id from user_objects where object_name = 'MY_OBJECTS';

OBJECT_ID

----------

55422

那么,当table在进行shrink时,我们对table是可以进行DML操作的。

c. shrink对空间的要求

我们在前面讨论了shrink的数据的移动机制,既然oracle是从后向前移动行数据,那么,shrink的操作就不会像move一样,shrink不需要使用额外的空闲空间。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值