securefiles 省空间靠默认禁用 in row、废除 pctversion 机制及可选的 compress/deduplicate;basicfiles 因 in row 和 pctversion 导致双重占用与旧版本堆积,空间虚高;迁移须用 move,且依赖 assm 与正确 db_securefile 设置。
securefiles 省空间不是靠“自动压缩”,而是靠三件事:默认禁用 in row、废掉 pctversion 旧版本堆积机制、以及可选的 compress 和 deduplicate——但后两者必须手动启用且效果高度依赖数据特征。
BasicFiles 的双重占用和旧版本失控是空间膨胀主因
BasicFiles 默认允许小 LOB(≤3964 字节)存进表块(IN_ROW = YES),但只要发生一次 UPDATE,哪怕只改了其他字段,Oracle 就可能把原在行内的 LOB “踢出去”到独立段,且不回收原行内空间。结果就是同一份数据同时占着表块 + LOB 段。
更严重的是 PCTVERSION(默认 10):每次更新都保留旧版本块,这些块不会被常规 DELETE 或 COMMIT 清理,长期积累成“幽灵空间”。DBA_SEGMENTS.BYTES 显示几百 GB,实际有效数据可能只有几 GB。
- 查当前状态:
SELECT column_name, in_row, pctversion, chunk FROM dba_lobs WHERE table_name = 'YOUR_TABLE' - 若
in_row = YES且pctversion = 10,基本可以断定空间虚高来自这里 - SecureFiles 默认
IN_ROW = NO,且用RETENTION替代PCTVERSION,版本清理可控
COMPRESS 和 DEDUPLICATE 不是开就生效,得看数据是不是“可压可去”
COMPRESS HIGH 对纯文本、XML、日志类重复结构有效;对 AES 加密后的二进制、JPEG 头部微变的图片,压缩率接近 0。它按 LOB 块(chunk)压缩,不是整列扫描。
DEDUPLICATE 是全值哈希比对:两个 10MB 的 CLOB,只要差 1 字节,就不会去重。它不支持跨列、跨表,仅限同一 SecureFile LOB 列内完全相同的值之间生效。
- 启用方式必须写在
MOVE或建表语句里:STORE AS SECUREFILE (COMPRESS HIGH DEDUPLICATE) - 迁移后不能直接信
DBA_SEGMENTS.BYTES——它显示分配空间,不是真实占用 - 查真实空间用:
DBMS_SPACE.SPACE_USAGE,重点看USED_BYTES
MOVE 迁移是唯一路径,但 COMPRESS/DEDUPLICATE 会显著拖慢过程
别指望 ALTER TABLE MODIFY LOB ... STORE AS SECUREFILE 能升级存量数据——它只影响新插入的 LOB,老数据仍在 BasicFile 段里躺着,空间和性能问题照旧。
真正迁移必须用 ALTER TABLE ... MOVE LOB (...) STORE AS SECUREFILE,但这个操作:
- 锁全表,DML 全部阻塞,必须安排停写窗口
-
COMPRESS和DEDUPLICATE会让 MOVE 时间翻倍甚至更多,建议先在测试环境压测 - MOVE 后原 BasicFile 段(
SYS_LOB%)不会自动删除,得手动确认并DROP SEGMENT - LOB 索引不支持
REBUILD ONLINE,必须离线重建
最常被忽略的一点:SecureFiles 强制依赖 ASSM 表空间,且 db_securefile 参数不能是 NEVER。即使建表时写了 SECUREFILE,如果表空间不是 ASSM 或参数设错,Oracle 会静默退化为 BasicFile——查 DBA_LOBS.SECUREFILE 才算数,光看 DDL 不顶用。











