导读:本期聚焦于美园和花创作的《Oracle数据库碎片整理怎么做?表空间收缩与碎片优化的完整实践》,敬请观看详情。数据库用久了,明明删了大量数据,表空间却不见变小,查询性能还越来越慢,这多半是碎片问题在作怪。本文围绕Oracle碎片整理展开,先解释行迁移、高水位线下降等碎片的产生原理,再介绍如何通过数据字典视图定位碎片率高的对象,最后给出shrink space、move、expdp impdp重组等几种主流收缩方案的完整操作步骤和适用场景对比,同时说明在线重定义、索引重建的配合使用技巧,以及生产环境操作前的注意事项,帮助读者安全地把空间还给操作系统,恢复查询效率。

Oracle数据库在长期运行过程中,频繁的删除和更新操作会让表段和数据文件中产生大量碎片。典型表现是:一张表删掉了几千万行数据,dba_segments里显示的段大小却几乎没变,新插入的数据依然占着磁盘空间。要理解碎片整理,必须先弄清楚Oracle存储结构中两个关键概念:行迁移和高水位线(HWM)。本文将从原理、诊断和具体操作三个层面,完整讲解Oracle的碎片整理与空间收缩方法。

Oracle数据库碎片整理怎么做?表空间收缩与碎片优化的完整实践

一、Oracle碎片是怎么产生的

Oracle对表的存储管理以段(Segment)为单位,段由多个区间(Extent)组成,区间又由连续的数据块构成。当执行DELETE操作时,Oracle只在数据块内标记行被删除,被释放的空间会进入空闲列表或者位图管理,但段本身占用的区间并不会归还。也就是说,DELETE之后段大小基本不变,只有TRUNCATE才会真正释放区间(如果TRUNCATE没带REUSE STORAGE子句)。

另一个碎片来源是行迁移(Row Migration)。当一行数据因为UPDATE而变长,原来的数据块放不下时,Oracle会把整行迁移到新的数据块,原位置只留一个指针指向新块。发生迁移的行在被查询时需要访问两个数据块,代价翻倍。判断行迁移数量可以查看v$sysstat中的table fetch continued row统计值,如果这个数字持续增长,说明存在明显的行迁移问题。

高水位线(High Water Mark)是段中曾使用过的最大数据块位置。全表扫描会一直扫描到HWM,即使HWM以下的块全是空的。DELETE不会降低HWM,所以一张删空的表做全表扫描依然很慢,这就是碎片影响性能的直接体现。

二、如何诊断和定位碎片严重的对象

收缩之前,先要找到哪些对象碎片率高。可以通过查询数据字典统计信息来判断,核心是对比段的实际大小和有效数据量。常用的判断方式是查看表的统计信息中空块的比例:

-- 查询碎片率较高的表(需要先收集统计信息)
SELECT owner,
       table_name,
       ROUND((blocks * 8) / 1024, 2) AS size_mb,      -- 分配的大小(8K块)
       ROUND((num_rows * avg_row_len / 1024 / 1024), 2) AS data_mb,  -- 实际数据大小
       ROUND((blocks * 8) / 1024 - (num_rows * avg_row_len / 1024 / 1024), 2) AS frag_mb -- 碎片大小
FROM dba_tables
WHERE blocks IS NOT NULL
  AND num_rows IS NOT NULL
  AND owner NOT IN ('SYS','SYSTEM')
  AND (blocks * 8) / 1024 - (num_rows * avg_row_len / 1024 / 1024) > 100
ORDER BY frag_mb DESC;

查询结果中size_mb与data_mb差距越大的表,碎片越严重,越值得优先处理。需要注意的是,统计信息必须是最新的,否则结果不可靠,可以先执行DBMS_STATS.GATHER_TABLE_STATS收集。对于索引碎片,可以查看dba_indexes视图的DEL_LF_ROWS与LF_ROWS的比例,被删除叶子行超过总行数的20%就建议重建索引。

如果想从操作系统层面确认,还可以查看数据文件的空闲空间分布:dba_free_space视图能看到每个表空间中有多少空闲区间,但要注意,表空间内有空闲空间不等于可以缩小数据文件,因为数据文件的收缩只能缩小到高水位线以下,而空闲区间可能分散在数据文件的尾部之外。

三、三种主流收缩方案对比与操作步骤

