我们在使用windows的时候,都知道要定期整理磁盘碎片,因为磁盘碎片会影响性能,给管理上带来额外的
负担。那oracle更是如此,当随着数据增加,oracle处理海量数据本身就已经很费力了啊,如果再有大量
的碎片,那就是雪上加霜啊。所以碎片要引起dba的高度重视,尽早发现尽早处理。
碎片是怎么产生的呢?
简单理解就是由于更新和删除产生一些碎小的不能被再次使用的空间,根据每种不同的碎片他们的产生也是有区别的
block-level的碎片,而block又分为data
block和index block,在data block中存放的是row数据,在index block
中存放的是索引键值数据,所以按上面所说,block-level碎片有细分为row-level碎片和Index Leaf
Block-level碎片。
oracle的每一个对象都是存储在segment中,而oracle的最小分配单位是extents(区),在数据更新删除中也会产生碎片
这一级别的碎片就是segment碎片。segment又存在datafile中,而tablespace又是包含datafile的逻辑概念。所以这一层
是tablespace-level碎片;tablespace是在disk上存储,所以这一层就是disk-level碎片。
简单图示如下
disk-level fragmention
tablespace-level fragmentation
segment-level fragmentation
block-level fragmentation
row-level fragmentation
index leaf block-level fragmentation
顺便提下oracle extents存在的理由
一个extents是由多个相连的block组成的,多个extents做成一个segment;extent是oracle的最小分配单位
extent的优点:
1. 提高空间分配,释放的效率,降低管理block的资源成本
2. 提高扫描的效率,因为extent是由相连blocks做成的特性,可以一次读取更多的内容,较低io读写次数
extent的缺点
容易产生碎片
如何确定产生了碎片的呢?
一。表空间碎片确定参考
由于自由空间碎片是由几部分组成,如范围数量、最大范围尺寸等,我们可用
FSFI--Free Space Fragmentation Index
(自由空间碎片索引)值来直观体现:
FSFI=100*SQRT(max(extent)/sum(extents))*1/SQRT(SQRT(count(extents)))
可以看出,FSFI 的最大可能值为 100
(一个理想的单文件表空间)。随着范围的增加, FSFI 值缓慢下降,而随着最大范
围尺寸的减少,FSFI 值会迅速下降。通过如下语句查询FSFI:
select tablespace_name,
sqrt(max(blocks) / sum(blocks)) * (100 / sqrt(sqrt(count(blocks))))
FSFI
from dba_free_space
group by tablespace_name
order by 1;
在一个有着足够有效自由空间,且FSFI
值超过30的表空间中,很少会遇见有效自由空间的问题。当一个空间将要接近
可比参数时,就需要做碎片整理了(DMT空间可以整理,如果是LMT就无法整理)。(SMON 会将相邻的自由范围自动合并)
temp表空间(非本地管理表空间)
回收
可以将表空间的缺省存储参数pctincrease改为非0。一般将其设为1,如:
alter
tablespace
temp
default
storage(pctincrease
1);
这样smon便会将自由范围自动合并。也可以手工合并自由范围:
alter
tablespace
temp
coalesce;
二。segment的碎片整理
segment的碎片整理一般主要整理table和index
9i之前碎片整理的方法
1. exp/truncate/imp
2.
alter table table_name move stroage(initial 1m)
alter index index_name rebuild [tablespace tablespace_name]
[nologging] [online]
3.CTAS重组
在10g之后,不但可以用以上两种方法,还提供了新的方法
alter table <table_name> shrink space [ <null> | compact | cascade ];
compact:这个参数当系统的负载比较大时可以用,不降低HWM。如果系统负载较低时,直接用alter table
table_name shrink space就一步到位了
cascade:这个参数是在shrink table的时候自动级联索引,相当于rebulid index。
普通表
shrink必须开启行迁移功能。
alter table table_name enable row movement ;
保持HWM,相当于把块中数据打结实了
alter table table_name shrink space compact;
回缩表与降低HWM
alter table table_name shrink space;
回缩表与相关索引,降低HWM
alter table table_name shrink space cascade;
回缩索引与降低HWM
alter index index_name shrink space
虽然在10g中可以用shrink ,但也有些限制:
1). 对cluster,cluster
table,或具有Long,lob类型列的对象 不起作用。
2). 不支持具有function-based indexes 或 bitmap join indexes的表
3). 不支持mapping 表或index-organized表。
4). 不支持compressed 表
参考文档:
从9i开始index碎片的整理除了drop and create index,还可以 alter index skate.t1_idx rebuild nologging parallel 4 online ;
表的碎片查找