shrink space仅支持堆组织表(heap table),不支持iot、外部表、临时表、物化视图日志表、含long列或启用flashback data archive的表;分区表须指定分区,且必须位于assm表空间并已启用row movement。

SHRINK SPACE 不能直接回收整个表空间,只能收缩单个段(如表、索引)或临时表空间;想释放数据文件物理大小,必须额外执行 RESIZE 或手动迁移。
哪些对象能用 SHRINK SPACE?
不是所有对象都支持——硬性限制会直接报 ORA-10637 或 ORA-10638:
- 仅限堆组织表(
HEAP TABLE),不支持索引组织表(IOT)、外部表、临时表、物化视图日志表 - 含
LONG类型列的表,哪怕该列全为空也不行 - 启用了
Flashback Data Archive的表禁止 shrink - 分区表只能对单个分区操作:
ALTER TABLE t SHRINK SPACE PARTITION p1,不能直接 shrink 整个表 - 必须位于自动段空间管理(
ASSM)的表空间中;查证命令:SELECT segment_space_management FROM dba_tablespaces WHERE tablespace_name = 'YOUR_TS'
为什么执行 SHRINK SPACE 总报 ORA-10636?
这不是权限或空间不足的问题,而是表没开行移动:
- 必须先执行:
ALTER TABLE table_name ENABLE ROW MOVEMENT - 启用后,
UPDATE可能触发更多UNDO和REDO,高并发更新场景慎开 - 行移动开启后,基于
ROWID的触发器需手动禁用(DISABLE),否则 shrink 会失败 - 注意:
ENABLE ROW MOVEMENT是 DDL 操作,会隐式提交,不可回滚
SHRINK SPACE 和 DEALLOCATE UNUSED 到底差在哪?
两者都“释放空间”,但作用层级和效果完全不同:
-
DEALLOCATE UNUSED只把高水位线(HWM)以上的空闲区还给表空间,不移动数据、不降低HWM;执行后DBA_SEGMENTS.BYTES不变是正常现象 -
SHRINK SPACE会物理重排数据、下压HWM,真正回收块内碎片,让后续INSERT能复用空闲块 - 刚做完大量
DELETE或TRUNCATE→ 优先用DEALLOCATE UNUSED快速清理高位空闲区 - 长期运行、反复增删导致扫描变慢 → 必须用
SHRINK SPACE整理内部碎片 - 想分步操作避免长锁:先
SHRINK SPACE COMPACT(只整理不降 HWM),再SHRINK SPACE(真正释放)
收缩后空间没从操作系统消失?这是对的
SHRINK SPACE 只在数据文件内重新组织块,不会自动缩小文件物理大小:
-
DBA_DATA_FILES.BYTES不变,DBA_FREE_SPACE中空闲字节数会增加 - 要真正缩文件,得额外执行:
ALTER DATABASE DATAFILE '/path/to/file.dbf' RESIZE 2G - 但注意:
RESIZE不能小于当前已用空间上限,否则报ORA-03297;建议先查SELECT MAX(block_id + blocks - 1) * block_size FROM dba_extents WHERE file_id = N - 临时表空间可用
ALTER TABLESPACE temp SHRINK SPACE或SHRINK TEMPFILE直接生效,但普通表空间不行











