背景
在 Oracle 数据库的日常运维中,除了 RMAN 、 expdp 等常见备份手段外, DBMS_FILE_TRANSFER 包也是一个不容忽视的工具。它提供了 COPY_FILE 、 GET_FILE 、 PUT_FILE 三个过程,可以在数据库之间、或者同一数据库的不同目录之间传输数据文件( datafile )。利用这一特性,我们可以把源库的数据文件直接 " 推送 " 或 " 拉取 " 到远端服务器,实现一份远程备份。
PUT_FILE 还是 GET_FILE ?
DBMS_FILE_TRANSFER 既支持 PUT_FILE (源端主动推送到远端),也支持 GET_FILE (远端主动从源端拉取),两种方式理论上都可以用来做备份,但需要结合其使用前提来权衡:
由于 DBMS_FILE_TRANSFER 要求数据库处于打开状态才能使用,被传输的数据文件对应的表空间必须先满足以下条件之一:
将表空间置于热备状态( BEGIN BACKUP 模式);
将表空间或整个数据库置于只读状态。
如果选择 GET_FILE 方式,备份动作发起端在远端站点。为了拿到一份一致性完好的文件,远端要么能控制源库表空间进入只读(对系统可用性影响太大),要么仍需回到源库执行 ALTER TABLESPACE ... BEGIN BACKUP ,操作被拆散在两个站点上,反而更繁琐。
因此综合来看,直接在源数据库端使用 DBMS_FILE_TRANSFER.PUT_FILE 更为方便:只需在源端将表空间置于热备状态,一条命令即可把数据文件推送到远端目录,操作集中、对系统可用性的影响也最小。
使用前提与限制
如果只是把文件传到远端留存一份备份,限制其实并不多,归纳起来有以下几点:
数据库版本:源数据库和目标服务器上的数据库版本都需要在 10g 以上;
数据库状态:两端的数据库都必须处于打开状态(数据库链要走通);
数据库链:当前用户需要配置一条指向远端数据库的 dblink ;
远端权限: dblink 所连接的远端用户可以访问备份目录对应的 DIRECTORY 对象,并且拥有对该目录的写权限;
本地权限:当前用户拥有 DBMS_FILE_TRANSFER 包的执行权限,并且拥有数据文件所在目录对应的 DIRECTORY 对象的访问权限。
DBMS_FILE_TRANSFER 包的结构
先看一下这个包里三个过程的定义:
SQL> desc dbms_file_transfer PROCEDURE COPY_FILE Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- SOURCE_DIRECTORY_OBJECT VARCHAR2 IN SOURCE_FILE_NAME VARCHAR2 IN DESTINATION_DIRECTORY_OBJECT VARCHAR2 IN DESTINATION_FILE_NAME VARCHAR2 IN PROCEDURE GET_FILE Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- SOURCE_DIRECTORY_OBJECT VARCHAR2 IN SOURCE_FILE_NAME VARCHAR2 IN SOURCE_DATABASE VARCHAR2 IN DESTINATION_DIRECTORY_OBJECT VARCHAR2 IN DESTINATION_FILE_NAME VARCHAR2 IN PROCEDURE PUT_FILE Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- SOURCE_DIRECTORY_OBJECT VARCHAR2 IN SOURCE_FILE_NAME VARCHAR2 IN DESTINATION_DIRECTORY_OBJECT VARCHAR2 IN DESTINATION_FILE_NAME VARCHAR2 IN DESTINATION_DATABASE VARCHAR2 IN
三者的区别 如下 :
COPY_FILE : 同一数据库内目录间复制 , 不涉及数据库链
GET_FILE : 从远端数据库拉取文件到本地 , 需要指定 SOURCE_DATABASE (源端 dblink )
PUT_FILE : 将本地文件推送到远端数据库 , 需要指定 DESTINATION_DATABASE (目标端 dblink )
实测步骤
下面以 PUT_FILE 为例,演示将源库 USERS 表空间的数据文件备份到远端服务器的完整过程。
1. 目标端:创建备份目录对应的 DIRECTORY
在目标数据库上,创建接收数据文件的路径对应的 directory :
SQL> create directory d_dest as '/home/oracle';
Directory created.
2. 源端:创建数据文件路径对应的 DIRECTORY
在源数据库上,创建被传输数据文件所在路径对应的 directory :
SQL> create directory d_source as '/oracle/app/nb/';
Directory created.
3. 源端:创建访问目标端的 dblink
create public database link test_dblink
connect to test123 identified by oracle
using '(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = 192.168.238.136)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = rac)))';
其中 test123 用户就是远端具备 d_dest 目录读写权限的用户。
4. 将表空间置于热备模式
SQL> alter tablespace users begin backup;
5. 开始传输
SQL> exec dbms_file_transfer.put_file('d_source', 'users01.dbf', 'd_dest', 'users01.dbf', 'test_dblink')
PL/SQL procedure successfully completed.
6. 结束热备
传输完成后,务必记得结束热备状态:
SQL> alter tablespace users end backup;
DBMS_FILE_TRANSFER.PUT_FILE 提供了一种不依赖 RMAN 的轻量级远程文件备份方式,操作集中在一个会话里即可完成;
备份前必须让表空间进入热备或只读状态,否则备份出的数据文件存在分裂块( fractured block )风险,恢复时可能导致文件不一致;
BEGIN BACKUP 期间数据库会多产生 redo ,操作完成后一定要及时 END BACKUP ;
传输的目标文件不能覆盖远端已存在的同名文件,重复执行前需要先清理远端目录;
该方式备份的是数据文件本身,恢复时还需要配合归档日志 / 控制文件才能完成完整恢复,建议作为常规备份策略的补充而非替代。
对于跨机房的文件级备份、以及向备库 / 测试环境克隆数据文件这类场景, DBMS_FILE_TRANSFER 是一个非常顺手的选择。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013625/viewspace-3181338/ ,如需转载,请注明出处,否则将追究法律责任。