ORA-10636报错直接原因是表未启用行移动(ALTER TABLE ... ENABLE ROW MOVEMENT),SHRINK SPACE依赖该特性物理重排数据;启用后需注意undo/redo增加及索引可能失效需手动REBUILD。
Oracle SHRINK SPACE 为什么经常报错 ORA-10636
直接原因是表没开行移动(row movement),shrink space 依赖这个特性来物理重排行数据。不启用就报 ora-10636: row movement is not enabled,不是权限或空间不足的问题。
实操建议:
- 先执行
ALTER TABLE table_name ENABLE ROW MOVEMENT,再 shrink - 注意:启用了 row movement 后,
UPDATE语句可能触发更多 undo 和 redo,高并发更新表时慎开 - 索引不会自动重建,shrink 后如果发现查询变慢,大概率是索引失效,得手动
ALTER INDEX idx_name REBUILD
SHRINK SPACE 和 DEALLOCATE UNUSED 的区别在哪
两者都释放空间,但作用层级和效果完全不同:DEALLOCATE UNUSED 只把高水位线(HWM)以上的空闲区还给表空间,不移动数据、不降低 HWM;SHRINK SPACE 会把 HWM 往下压,真正回收碎片并允许后续 INSERT 复用空闲块。
常见错误现象:执行了 DEALLOCATE UNUSED,DBA_SEGMENTS 里 BYTES 没变,误以为没生效——其实它只影响 DBA_EXTENTS 中的 extent 分配,不压缩段内部。
使用场景:
- 快速释放刚 TRUNCATE 或大量 DELETE 后的高位空闲区 → 用
DEALLOCATE UNUSED - 长期运行、反复 DELETE/INSERT 导致块内碎片严重、全表扫描变慢 → 必须用
SHRINK SPACE -
SHRINK SPACE COMPACT可以分两步:先 compact(只整理不降 HWM),再 shrink space(真正释放),适合业务不能停的窗口
哪些对象不支持 SHRINK SPACE
不是所有表都能 shrink。Oracle 明确限制以下情况会直接报错 ORA-10637 或 ORA-10638:
- 堆组织表(heap table)以外的类型:比如索引组织表(IOT)、外部表、临时表、物化视图日志表
- 含 LONG 类型列的表(哪怕该列为空也不行)
- 启用了 Flashback Data Archive(FDA)的表
- 分区表只能对单个分区 shrink,语法是
ALTER TABLE t SHRINK SPACE PARTITION p1,不能直接 shrink 整个分区表
容易踩的坑:DBA 习惯性对所有大表批量执行 shrink 脚本,遇到 IOT 表就中断,还可能误删 FDA 表的归档配置。
收缩后空间没立刻返还给操作系统?
这是正常现象。Oracle 的 SHRINK SPACE 只在数据文件内重新组织块,并不会自动缩小数据文件大小。DBA_DATA_FILES 的 BYTES 不变,DBA_FREE_SPACE 里对应表空间的空闲字节数会增加。
想真正缩文件,得额外执行:
-
ALTER DATABASE DATAFILE '/path/to/file.dbf' RESIZE N G;(需确保 resize 值 ≥ 当前已分配的 high water mark) - 先查安全下限:
SELECT bytes FROM dba_segments WHERE segment_name = 'YOUR_TABLE';再加点余量,避免 resize 过头报错 - ASM 环境下不能直接 resize,得用
ALTER DISKGROUP ... SHRINK SPACE配合 rebalance
最常被忽略的是:shrink 表之后忘记检查对应表空间是否启用了 AUTOEXTEND,结果空闲空间又被自动填满,白忙一场。










