您的位置:首页 > 数据库 > Oracle

oracle 11g PL/SQL Programming学习十三

2013-06-14 00:36 525 查看
----------------------------------------------------------------------------

-----------------PL/SQL学习笔记系列 By Cryking-----------------

------------------------转载请注明出处,谢谢!------------------------


第13章 外部存储(External Procedures)

一般日常的外部操作都通过外部存储处理.这样数据库可通过PL/SQL来和外部应用进行交流.

开发人员可能想数据库少一些逻辑编程,所以外部存储是常用的选择.

这对密集型计算程序是理想的,此时的外部存储提供了一个外部数据资源到数据库的接口.

不像单独的Oracle Prc*C程序,外部存储能被PL/SQL调用.

在本章,你将会用到c共享库和J***A类库.

1.外部存储架构定义

Oracle为外部存储构建了一个可扩展的架构.

它能非常灵活的支持任何能被C调用的编程语言.

例如,你可以在C中调用C++的程序(通过extern命令),尽管这样,通过外部程序回调到数据库时仍需要OCI的支持.

OCI支持C,C++,COBOL,FORTRAN,PL/1,Visual Basic,Perl,PHP和Java.

无论你选择了哪种语言来执行,必须支持建立一个共享库,也就是DLL.

J***A的共享库称为单元库.当你从PL/SQL访问共享库时,库被作为外部存储动态装载到内存.

缺省情况下,每一个远程存储调用使用分散的、专有的extproc代理去访问共享库.

你也可以通过Oracle异构服务(ORACLE HS)选择配置一个多线程代理.如果这样,你可以在任何数据库会话之间共享extproc代理.

外部存储使用PL/SQL定义库来在PL/SQL运行时引擎和共享库之间交换数据.

PL/SQL定义库定义了指定的外部调用,并且映射PL/SQL数据类型到本地语言的数据类型.

2.定义extproc oracle网络服务配置

外部存储使用oracle网络服务来fork或链接到extproc代理.

extproc代理可以是默认的独立单元或者一个多线程的extproc代理.

麻烦的是,配置你的listener.ora和tnsnames.ora将是一个手动的过程.

使用NETCA建立标准的监听并不提供一个完整的extproc代理监听器.

你必须为外部存储建立一个专用的监听.

标准的listener.ora文件包含两块内容:LISTENER以及SID_LIST_LISTENER.

LISTENER描述了一个地址列表或一组地址列表.

地址由一个协议和一个key值组成,或者一个协议、主机名、端口号组成.

11g标准的LISTENER格式块如下:

LISTENER =
 (DESCRIPTION_LIST =
  (DESCRIPTION =
   (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = IPC)
          (KEY = EXTPROC1521)
    )
   )
   (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)
          (HOST = <host_name>.<domain_name>)
          (PORT = 1521)
    )
   )
  )
)


标准的listener.ora文件不能支持extproc代理,因为它有两个不同协议的ADDRESS_LIST.

SID_LIST_LISTENER部分包含SID的描述.

标准的SID_LIST_LISTENER块包含SID_NAME,ORACLE_HOME和PROGRAM预定义参数.

标准的SID_LIST_LISTENER块格式如下:

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

(SID_NAME = PLSExtProc)

(ORACLE_HOME = <oracle_home_directory)

(PROGRAM = extproc)

)

)

SID_NAME和PROGRAM参数在这里可以用来支持extproc代理.

标准listener.ora文件和标准tnsnames.ora文件配合,一起为oracle网络服务所使用.

标准的tnsnames.ora文件提供两个服务名:

一个是代码,用来映射数据库的标准监听.

另一个是EXTPROC_CONNECTION_DATA,用来映射extproc代理.

标准的tnsnames.ora格式如下:

CODE =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)

(HOST = <host_name>.<domain_name>)

(PORT = 1521)

)

(CONNECT_DATA =

(SERVER = DEDICATED)

(SERVICE_NAME = <database_sid>)

)

)

EXTPROC_CONNECTION_DATA =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = IPC)

(KEY = EXTPROC)

)

)

(CONNECT_DATA =

(SID = PLSExtProc)

(PRESENTATION = RO)

)

)

tnsnames.ora服务名提供了一个使用户和程序连接到监听的连接别名.

通过tnsnames.ora中的ADDRESS参数来解释连接请求,然后使用CONNECTION_DATA参数来连接到数据库或代理.

extproc代理不仅仅是oracle 11g支持的唯一代理.

你可以定义任意数量的可在oracle和其他数据库之间通信的异构服务.

可通过TNSPING 工具来测试extproc是否正常解释.

如果正常,你使用TNSPING得到的结果可能如下:

