数据库管道(PIPE)是一种多SESSION间传递消息的机制,可以通过包DBMS_PIPE进行消息的发布和接收,主要用作外部服务消息接口,也可以用于多个独立进程之间的通讯。在Oracle EBS环境中,MRP的计算过程就用到了数据库管道技术。RMAN也可以通过数据库管道进行操作,通过管道接口,可以直接使用PL/SQL来操作RMAN行为并获得输出结果。通过数据库管道技术,可以设计出基于RMAN的第三方备份、恢复管理系统。

用于RMAN的必须是私有管道,这是出于安全考虑。私有管道有如下限制:

  • 各SESSION用户(USERID)必须和管道创建者一致
  • 存储过程的执行权限和管道创建者(USERID)一致
  • 用户必须通过SYSDBA角色连接到数据库

RMAN拥有两个私有管道,一个用于接收,一个用于发布。在启动RMAN时可以通过PIPE参数指定管道名称(此处为ABC),比如:

[oradba@localhost ~]$ rman PIPE ABC TARGET / TIMEOUT 60
Recovery Manager: Release 11.2.0.1.0 - Production on Sun Mar 21 16:43:28 2010
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

该进程会等待DBMS_PIPE传入指令,如果60秒后无任何指令传入,则自动退出。若不加TIMEOUT参数,则RMAN会一直等待指令传入。

RMAN会自动打开两个私有管道,ORA$RMAN_ABC_IN和ORA$RMAN_ABC_OUT,前者用于接收消息,后者用于发布消息,消息类型都是VARCHAR2。第一次启用时,RMAN会自动初始化这两个管道,如果需要在启动RMAN之前就存入指令,则需要首先手工使用DBMS_PIPE.CREATE_PIPE创建管道。

l_status := dbms_pipe.create_pipe(pipename =>l_pipename,private => true);

private 参数必须为true,否则默认会创建公共管道,无法用于RMAN。

发布指令到RMAN:

DECLARE
  l_status INT;
BEGIN
  dbms_pipe.pack_message('show all;');
  l_status    :=dbms_pipe.send_message('ORA$RMAN_ABC_IN');
  IF l_status <> 0 THEN
    RAISE_APPLICATION_ERROR(-20010, 'Error while sending.  Status = ' || l_status);
  END IF;
END;

打印RMAN输出结果:

DECLARE
  l_message VARCHAR2(1000);
  l_status  INT DEFAULT 0;
BEGIN
  --  l_status := dbms_pipe.create_pipe(pipename =>l_pipename,private => true);
  WHILE (l_status = 0 )
  LOOP
    l_status    :=dbms_pipe.receive_message(pipename =>'ORA$RMAN_ABC_OUT',timeout=>3);
    IF l_status <> 0 THEN
      EXIT;
    END IF;
    dbms_pipe.unpack_message(l_message);
    dbms_output.put_line('received message:' || l_message);
  END LOOP;
END;

测试环境为:

SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 21 18:49:23 2010

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options