Shrink详解Word文档格式.docx
- 文档编号:20809469
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:12
- 大小:147.76KB
Shrink详解Word文档格式.docx
《Shrink详解Word文档格式.docx》由会员分享,可在线阅读,更多相关《Shrink详解Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
altertableXXXenablerowmovement语句会造成引用表XXX的对象(如存储过程、包、视图等)变为无效。
执行完成后,最好执行一下utlrp.sql来编译无效的对象。
语法:
altertable<
table_name>
shrinkspace[<
null>
|compact|cascade];
其中:
shrinkspacecompcat;
收缩表,相当于把块中数据打结实了,但会保持
highwatermark;
tablespace_name>
shrinkspace;
收缩表,降低
shrinkspacecascade;
highwatermark,并且相关索引也要收缩一下。
alterindexidxnameshrinkspace;
回缩索引
1:
普通表
Sql脚本,该脚本会生成相应的语句:
select'
altertable'
||table_name||'
enablerowmovement;
'
||chr(10)||'
||table_name||'
||chr(10)fromuser_tables;
select'
alterindex'
||index_name||'
||chr(10)fromuser_indexes;
2:
分区表的处理
进行shrinkspace时
发生ORA-10631错误.shrinkspace有一些限制.
在表上建有函数索引(包括全文索引)会失败。
Sql脚本,改脚本会生成相应的语句:
||chr(10)||'
||chr(10)fromuser_tables;
||chr(10)fromuser_indexeswhereuniqueness='
NONUNIQUE'
;
||segment_name||'
modifysubpartition'
||partition_name||'
||chr(10)fromuser_segmentswheresegment_type='
TABLESUBPARTITION'
详细测试:
我们用系统视图all_objects来在上个测试的tablespaceASSM上创建测试表my_objects
SELECT
TABLESPACE_NAME,
BLOCK_SIZE,
EXTENT_MANAGEMENT,
ALLOCATION_TYPE,
SEGMENT_SPACE_MANAGEMENT
FROM
dba_tablespaces
WHERE
TABLESPACE_NAME
=
HECV'
;
CREATE
TABLE
my_objects
TABLESPACE
hecv
AS
*
all_objects;
然后我们随机地从tableMY_OBJECTS中删除一部分数据:
SQL>
COUNT
(*)
my_objects;
deletefrommy_objectswhereobject_namelike'
%C%'
%U%'
%A%'
现在我们使用show_space()来看看my_objects的数据存储状况:
exec
show_space('
my_objects'
'
auto'
T'
Y'
);
这里,tablemy_objects的HWM下有1152个block,其中,freespace为25-50%的block有303个,freespace为50-75%的block有284个,freespace为75-100%的block有409个.Totalblocks11个。
这种情况下,我们需要对这个table的现有数据行进行重组。
要使用assm上的shink,首先我们需要使该表支持行移动,可以用这样的命令来完成:
altertablemy_objectsenablerowmovement;
现在,就可以来降低my_objects的HWM,回收空间了,使用命令:
altertablebookingsshrinkspace;
我们具体的看一下实验的结果:
在执行玩shrink命令后,我们可以看到,tablemy_objects的HWM现在降到了456的位置,而且HWM下的block的空间使用状况,Totalblocks
的block有430个,freespace
为25-50%Block只有1个。
Shrink
的实现机制:
我们接下来讨论一下shrink的实现机制,我们同样使用讨论move机制的那个实验来观察。
TEST_HWM
(id
INT,
name
CHAR
(2000))
hecv;
INSERT
INTO
VALUES
(1,
aa'
(2,
bb'
cc'
(3,
dd'
(4,
ds'
(5,
dss'
(6,
(7,
ess'
(8,
es'
(9,
(10,
我们来看看这个table的rowid和block的ID和信息:
ROWID,
id,
TEST_HWM;
EXTENT_ID,
FILE_ID,
RELATIVE_FNO,
BLOCK_ID,
BLOCKS
dba_extents
segment_name
TEST_HWM'
然后从tabletest_hwm中删除一些数据:
deletefromTEST_HWMwhereid=2;
deletefromTEST_HWMwhereid=4;
deletefromTEST_HWMwhereid=3;
deletefromTEST_HWMwhereid=7;
deletefromTEST_HWMwhereid=8;
观察tabletest_hwm的rowid和blockid的信息:
selectrowid,id,namefromTEST_HWM;
从以上的信息,我们可以看到,在tabletest_hwm中,剩下的数据是分布在AAA10z,AAA100,AAA102,AAA103这样四个连续的block中。
我们可以看到目前这四个block的空间使用状况,AAA10z,AAA100,AAA103上各有一行数据,我们猜测freespace为50-75%的3个block是这三个block,那么freespace为25-50%的1个block就是AAA102了,剩下freespace为
75-100%
的1个block,是HWM下已格式化的尚未使用的block。
然后,我们对tablemy_objects执行shtink的操作:
altertabletest_hwmenablerowmovement;
altertabletest_hwmshrinkspace;
selectrowid,id,namefromTEST_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之前,(9,es)被移动到blockAAA10z上,写到(1,aa)这行数据的后面,所以(9,es)的rowid发生改变。
然后是(6,es)这行数据,重复上述过程。
这是oracle从后向前移动行数据的大致遵循的规则,那么具体移动行数据的的算法是比较复杂的,包括向ASSM的table中insert数据使用block的顺序的算法也是比较复杂的,大家有兴趣的可以自己来研究,在这里我们不多做讨论。
在shrinktable的同时shrink这个table上的index:
altertablemy_objectsshrinkspacecascade;
同样地,这个操作只有当table上的index也是ASSM时,才能使用。
Move
和
产生日志的对比
我们对比了同样数据量和分布状况的两张table,在move和shrink下生成的redosize(table上没有index的情况下):
tablespace_name,
tablespace_name
IN
('
HECV'
createtablemy_objectstablespaceHECVasselect*fromall_objectswhererownum<
20000;
createtablemy_objects1tablespaceHECV_FRONTasselect*fromall_objectswhererownum<
selectbytes/1024/1024fromuser_segmentswheresegment_name='
MY_OBJECTS'
deletefrommy_objects1whereobject_namelike'
altertablemy_objectsenablerowmovement;
VALUE
v$mystat,
v$statname
v$mystat.statistic#
v$statname.statistic#
AND
v$statname.name
redosize'
altertablemy_objectsshrinkspace;
altertablemy_objects1move;
对于tablemy_objects,进行shrink,产生了21148396–16762668=4385728,约4.2M的redo
;
对tablemy_objects1进行move,产生了21212908-21148396=64512,约63K的redosize。
结论:
与move比较起来,shrink的日志写要大得多。
Shrink的几点问题:
1.
shrink后index是否需要rebuild:
因为shrink的操作也会改变行数据的rowid,那么,如果table上有index时,shrinktable后index会不会变为UNUSABLE呢?
我们来看这样的实验,同样构建my_objects的测试表:
createtablemy_objectstablespacehecvasselect*fromall_objectswhererownum<
createindexi_my_objectsonmy_objects(object_id);
deletefrommy_objectswhereobject_namelike'
现在我们来shrinktablemy_objects:
selectindex_name,statusfromuser_indexeswhereindex_name='
I_MY_OBJECTS'
我们发现,tablemy_objects上的index的状态为VALID,估计shrink在移动行数据时,也一起维护了index上相应行的数据rowid的信息。
我们认为,这是对于move操作后需要rebuildindex的改进。
但是如果一个table上的index数量较多,我们知道,维护index的成本是比较高的,shrink过程中用来维护index的成本也会比较高。
2.shrink时对table的lock
在对table进行shrink时,会对table进行怎样的锁定呢?
当我们对tableMY_OBJECTS进行shrink操作时,查询v$locked_objects视图可以发现,tableMY_OBJECTS上加了row-X(SX)
的lock:
selectOBJECT_ID,SESSION_ID,ORACLE_USERNAME,LOCKED_MODEfromv$locked_objects;
OBJECT_IDSESSION_IDORACLE_USERNAMELOCKED_MODE
-------------------------------------------------
55422153DLINGER3
selectobject_idfromuser_objectswhereobject_name='
OBJECT_ID
----------
55422
那么,当table在进行shrink时,我们对table是可以进行DML操作的。
3.shrink对空间的要求
我们在前面讨论了shrink的数据的移动机制,既然oracle是从后向前移动行数据,那么,shrink的操作就不会像move一样,shrink不需要使用额外的空闲空间。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Shrink 详解