oracle 初始化参数SERVICE_NAMES和客户端TNS中SERVICE_NAME

来源:互联网 发布:淘宝时间倒计时代码 编辑:程序博客网 时间:2024/04/30 20:47

彻底理解初始化参数SERVICE_NAMES和客户端TNS中SERVICE_NAME

彻底理解初始化参数SERVICE_NAMES和客户端TNS中SERVICE_NAME

本文可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明

http://blog.itpub.net/post/11/3085

1.  SERVICE_NAMES与LISTENER

初始化参数SERVICE_NAMES默认为INSTANCE_NAME,后台进程PMON自动在服务器监听器中注册该SERVICE_NAMES。实验如下:

sidb@GDSI-HYQL> show parameter service_

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
service_names                        string      simis

sidb@GDSI-HYQL> show parameter instance_name

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
instance_name                        string      simis

首先监听器配置文件手工配置了数据库服务,listener.ora的配置信息为:

# LISTENER.ORA Network Configuration File: D:oracleora90networkadminlistener.ora
# Generated by Oracle configuration tools.

LISTENER =

  (DESCRIPTION_LIST =

    (DESCRIPTION =

      (ADDRESS_LIST =

        (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))

      )

      (ADDRESS_LIST =

        (ADDRESS = (PROTOCOL = TCP)(HOST = sb-hyk)(PORT = 1521))

      )

    )

  )

SID_LIST_LISTENER =

  (SID_LIST =

    (SID_DESC =

      (SID_NAME = PLSExtProc)

      (ORACLE_HOME = D:oracleora90)

      (PROGRAM = extproc)

    )

    (SID_DESC =

      (GLOBAL_DBNAME = simis)

      (ORACLE_HOME = D:oracleora90)

      (SID_NAME = simis)

    )

  )

 
lsnrctl service显示的信息如下:

LSNRCTL for 32-bit Windows: Version 9.0.1.1.1 - Production on 14-10月-2004 10:32:18
Copyright (c) 1991, 2001, Oracle Corporation.  All rights reserved.

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))

服务摘要..

服务 "PLSExtProc" 包含 1 个例程。

  例程 "PLSExtProc", 状态 UNKNOWN, 包含此服务的 1 个处理程序...

    处理程序:

      "DEDICATED" 已建立:0 已被拒绝:0

         LOCAL SERVER

服务 "simis" 包含 2 个例程。

  例程 "simis", 状态 UNKNOWN, 包含此服务的 1 个处理程序...

    处理程序:

      "DEDICATED" 已建立:0 已被拒绝:0

         LOCAL SERVER

  例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...

    处理程序:

      "DEDICATED" 已建立:4 已拒绝:0 状态:ready

         LOCAL SERVER

命令执行成功


通过如下实验可以证明服务状态为READY表示PMON自动注册的服务名,而UNKNOWN则表示该服务是手工在LISTENER.ORA中配置的数据库服务。

把listener.ora配置文件中的数据库服务信息去掉,更改为:

# LISTENER.ORA Network Configuration File: D:oracleora90networkadminlistener.ora
# Generated by Oracle configuration tools.

LISTENER =

  (DESCRIPTION_LIST =

    (DESCRIPTION =

      (ADDRESS_LIST =

        (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))

      )

      (ADDRESS_LIST =

        (ADDRESS = (PROTOCOL = TCP)(HOST = sb-hyk)(PORT = 1521))

      )

    )

  )

下面再看看lsnrctl service的显示信息:

LSNRCTL> reload

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))

命令执行成功

LSNRCTL> service

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))

服务摘要..

服务 "simis" 包含 1 个例程。

  例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...

    处理程序:

      "DEDICATED" 已建立:0 已拒绝:0 状态:ready

         LOCAL SERVER

命令执行成功

这里显示的simis就是初始化参数中SERVICE_NAMES设置的参数值,由PMON自动注册到监听器上。下面不妨修改初始化参数SERVICE_NAMES来证明这一观点:

alter system set service_names='simis,hyk,hyb' scope=memory

/

在当前实例上修改sevice_names对监听器不起作用:

