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