重庆思庄Oracle、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 209|回复: 0
打印 上一主题 下一主题

[Oracle] Oracle表空间碎片维护

[复制链接]
跳转到指定楼层
楼主
发表于 2024-9-1 19:23:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

表空间碎片说明

在Oracle数据库中,表空间碎片指的是表空间中存在未被充分利用的空间片段(extent)。
这些空间片段可能是由于数据的增删改操作导致,造成表空间中存在一些零散的、不连续的数据块。表空间碎片可能会影响数据库性能和空间利用效率,也就是存在空闲空间,但是无法被使用,造成业务在对数据库表的增删改时提示空间不足的问题。



Oracle存储逻辑结构

Oracle存储的逻辑结构由表空间、段、区间、块组成,区间是数据库存储空间分配的逻辑单位,由一些连续数据块组成。一个或多个区间又构成了一个段。当现有分配的区间被完全使用的时候,Oracle就会为段分配一个新的区间。
对于AutoAllocate管理的区间而言,你可以指定初始段的大小,然后由Oracle决定新增区间的大小,最小区间大小为64k。自动扩展空间的选择有64K,1M,8M,64M。



表空间监控

为了防止表空间碎片过高导致表空间不可用问题,我们优化了表空间监控语句,增加了碎片空间监控,也就是不再只是仅仅监控剩余空间,而是将剩余空间减去碎片空间,得出的才是可用空间;
因为每个库大小不一,表的增删改每次获取的空间大小不一致,我们采用最大指标64M来进行监控,当获取不到64M的连续数据块时(extent),这些不连续的数据块被认定为碎片。
以下是最新表空间监控语句:
select  a.TABLESPACE_NAME "TBNAME",
    a.SPLINTER_SPACE "GetTableSplinterSize",
    a.SP_RATE "GetTableSPSizePused"
  from
    (SELECT D.TABLESPACE_NAME,
        TO_CHAR(SPACE,'fm999990.99') SPACE,
        BLOCKS SUM_BLOCKS,
        TO_CHAR(SPACE - NVL(FREE_SPACE, 0),'FM999990.00') "USED_SPACE",
        TO_CHAR(ROUND((1 - NVL(FREE_SIZE, 0) TOTAL_SIZE) * 100, 2),'FM999990.00') "USED_RATE",
        TO_CHAR(FREE_SPACE,'FM999990.00') "FREE_SPACE",
        TO_CHAR(S.SPLINTER_SPACE,'fm999990.00') "SPLINTER_SPACE",
        TO_CHAR(ROUND((1 - NVL(F.FREE_SIZE-S.SPLINTER, 0) / D.TOTAL_SIZE) * 100, 2),'fm999990.99') "SP_RATE"
    FROM
      (SELECT TABLESPACE_NAME, SUM(BYTES) TOTAL_SIZE,ROUND(SUM(BYTES) / (1024 * 1024), 2) SPACE, SUM(BLOCKS) BLOCKS FROM DBA_DATA_FILES GROUP BY TABLESPACE_NAME) D,
      (SELECT TABLESPACE_NAME, SUM(BYTES) FREE_SIZE,ROUND(SUM(BYTES) / (1024 * 1024), 2) FREE_SPACE FROM DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F,
      (SELECT TABLESPACE_NAME,COUNT(*) SP_COUNT,SUM(BYTES) SPLINTER,round(sum(bytes)/1024/1024,2) SPLINTER_SPACE FROM DBA_FREE_SPACE WHERE BYTES/1024/1024 <64 GROUP BY TABLESPACE_NAME) S
      WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+)
      AND D.TABLESPACE_NAME = S.TABLESPACE_NAME
      ORDER BY  "USED_RATE" DESC) a,
    dba_tablespaces b
  where a.tablespace_name = b.tablespace_name
  and a.tablespace_name not like 'UNDO%';



表空间可用空间不足处理方法

4.1 清理数据
可以清理业务过期数据,释放空间,增加可用空间:
Drop table T1 purge;

4.2 重组表
可以将表重建,重新获取连续空间,降低不连续空间的概率:
Create table t2 as select * from t1;
Drop table t1 purge;
Alter table t2 rename to t1;

4.3 申请扩容表空间
可以提扩容工单,扩容足够表空间防止空间不可用情况:
Alter tablespace tbs1 add datafile ‘+DATA’ size 30G;



碎片解决办法

5.1 创建新表空间test_tbs
大小大于需要移动的原表空间:
create tablespace test_tbs datafile '+DATA' SIZE 30G;
Alter tablespace test_tbs add datafile '+DATA' SIZE 30G;
Alter tablespace test_tbs add datafile '+DATA' SIZE 30G;

5.2 移动原表空间内的表
--批量脚本:
SELECT  'alter table '||OWNER||'.'||TABLE_NAME||' move
tablespace NEW_TABLESPACE;' FROM DBA_TABLES WHERE TABLESPACE_NAME = 'OLD_TABLESPACE';

--示例:
alter table U1.T1 move tablespace NEW_TABLESPACE;

如果有分区表:
select 'alter table ' ||table_owner|| '.' || table_name || '
move partition ' || partition_name || ' tablespace
NEW_TABLESPACE;' as move_sql from dba_tab_partitions where tablespace_name='OLD_TABLESPACE';

如果有子分区表:
select 'alter table ' ||table_owner|| '.' || table_name || '
move subpartition ' || SUBPARTITION_NAME || ' tablespace
NEW_TABLESPACE;' as move_sql from DBA_TAB_SUBPARTITIONS
where tablespace_name='OLD_TABLESPACE';

5.3 查看索引情况
select index_name,index_type,table_name,table_owner,table_type,uniq
ueness,status from dba_indexes where tablespace_name = 'OLD_TABLESPACE';

5.4 重建索引
select 'alter index ' ||OWNER||'.'||index_name||' rebuild
online;' from dba_indexes where status <> 'VALID';

如果有分区索引:
select 'alter index '||a.table_owner||'.' ||b.index_name||'
rebuild partition '||a.partition_name||' tablespace
NEW_TABLESPACE parallel 8 online; ' from dba_tab_partitions
a,dba_ind_partitions b where
a.partition_name=b.partition_name and
a.tablespace_name='OLD_TABLESPACE';

如果有子分区索引:
select 'alter index '||a.table_owner||'.' ||b.index_name||'
rebuild subpartition '||a.partition_name||' tablespace NEW_TABLESPACE parallel 8 online; ' from
dba_tab_subpartitions a,dba_ind_subpartitions b where
a.partition_name=b.partition_name and
a.subpartition_name=b.subpartition_name and
a.tablespace_name='OLD_TABLESPACE';

如果有lob字段:
select 'alter table '||owner||'.'||table_name||
' move lob('||COLUMN_NAME||') store as (NEW_TABLESPACE);'from dba_lobs where TABLESPACE_NAME='OLD_TABLESPACE';

如果有需要,可以将这些表,索引等对象重新移动回原表空间内,然后删除中转的表空间;如果直接使用新表空间,可以将原表空间的大小resize回收到ASM磁盘组即可(建议DBA操作)。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2024-10-10 05:27 , Processed in 0.086780 second(s), 21 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表