BasicFile 到 SecureFile 的迁移必须重建 LOB 存储结构,不支持原地升级;推荐使用 DBMS_REDEFINITION 在线重定义,或 12cR2+ 的 dbms_securefile.migrate 工具,也可用 INSERT INTO…SELECT(仅限可停机场景),迁移后须验证 USER_LOBS、V$LOBSTAT 及应用连接兼容性。

BasicFile 到 SecureFile 的迁移不是“改个参数就能生效”的操作,必须重建 LOB 存储结构。直接 ALTER COLUMN … STORE AS SECUREFILE 会报错 ORA-43853,因为 Oracle 不支持原地升级 LOB 类型。
用 DBMS_REDEFINITION 在线重定义(推荐)
这是 Oracle 官方首选方案,表全程可读写,无需停机,且能自动处理索引、约束、触发器等依赖对象。
- 目标表必须与源表结构一致(含分区、列顺序、数据类型),但 LOB 列需显式声明为
STORE AS SECUREFILE - 执行前确认用户有
EXECUTE_CATALOG_ROLE和SELECT ANY TABLE权限 - 调用
DBMS_REDEFINITION.START_REDEF_TABLE时,若源表含 LONG 列,需先转为 LOB;否则会失败 - 重定义期间新插入/更新的数据会自动同步到目标表,但 DML 性能略降(因需维护两份日志)
- 完成
FINISH_REDEF_TABLE后,原表名指向新表,旧段立即标记为废弃,但空间不会自动释放——得手动DROP TABLE ... PURGE
SecureFiles 迁移工具(dbms_securefile.migrate)
Oracle 12cR2+ 提供的封装工具,本质仍是调用 DBMS_REDEFINITION,但省去手动建中间表和配置步骤。
- 需提前创建配置表(如
migration_config),填入 schema、table、column 名称及run_type(首次填"first") - 运行脚本时指定
directory_path,日志和 dump 文件将写入该目录——路径必须是数据库已注册的DIRECTORY对象,不能是任意 OS 路径 - 不支持对单个 LOB 分区单独迁移;整个表或整个 LOB 列一起走,无法细粒度控制
- 迁移后默认不启用压缩,需额外调用
ALTER TABLE ... MODIFY LOB (...) (COMPRESS HIGH)
INSERT INTO … SELECT FROM 方案(仅限低流量、可停机场景)
新建 SECUREFILE 表,再灌数据。看似简单,实则坑多。
-
INSERT /*+ APPEND */可跳过 REDO(若目标表NOLOGGING),但归档模式下仍可能触发大量归档日志——尤其当源 LOB 含大量小碎片时 - 全局索引需重建,本地索引虽自动继承,但分区键必须完全匹配,否则报
ORA-14097 - LOB 的
CHUNK、PCTVERSION、CACHE等参数若与源表不同,可能导致应用行为变化(例如某些 JDBC 驱动读取大 LOB 时超时) - 原始表的统计信息不会自动复制,迁移后务必
DBMS_STATS.GATHER_TABLE_STATS,否则执行计划可能劣化
迁移后必须验证的三个细节
很多人跑完脚本就认为完工了,但以下三点不检查,上线后大概率出问题:
- 查
USER_LOBS视图:确认SEGMENT_NAME对应的SECUREFILE值为YES,且TABLESPACE_NAME指向正确的 ASM 或本地表空间(BasicFile 用的是BASICFILE) - 查
V$LOBSTAT:观察SECUREFILE列的USED_SPACE是否与业务量匹配,避免因ENABLE STORAGE IN ROW导致意外行内存储膨胀 - 测试应用连接:某些旧版 OCI 或 ODBC 驱动不识别 SecureFile 的加密/压缩标志,会抛
ORA-22288或读取为空——需升级驱动或禁用ENCRYPT选项
NOLOGGING 改成 LOGGING,都可能让归档日志暴增三倍。别只盯着“能不能迁”,先想清楚“业务能不能扛”。


















