2.8 DBMS_FILE_TRANSFER的可选性

从Oracle 10g开始,Oracle提供了DBMS_FILE_TRANSFER程序包,可以很方便地在本地数据库和远程数据库,ASM和文件系统间传输数据库文件。

有了DBMS_FILE_TRANSFER,数据库文件的传输就方便了许多,尤其是在传输基于ASM存储的数据文件时,不再局限于利用RMAN来进行传输,为我们提供了更多的选择。

注意:DBMS_FILE_TRANSFER具备一定的限制,单个数据库文件必须是512字节的整数倍并且文件大小必须小于或者等于 2TB们提供了多一个选择和,但是这基本上算不上什么弱点,我们的绝大多数需求都可以被满足。

DBMS_FILE_TRANSFER 包一共包含了 3 个存储过程,分别提供本机之间拷贝(COPY_FILE)、本机从远程主机获取(GET_FILE)以及本机上传至远程主机(PUT_FILE)3 种传输数据库文件的功能。

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

以上过程的参数中,除了文件名称外,最关键的是DIRECTORY目录参数,这个目录需要预先设定,并且要求传输用户对相应的目录具有读或者写的权限。

看以下测试,首先通过asmcmd在DATADG下创建一个asmbk目录:

$ export ORACLE_SID=+ASM1

$ asmcmd

ASMCMD> ls

DATADG/

FSHDG/

ASMCMD> cd DATADG

ASMCMD> mkdir asmbk

然后在数据库内部创建两个DIRECTORY:

SQL> create directory ASMBK as '+DATADG/asmbk';

Directory created.

SQL> create directory OBASE as '/opt/oracle';

Directory created.

SQL> select * from dba_directories;

OWNER DIRECTORY_NAME DIRECTORY_PATH

---------- ---------------------------- ---------------------------------------------

SYS  ASMBK      +DATADG/asmbk

SYS  OBASE      /opt/oracle

现在DBMS_FILE_TRANSFER就可以大显身手,快速地帮助我们解决文件传输的问题:

SQL> exec dbms_file_transfer.copy_file('OBASE','trans.dbf','ASMBK','trans.dbf');

PL/SQL procedure successfully completed.

看一下ASM磁盘组上的内容,实际上文件的位置是在DATAFILE下,asmbk下存放的是一个别名:

ASMCMD> ls

DATADG/

FSHDG/

ASMCMD> cd DATADG

ASMCMD> cd asmbk

ASMCMD> ls

trans.dbf

ASMCMD> ls -l

Type Redund Striped Time  Sys Name

N trans.dbf =>

+DATADG/RAC/DATAFILE/COPY_FILE.271.728582605

DBMS_FILE_TRANSFER包更强大的功能是基于网络的远程PUT_FILE和COPY_FILE功能,这两个功能通过DB Link实现。以下是一个简单测试。

首先在远程数据库创建测试用户及目录,并进行授权:

SQL> create user eygle identified by eygle;

SQL> grant connect,resource to eygle;

SQL> create or replace directory OBASE as '/opt/oracle';

SQL> grant read,write on directory OBASE to eygle;

SQL> grant execute on dbms_file_transfer to eygle;

接下来在本地数据库配置 tnsnames.ora文件,并创建DB Link:

SMSDBN =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.9.108)(PORT = 1521))

(CONNECT_DATA =

(SERVER = DEDICATED)

(SERVICE_NAME = smsdbn)

)

)

SQL> create database link smsdbn connect to eygle identified by eygle using 'smsdbn';

Database link created.

SQL> select * from dual@smsdbn;

D

-

X

接下来就可以通过DB Link进行远程的文件操作了,PUT_FILE可以将文件传输至远程主机:

SQL> exec dbms_file_transfer.put_file(

'ASMBK','trans.dbf','OBASE','remote_trans.dbf','SMSDBN');

PL/SQL procedure successfully completed.

在远程节点可以立刻检查到这个文件的存在:

SQL> ! ls -al remote_trans.dbf

-rw-r----- 1 oracle dba 10493952 Sep 1 17:16 remote_trans.dbf

进一步的,可以将远程文件读取到本地:

SQL> exec dbms_file_transfer.get_file(

'OBASE','remote_trans.dbf','SMSDBN','ASMBK','local_trans.dbf');

PL/SQL procedure successfully completed.

本地ASM存储中,马上获得了这个文件:

$ export ORACLE_SID=+ASM1

$ asmcmd

ASMCMD> cd DATADG/ASMBK

ASMCMD> ls

local_trans.dbf

trans.dbf

ASMCMD> ls -l

Type Redund Striped Time Sys Name

N local_trans.dbf =>

+DATADG/RAC/DATAFILE/FILE_TRANSFER.272.728586765

N trans.dbf =>

+DATADG/RAC/DATAFILE/COPY_FILE.271.728582605

而进一步地,将表空间置于热备模式下,可以通过 DBMS_FILE_TRANSFER 包将数据库热备到远程主机,甚至可以基于次来创建远程的DataGuard数据库,有时在数据库巨大,备份恢复空间不足时,通过这种方式进行数据传输与备库创建未尝不是一种妙解:

SQL> alter tablespace system begin backup;

Tablespace altered.

SQL> create or replace directory odata as '+DATADG/rac/datafile/';

Directory created.

SQL> exec dbms_file_transfer.put_file(

'ODATA','system.259.722961061','OBASE','system01.dbf','SMSDBN');

PL/SQL procedure successfully completed.

SQL> alter tablespace system end backup;

Tablespace altered.

DBMS_FILE_TRANSFER 为我们提供了多一个选择和灵活性,很多时候,Oracle 的一个小小的增强如果能够恰如其份的利用,就能够发挥巨大的优势。了解了Oracle的种种可能之后,我们才能够灵活运用,如臂使指。