DBMS_FILE_TRANSFER不能直接迁移表空间,仅能复制数据文件,需配合ALTER TABLESPACE READ ONLY、CREATE TABLESPACE、RENAME FILE及ONLINE等手工步骤完成迁移。
DBMS_FILE_TRANSFER 能不能直接迁移表空间
不能。dbms_file_transfer 本身不支持“迁移表空间”这个动作,它只负责在数据库之间或本地目录间复制数据文件(datafile),且要求目标端已有对应结构(如空表空间、一致的 db_block_size、相同字节序等)。真正完成表空间迁移,必须配合 alter tablespace ... read only、create tablespace ... datafile、alter database rename file 和 alter tablespace ... online 等手工步骤。
为什么用 DBMS_FILE_TRANSFER 而不用操作系统 cp/scp
核心原因是跨平台和一致性保障:DBMS_FILE_TRANSFER 在传输过程中会校验块头信息(如 SCN、checkpoint_change#),跳过未格式化的空白块,并自动处理平台差异(如字节序转换,当源库和目标库平台不同时)。而直接用 cp 或 scp 复制文件,若源库处于 READ WRITE 状态,极易导致块断裂;即使停库复制,跨平台时还需手动调用 RMAN CONVERT,流程更重。
- 仅适用于源/目标库都开启
ARCHIVELOG模式(推荐,便于后续恢复) - 目标库必须已创建同名(或别名)的空表空间,且
DATAFILE路径需提前规划好 - 传输前源表空间必须设为
READ ONLY,否则DBMS_FILE_TRANSFER.PUT_FILE会报错ORA-19721
DBMS_FILE_TRANSFER.PUT_FILE 的关键参数和权限坑
PUT_FILE 是实际触发文件传输的函数,最容易出错的是远程数据库链接(db_link)和目录对象(DIRECTORY)配置。
-
source_directory_object必须指向源库上的有效DIRECTORY,且该目录路径下必须存在待传输的DATAFILE(如/u01/oradata/ORCL/users01.dbf) -
source_file_name是文件名(不是全路径),例如'users01.dbf';若填了路径,会报ORA-19505 -
destination_directory_object是目标库上已创建的DIRECTORY,且数据库用户对该目录有READ和WRITE权限(通过GRANT READ,WRITE ON DIRECTORY ...授予) - 必须确保源库用户对
DBMS_FILE_TRANSFER有执行权限(GRANT EXECUTE ON SYS.DBMS_FILE_TRANSFER TO user_name) - 远程
db_link必须使用公共同义词或完整命名(如target_db@my_dblink),且目标库监听正常、TNS 配置无误
迁移后如何安全地切换表空间上线
文件复制完成后,不能直接 ALTER TABLESPACE ... ONLINE —— 因为数据文件头中的 checkpoint_change# 与控制文件不一致,会报 ORA-01122 / ORA-01110。必须先做恢复(RECOVER)或重命名(RENAME)。
- 如果源表空间是
READ ONLY后复制的,且目标库没有归档日志依赖,可直接用ALTER DATABASE RENAME FILE更新控制文件记录(注意:路径必须与destination_directory_object下实际写入路径一致) - 如果源库在复制期间仍写归档(比如误设为
READ WRITE),则必须用RECOVER TABLESPACE应用归档日志,直到 SCN 对齐 - 确认无误后执行
ALTER TABLESPACE users ONLINE;若报ORA-01157,说明控制文件里还记着旧路径,需先RENAME再ONLINE
整个过程最易被忽略的是:目标库的 DB_BLOCK_SIZE 必须与源库完全一致,哪怕只差 1 字节,ALTER DATABASE RENAME FILE 后也会在第一次访问时触发 ORA-01219 或数据块校验失败。