TNS Ping Utility for Linux: Version 11.1.0.6.0 - Production on 22-AUG-2007

Copyright (c) 1997, 2007, Oracle. All rights reserved.

Used parameter files:

/u03/oracle/11g/11.1.0/network/admin/sqlnet.ora

Used TNSNAMES adapter to resolve the alias

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL =

IPC)(KEY = EXTPROC1521))) (CONNECT_DATA = (SID = PLSExtProc) (PRESENTATION = RO)))

OK (0 msec)

配置支持extproc代理的监听:

服务器监听文件listener.ora配置

LISTENER =
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))
)
)

SID_LIST_LISTENER=
  (SID_LIST=
    (SID_DESC=
      (SID_NAME=cry)
      (ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1)
    )
  )

CALLOUT_LISTENER=
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=IPC)(KEY=extproc))
  )

SID_LIST_CALLOUT_LISTENER=
  (SID_LIST=
    (SID_DESC=
      (SID_NAME=PLSExtProc)
      (ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1)
      (PROGRAM=extproc)
      (ENV="EXTPROC_DLLS=ONLY:
      /u01/app/oracle/product/11.2.0/dbhome_1/customlib/writestr1.so,
      LD_LIBRARY_PATH=/u01/app/oracle/product/11.2.0/dbhome_1/lib")
    )
  )

ADR_BASE_LISTENER = /u01/app/oracle


服务器文件tnsnames.ora配置

cry=
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = cry)
    )
  )

EXTPROC_CONNECTION_DATA=
  (DESCRIPTION=
   (ADDRESS=(PROTOCOL=IPC)(KEY=extproc))
  (CONNECT_DATA=
    (SID=PLSExtProc)
    (PRESENTATION=RO)
  )
 )


然后执行以下命令(LINUX平台)进行验证:

[oracle@oracleserver ~]$ lsnrctl stop

LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 05-JAN-2013 04:15:05

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))

The command completed successfully

[oracle@oracleserver ~]$ lsnrctl start LISTENER

LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 05-JAN-2013 04:15:20

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

Starting /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 11.2.0.1.0 - Production

System parameter file is /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora

Log messages written to /u01/app/oracle/diag/tnslsnr/oracleserver/listener/alert/log.xml

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))

STATUS of the LISTENER

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

Alias LISTENER

Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production

Start Date 05-JAN-2013 04:15:20

Uptime 0 days 0 hr. 0 min. 0 sec

Trace Level off

Security ON: Local OS Authentication

SNMP OFF

Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora

Listener Log File /u01/app/oracle/diag/tnslsnr/oracleserver/listener/alert/log.xml

Listening Endpoints Summary...

(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))

The listener supports no services

The command completed successfully

[oracle@oracleserver ~]$ lsnrctl start CALLOUT_LISTENER

LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 05-JAN-2013 04:15:30

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

Starting /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 11.2.0.1.0 - Production

System parameter file is /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora

Log messages written to /u01/app/oracle/diag/tnslsnr/oracleserver/callout_listener/alert/log.xml

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=extproc)))

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=extproc)))

STATUS of the LISTENER

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

Alias CALLOUT_LISTENER

Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production

Start Date 05-JAN-2013 04:15:30

Uptime 0 days 0 hr. 0 min. 0 sec

Trace Level off

Security ON: Local OS Authentication

SNMP OFF

Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora

Listener Log File /u01/app/oracle/diag/tnslsnr/oracleserver/callout_listener/alert/log.xml

Listening Endpoints Summary...

(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=extproc)))

Services Summary...

Service "PLSExtProc" has 1 instance(s).

Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...

The command completed successfully

[oracle@oracleserver ~]$ lsnrctl status listener

LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 05-JAN-2013 04:39:43

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))

STATUS of the LISTENER

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

Alias LISTENER

Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production

Start Date 05-JAN-2013 04:35:08

Uptime 0 days 0 hr. 4 min. 35 sec

Trace Level off

Security ON: Local OS Authentication

SNMP OFF

Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora

Listener Log File /u01/app/oracle/diag/tnslsnr/oracleserver/listener/alert/log.xml

Listening Endpoints Summary...

(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))

Services Summary...

Service "cry" has 1 instance(s).

Instance "cry", status READY, has 1 handler(s) for this service...

Service "cryXDB" has 1 instance(s).

Instance "cry", status READY, has 1 handler(s) for this service...

The command completed successfully

[oracle@oracleserver ~]$

[oracle@oracleserver ~]$ lsnrctl status CALLOUT_LISTENER

LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 05-JAN-2013 04:40:11

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=extproc)))

STATUS of the LISTENER

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

Alias CALLOUT_LISTENER

Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production

