Oracle 作为一种特大型数据库,广泛应用于金融、邮电、电力、民航等数据吞吐量伟大,计算机网络宽泛推广的主要组织。至于系统管理员也就是说,何以责任书网络稳固运作,何以增高数据库性能,使其愈加保险高效率,便显得尤为重要。作为影响数据库性能的一大要素 -- 数据库碎片,应该唤起 DBA 的足够重视,及时发现并拾掇碎片就是 DBA 一项根本维护内容。
一、碎片是何以发作的
应生成一个数据库时,它会 分为号称表空间( Tablespace )的多个逻辑段( Segment ),如系统( System )表空间 , 暂时( Temporary )表空间等。一个表空间可以包孕多个数据范畴( Extent )和一个或多个自由范畴块,即自由空间( Free Space )。
表空间、段、范畴、自由空间的逻辑关系如次:
应表空间中生成一个段时,将从表空间有效自由空间中为这个段的初步范畴分配空间。在这些初步范畴充斥数据时,段会请求增多另一个范畴。这么的扩张历程会一直继续下去,直抵达到最大的范畴值,也许在表空间中已经没自由空间用来下一个范畴。最志向的状态乃是一个段的数据可被存在单调的一个范畴中。这么,全部的数据储存时挨近段内其它数据,而且寻觅数据可少用一些指针。但是一个段包孕多个范畴的状况是大量存在的,没任何措施可以军令状这些范畴是邻近储存的。应要满足一个空间要求时,数据库不再合龙紧邻的自由范畴(除非没法子),而是寻觅表空间中最大的自由范畴来运用。这么将渐渐形成越来越多的离散的、分隔的、较小的自由空间,即碎片。
二、碎片对系统的影响
跟着时间推移,基于数据库的运用系统的普遍运用,发作的碎片会越来越多,将对数据库有以次两点重要影响:
一)招致系统性能减杀
总的来说,应要满足一个空间要求时,数据库将第一查寻现阶段最大的自由范畴,而 " 最大 " 自由范畴渐渐变小,要找出一个足够大的自由范畴已变得愈来愈艰难,故此以致表空间中的速度障碍,使数据库的空间分配愈益远离志向状态;
二)铺张大量的表空间
固然有部分自由范畴(如表空间的 pctincrease 为非 零 )将会被 SMON (系统监控)后台老板历程周期性地归并,但始终有部分自由范畴没法方可自动合拢,铺张了大量的表空间。
三、自由范畴的碎片计算
因为自由空间碎片是由几一部分构成,如范畴数量、最大范围尺码等,我们可用 FSFI--Free Space Fragmentation Index (自由空间碎片目录)值来直观反映:
FSFI=100*SQRT(max(extent)/sum(extents))*一/SQRT(SQRT(count(extents)))
可以看出, FSFI 的最大或者值为 100 (一个志向的单资料表空间)。跟着范畴的增多, FSFI 值缓慢降落,而跟着最大范围分寸的减小, FSFI 值会迅速降落。
下边的脚本可以用以计算 FSFI 值:
rem FSFI Value Compute
rem fsfi.sql
column FSFI format 999,99
select tablespace_name,sqrt(max(blocks)/sum(blocks))*
(100/sqrt(sqrt(count(blocks)))) FSFI
from dba_free_space
group by tablespace_name order by 一;
spool fsfi.rep;
/
spool off;
例如,在某数据库运作脚本 fsfi.sql, 失去以次 FSFI 值:
TABLESPACE_NAME FSFI
------------------------------ -------
RBS 74.06
SYSTEM 100.00
TEMP 22.82
TOOLS 75.79
USERS 100.00
USER_TOOLS 100.00
YDCX_DATA 47.34
YDCX_IDX 57.19
YDJF_DATA 33.80
YDJF_IDX 75.55
---- 统计出了数据库的 FSFI 值,就可以把它作为一个可比参数。在一个有着足够有效自由空间,且 FSFI 值超过 30 的表空间中,很少会碰见有效自由空间的问题。应一个空间快要切近可比参数时,就需要做碎片收拾了。
四、自由范畴的碎片拾掇
表空间的 pctincrease 值为非 零
可以将表空间的缺省储存参数 pctincrease 改成非 零 。正常将其设为 一 ,如:
alter tablespace temp
default storage(pctincrease 一);
这么 SMON 便会将自由范畴自动归拢。也可以手工归拢自由范畴:
alter tablespace temp coalesce;
五、段的碎片拾掇
我们晓得,段由范畴结成。在有点情况下,有必要对段的碎片开展拾掇。要查看段的相关信息,可查看数据字典 dba_segments ,范畴的信息可查看数据字典 dba_extents 。
查询数据段
select segment_name,tablespace_name,bytes,blocks from USER_EXTENTS;
查询目录段
select index_name,table_owner,table_name,tablespace_name from USER_EXTENTS;
经过dba_segments查看段的信息
select tablespacee_name,count(*) nobjects,round(sum(bytes)/1024/1204/1024.2) GB,sum(blocks),sum(extents) from
dba_segments group by rollup(tablespace_name);
如若段的碎片过剩,将其数据压缩到一个范畴的最简略步骤乃是用准确的储存参数将这个段重建,其后将旧表中的数据安插到新表,与此同时剔除旧表。这个进程可以用 Import/Export (输入 / 输出)工具来完成。
Export ()下令有一个(压缩)标示,这个标示在读表时会挑动 Export 确定该表所分配的物理空间量,它会向输出转储资料写下一个新的初始化储存参数 -- 即是所有所分配空间。若这个表封闭, 则施用 Import ()工具从新生成。这么,它的数据会放入一个新的、较大的初始段中。比如:
exp user/password file=exp.dmp compress=Y grants=Y indexes=Y
tables=(table一,table二);
若输出顺利,则从库中剔除已输出的表,其后从输出转储资料中输入表:
imp user/password file=exp.dmp commit=Y buffer=64000 full=Y