LSNRCTL> reload

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))

命令执行成功

LSNRCTL> service

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))

监听器不支持服务

命令执行成功


修改参数,关闭数据库

SQL> alter system set service_names='simis,hyk,hyb' scope=both

  2  /
系统已更改。

-- 平台是windows,901,这里不得不提一下的是901真的非常垃圾,还会出现如下的bug

SQL> shutdown immediate;

ORA-03113: 通信通道的文件结束

SQL> conn / as sysdba

已连接到空闲例程。

SQL> startup
ORACLE 例程已经启动。
Total System Global Area  114061244 bytes
Fixed Size                   282556 bytes
Variable Size              79691776 bytes
Database Buffers           33554432 bytes
Redo Buffers                 532480 bytes
数据库装载完毕。
数据库已经打开。

SQL> show parameter service_

NAME                                 TYPE        VALUE

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

service_names                        string      simis,hyk,hyb

下面看看lsnrctl service的输出:

LSNRCTL> service

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))

服务摘要..

服务 "hyb" 包含 1 个例程。

  例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...

    处理程序:

      "DEDICATED" 已建立:0 已拒绝:0 状态:ready

         LOCAL SERVER

服务 "hyk" 包含 1 个例程。

  例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...

    处理程序:

      "DEDICATED" 已建立:0 已拒绝:0 状态:ready

         LOCAL SERVER

服务 "simis" 包含 1 个例程。

  例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...

    处理程序:

      "DEDICATED" 已建立:0 已拒绝:0 状态:ready

         LOCAL SERVER

命令执行成功

我们看到SERVICE_NAMES设置的服务参数simis、hyk、hyb均在监听器中自动注册。

谢谢biti_rainy的指正:

parameter 中 service_name 默认是 db_name.db_domain

SQL> show parameter db_name

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name string ocn
SQL> show parameter instance_name

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
instance_name string ocn1
SQL> show parameter db_domain

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_domain string db.alibaba.com
SQL>
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
instance_name string ocn1
SQL> show parameter service_name

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string ocn.db.alibaba.com


2.SERVICE_NAMES与客户端的TNS配置

在客户端配置tnsnames.ora:

test1 =

  (DESCRIPTION =

    (ADDRESS_LIST =

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

    )

    (CONNECT_DATA =

      (SERVICE_NAME = SIMIS)

    )

  )

test2 =

  (DESCRIPTION =

    (ADDRESS_LIST =

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

    )

    (CONNECT_DATA =

      (SERVICE_NAME = hyk)

    )

  )

test3 =

  (DESCRIPTION =

    (ADDRESS_LIST =

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

    )

    (CONNECT_DATA =

      (SERVICE_NAME = hyb)

    )

  )

下面分布尝试用这三个tns来连接:

SQL> conn system/manager@test1

已连接。

SQL> /
INSTANCE_NAME    HOST_NAME
---------------- ------------------------------
simis            SB-HYK

SQL> conn system/manager@test2

已连接。

SQL> /
INSTANCE_NAME    HOST_NAME
---------------- ------------------------------
simis            SB-HYK

SQL> conn system/manager@test3

已连接。

SQL> /
INSTANCE_NAME    HOST_NAME
---------------- ------------------------------
simis            SB-HYK

我们看到配置的SERVICE_NAME不管是simis、hyk、hyb均可以成功连接到服务器上。

下面看看如果SERVICE_NAMES中如果不包含INSTANCE_NAME的时候能不能通过INSTANCE_NAME进行连接,事实证明连接不成功:

SQL> alter system set service_names='hyb,hyk' scope=both;

系统已更改。

SQL> shutdown abort;

ORACLE 例程已经关闭。

SQL> conn / as sysdba

已连接到空闲例程。

SQL> startup
ORACLE 例程已经启动。
Total System Global Area  114061244 bytes
Fixed Size                   282556 bytes
Variable Size              79691776 bytes
Database Buffers           33554432 bytes
Redo Buffers                 532480 bytes
数据库装载完毕。
数据库已经打开。

SQL> conn system/manager@test1

ERROR:

ORA-12514: TNS: 监听进程不能解析在连接描述符中给出的 SERVICE_NAME


3. 结论

从oracle9i开始,后台进程PMON自动在监听器中注册初始化参数SERVICE_NAMES中定义的服务名,SERVICE_NAMES默认为DB_NAME+DOMAIN_NAME。客户端tns配置中SERVICE_NAME的名称必须是SERVICE_NAMES或其中的一个NAME。


4. 自动注册时的连接

SQL> select *from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Prod
PL/SQL Release 10.1.0.2.0 - Production
CORE 10.1.0.2.0 Production
TNS for 32-bit Windows: Version 10.1.0.2.0 - Production
NLSRTL Version 10.1.0.2.0 - Production

SQL> show parameter service_names

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string test1,test2
SQL>

客户端tns配置:
TEST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test)
)
)

TEST1 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test1)
)
)

TEST2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test2)
)
)

TEST3 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = )(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = simis)
)
)

1).服务器端配置示例一
# listener.ora Network Configuration File: e:/oracle/product/10.1.0/db_1/NETWORK/ADMIN/listener.ora
# Generated by Oracle configuration tools.

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

服务摘要..
服务 "test1" 包含 1 个例程。
例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...
处理程序:
"DEDICATED" 已建立:0 已拒绝:0 状态:ready
LOCAL SERVER
服务 "test2" 包含 1 个例程。
例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...
处理程序:
"DEDICATED" 已建立:0 已拒绝:0 状态:ready
LOCAL SERVER
命令执行成功
LSNRCTL>


客户端连接:
SQL> conn system/manager@test1
已连接。
SQL> conn system/manager@test2
已连接。
SQL> conn system/manager@test
ERROR:
ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务


警告: 您不再连接到 ORACLE。
SQL> conn system/manager@test3
ERROR:
ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务


2.服务器端配置示例二
# listener.ora Network Configuration File: e:/oracle/product/10.1.0/db_1/NETWORK/ADMIN/listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = test)
(ORACLE_HOME = E:/oracle/product/10.1.0/db_1)
(SID_NAME = simis)
)
)

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

服务摘要..
服务 "test" 包含 1 个例程。
例程 "simis", 状态 UNKNOWN, 包含此服务的 1 个处理程序...
处理程序:
"DEDICATED" 已建立:0 已被拒绝:0
LOCAL SERVER
服务 "test1" 包含 1 个例程。
例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...
处理程序:
"DEDICATED" 已建立:0 已拒绝:0 状态:ready
LOCAL SERVER
服务 "test2" 包含 1 个例程。
例程 "simis", 状态 READY, 包含此服务的 1 个处理程序...
处理程序:
"DEDICATED" 已建立:0 已拒绝:0 状态:ready
LOCAL SERVER
命令执行成功
LSNRCTL>


客户端连接:
SQL> conn system/manager@test
已连接。
SQL>
SQL> conn system/manager@test3
ERROR:
ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务


警告: 您不再连接到 ORACLE。

可以认为,如果没有在listener.ora中手动添加配置数据库服务的话客户端的service_name是必须要是数据库的service_names或其中之一.
如果在listener.ora中手动添加配置了数据库服务的话,客户端的service_name可以设置为服务器端监听器配置文件中的GLOBAL_DBNAME,也可以设置成数据库的service_names。

看oracle文档对GLOBAL_DBNAME 的描述
Purpose:
Identifies the global database name of the database, a name comprised of the database name and database domain. You can obtain the GLOBAL_DBNAME value from the SERVICE_NAMES parameter in the initialization parameter file.

This parameter must be embedded under SID_DESC and should match the value of the SERVICE_NAMES parameter.

Example:
sid_list_listener_name=
(sid_list=
(sid_desc=
(global_dbname=oracle.com)
(sid_name=orcl)
(oracle_home=/usr/oracle)))

但实际上在配置的时候GLOBAL_DBNAME 可以为任意合法的字符,而客户端均可以通过该GLOBAL_DBNAME 连接到db server上.

原创粉丝点击