确定目标对象后,可以选择合适的收缩方式。Oracle提供了在线收缩、ALTER TABLE MOVE和数据泵重组三种主流方案,各有优缺点。

1. 在线收缩(ALTER TABLE SHRINK SPACE)

shrink space是最推荐的在线方式,它通过多次小事务把数据块从段尾部移动到段前部,最后降低HWM,整个过程持有的是行级锁,对业务影响很小。前提条件是表必须启用行移动:

-- 开启行移动(会更新ROWID,有基于ROWID的触发器或复制配置时需评估)
ALTER TABLE orders ENABLE ROW MOVEMENT;

-- 收缩表及其所有索引,CASCADE会一并收缩索引段
ALTER TABLE orders SHRINK SPACE CASCADE;

-- 只移动数据暂不降HWM,可分两步执行减少锁定时间
ALTER TABLE orders SHRINK SPACE COMPACT;
ALTER TABLE orders SHRINK SPACE;

-- 收缩数据文件,把空间归还给操作系统
ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/orcl/users01.dbf' RESIZE 8G;

shrink的优点是在线、锁粒度小、自动维护索引;缺点是会产生大量redo日志,对有外键关联的从表执行时可能有约束问题,且执行时间可能较长,适合业务高峰之外的低峰时段。另外,shrink之后最好重建索引统计信息:EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT','ORDERS',cascade=>TRUE);

2. ALTER TABLE MOVE重组

move会重新分配一个新的段,把数据按顺序插入,等效于一次彻底的碎片整理,速度快于shrink,但会锁表(11g之后的某些场景除外),并且move之后所有索引会变成UNUSABLE状态,必须重建:

-- 移动表到当前表空间并整理碎片
ALTER TABLE big_table MOVE;

-- 移动同时压缩(使用高级压缩选项时)
ALTER TABLE big_table MOVE COMPRESS;

-- 必须重建该表的全部索引
ALTER INDEX idx_big_table_col1 REBUILD;
ALTER INDEX idx_big_table_col2 REBUILD ONLINE;

move适合维护窗口期操作,或者表上有大量链化行需要彻底消除的场景。如果业务不能停,可以考虑12c引入的ALTER TABLE ... MOVE ONLINE,在线move期间允许DML操作。

3. 数据泵导出导入重组

对于碎片极其严重、或者需要迁移存储的历史大表,可以用expdp导出后重建表再导入,这是最彻底但也最重的方式:

-- 导出表
expdp system/pwd tables=SCOTT.HISTORY_TAB directory=DP_DIR dumpfile=hist.dmp

-- 删除原表后导入,段将从初始区间开始紧凑分配
impdp system/pwd tables=SCOTT.HISTORY_TAB directory=DP_DIR dumpfile=hist.dmp
  remap_table=HISTORY_TAB:HISTORY_TAB_NEW

数据泵方式的优点是重组彻底、可以顺便调整存储参数,缺点是需要额外磁盘空间、耗时最长,且导入期间数据不可用,一般只在表空间整体整理或数据库迁移时采用。

四、生产环境操作的注意事项

碎片整理属于高风险维护操作,正式执行前有几件事必须做好。首先,务必确认对象的依赖关系:基于ROWID的物化视图、触发器在shrink和move之后会失效或行为异常;外键关联的子表在父表shrink时可能报ORA-10635错误,需要先处理子表。操作前查询dba_dependencies和失效对象列表,做到心中有数。

其次,评估归档日志空间。shrink和move都会产生大量redo,归档目录被打满会导致数据库挂起,建议操作前清理旧归档并扩大归档空间。执行时间上优先安排在业务低峰,大表可以先执行SHRINK SPACE COMPACT分批移动数据,把最后降HWM的动作控制在最短时间窗口内完成。

最后,收缩段只是第一步,如果想把空间真正还给操作系统,还需要RESIZE数据文件。resize的大小不能低于数据文件内最后一个已用块的位置,可以先查询dba_extents中该数据文件的最大块位置来估算可收缩的下限,一次resize失败就逐步减小目标值重试。操作完成后,重新收集统计信息,并验证应用核心SQL的执行计划没有因数据分布变化而劣化,整个碎片整理工作才算完整收尾。

Oracle碎片整理表空间收缩shrink space修改时间:2026-09-12 10:10:39

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260912/55264.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。