Start Date 05-JAN-2013 04:15:30

Uptime 0 days 0 hr. 24 min. 40 sec

Trace Level off

Security ON: Local OS Authentication

SNMP OFF

Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora

Listener Log File /u01/app/oracle/diag/tnslsnr/oracleserver/callout_listener/alert/log.xml

Listening Endpoints Summary...

(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=extproc)))

Services Summary...

Service "PLSExtProc" has 1 instance(s).

Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...

The command completed successfully

[oracle@oracleserver ~]$ tnsping EXTPROC_CONNECTION_DATA

TNS Ping Utility for Linux: Version 11.2.0.1.0 - Production on 05-JAN-2013 04:50:37

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

Used parameter files:

/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/sqlnet.ora

Used TNSNAMES adapter to resolve the alias

Attempting to contact (DESCRIPTION= (ADDRESS=(PROTOCOL=IPC)(KEY=extproc)) (CONNECT_DATA= (SID=PLSExtProc) (PRESENTATION=RO)))

OK (10 msec)

由上可知,我们已经配置了2个监听服务(CALLOUT_LISTENER和listener),并已成功启动.

其中CALLOUT_LISTENER是用来监听extproc代理的.

如果此时您使用该连接名登录,将会获得ORA-28547错误,如下:

[oracle@oracleserver ~]$ sqlplus scott/tiger@EXTPROC_CONNECTION_DATA

SQL*Plus: Release 11.2.0.1.0 Production on Sat Jan 5 04:52:59 2013

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

ERROR:

ORA-28547: connection to server failed, probable Oracle Net admin error

这个错误是正常的,说明连接已被extproc代理拒绝.

3.定义多线程的外部存储代理

配置异构的多线程代理是一个复杂的过程.

不过它可以让你在多个数据库会话间共享单个的extproc代理,这样可以减少资源使用.

外部存储缺省情况下每个调用将fork一个新的extproc代理.这个缺省的行为将会频繁地消耗很多资源.

当你有很多使用外部存储的会话时,你应该使用一个多线程的extproc代理.

在配置多线程的外部存储代理前,这里有3点应当注意:

1.外部库必须是线程安全的.

2.代理进程、数据库服务器、监听进程必须在同一台主机

3.代理进程和外部存储调用必须运行在同一个数据库实例上.



使用agtctl配置多线程extproc代理

agtctl是一个代理控制工具,用来启动和管理会话.它在$ORACLE_HOME/bin目录下.

agtctl没有GUI界面,它要么运行在单行命令模式,要么运行在agtctl shell模式.

agtctl有8个命令:

1.delete 作用:删除一个agent_sid实体

2.exit 作用:推出agtctl

3.help 作用:显示可用的命令

4.set 作用:设置参数值

5.show 作用:显示参数值

6.shutdown 作用:关闭一个agent_sid多线程代理

7.startup 作用:启动一个agent_sid多线程代理

8.unset 作用:取消一个参数值的设置

相关的初始化参数值:

参数:listener_address

缺省值:

(ADDRESS_LIST =

(ADDRESS =(PROTOCOL = IPC)(KEY = PNPKEY))

(ADDRESS =(PROTOCOL = IPC)(KEY= <oracle_sid>)

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

参数:max_dispatchers

缺省值:1

参数:max_sessions

缺省值:5

参数:max_task_threads

缺省值:2

参数:shutdown_address

缺省值:

(ADDRESS_LIST =

(ADDRESS =(PROTOCOL = IPC)(KEY = extproc)))

tcp_dispatchers

缺省值:0

下面将演示使用agtctl工具配置extproc多线程代理(需要按上面配置好extproc监听).

--启用50个会话和2个调度器

[oracle@oracleserver admin]$ agtctl

AGTCTL: Release 11.2.0.1.0 - Production on Sat Jan 5 05:29:51 2013

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

AGTCTL> set agent_sid CALLOUT_LISTENER
AGTCTL> set max_dispatchers 2
AGTCTL> set max_sessions 50
AGTCTL> show max_sessions
50
AGTCTL> show max_dispatchers
2
AGTCTL> startup extproc
AGTCTL> exit



此时发现多线程外部存储代理已经启动,如下:

[oracle@oracleserver admin]$ ps -ef|grep -v grep|grep extprocCALLOUT
oracle    6612     1  0 05:31 ?        00:00:00 extprocCALLOUT_LISTENER -mt



和关闭数据库一样,使用shutdown immediate命令来关闭多线程外部存储代理.

当你开启了extproc多线程代理,所有新的外部存储调用将通过多线程代理来调用.

但是之前的调用还是使用动态的单个extproc代理,直到调用完成.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: