oracle 初始化參數SERVICE_NAMES和客戶端TNS中SERVICE_NAME

徹底理解初始化參數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上.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章