現象:
為數據庫設置多個服務名(通過SCOPE=both設置,同時修改參數文件)
1 SQL> show parameter service_names; 2 3 NAME TYPE VALUE 4 ------------------------------------ ----------- ------------------------------ 5 service_names string vmdb 6 7 SQL> alter system set service_names='vmdb,sn01,sn02' scope=both; 8 9 System altered.
重啟監聽后,監聽狀態並未顯示服務sn01,sn02
1 [oracle@CentOS ~]$ lsnrctl stop 2 3 LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 26-MAR-2018 18:29:21 4 5 Copyright (c) 1991, 2009, Oracle. All rights reserved. 6 7 Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=CentOS)(PORT=1521))) 8 The command completed successfully 9 [oracle@CentOS ~]$ lsnrctl start 10 11 LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 26-MAR-2018 18:29:24 12 13 Copyright (c) 1991, 2009, Oracle. All rights reserved. 14 15 Starting /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnslsnr: please wait... 16 17 TNSLSNR for Linux: Version 11.2.0.1.0 - Production 18 System parameter file is /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora 19 Log messages written to /u01/app/oracle/diag/tnslsnr/CentOS/listener/alert/log.xml 20 Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=CentOS)(PORT=1521))) 21 22 Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=CentOS)(PORT=1521))) 23 STATUS of the LISTENER 24 ------------------------ 25 Alias LISTENER 26 Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production 27 Start Date 26-MAR-2018 18:29:24 28 Uptime 0 days 0 hr. 0 min. 0 sec 29 Trace Level off 30 Security ON: Local OS Authentication 31 SNMP OFF 32 Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora 33 Listener Log File /u01/app/oracle/diag/tnslsnr/CentOS/listener/alert/log.xml 34 Listening Endpoints Summary... 35 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=CentOS)(PORT=1521))) 36 Services Summary... 37 Service "vmdb" has 1 instance(s). 38 Instance "vmdb", status UNKNOWN, has 1 handler(s) for this service... 39 The command completed successfully
通過另一台機器通過服務名sn01連接可以連接上:
1 [oracle@centos-sample ~]$ sqlplus test/test@192.168.8.141/sn01 2 3 SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 25 20:06:35 2018 4 5 Copyright (c) 1982, 2009, Oracle. All rights reserved. 6 7 ERROR: 8 ORA-28002: the password will expire within 7 days 9 10 11 12 Connected to: 13 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production 14 With the Partitioning, OLAP, Data Mining and Real Application Testing options 15 16 SQL>
在數據庫中可以查詢v$session視圖的service_name來判斷會話是由通過哪個服務名連接創建的:
1 SQL> col paddr format a20 2 SQL> col Sid format 9999999 3 SQL> col username format a15 4 SQL> col service_name format a20 5 SQL> Select paddr,Sid,serial#,username,service_name From v$session Where username Is Not Null; 6 7 PADDR SID SERIAL# USERNAME SERVICE_NAME 8 -------------------- -------- ---------- --------------- -------------------- 9 000000008DC95250 17 19 SYS SYS$USERS 10 000000008DC98310 36 7 TEST vmdb 11 000000008DC96290 37 22 TEST sn01 12 000000008DC99350 38 11 TEST vmdb
重啟數據庫:
1 SQL> shutdown immediate; 2 Database closed. 3 Database dismounted. 4 ORACLE instance shut down. 5 SQL> startup 6 ORACLE instance started. 7 8 Total System Global Area 776646656 bytes 9 Fixed Size 2217384 bytes 10 Variable Size 583010904 bytes 11 Database Buffers 188743680 bytes 12 Redo Buffers 2674688 bytes 13 Database mounted. 14 Database opened.
再次查看監聽,sn01,sn02服務名顯示出來了:
1 [oracle@CentOS ~]$ lsnrctl status 2 3 LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 26-MAR-2018 18:30:29 4 5 Copyright (c) 1991, 2009, Oracle. All rights reserved. 6 7 Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=CentOS)(PORT=1521))) 8 STATUS of the LISTENER 9 ------------------------ 10 Alias LISTENER 11 Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production 12 Start Date 26-MAR-2018 18:29:24 13 Uptime 0 days 0 hr. 1 min. 5 sec 14 Trace Level off 15 Security ON: Local OS Authentication 16 SNMP OFF 17 Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora 18 Listener Log File /u01/app/oracle/diag/tnslsnr/CentOS/listener/alert/log.xml 19 Listening Endpoints Summary... 20 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=CentOS)(PORT=1521))) 21 Services Summary... 22 Service "sn01" has 1 instance(s). 23 Instance "vmdb", status READY, has 1 handler(s) for this service... 24 Service "sn02" has 1 instance(s). 25 Instance "vmdb", status READY, has 1 handler(s) for this service... 26 Service "vmdb" has 2 instance(s). 27 Instance "vmdb", status UNKNOWN, has 1 handler(s) for this service... 28 Instance "vmdb", status READY, has 1 handler(s) for this service... 29 Service "vmdbXDB" has 1 instance(s). 30 Instance "vmdb", status READY, has 1 handler(s) for this service... 31 The command completed successfully
但是監聽配置文件里不會自動增加服務名sn01,sn02:
1 [oracle@CentOS ~]$ cat /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora 2 # listener.ora Network Configuration File: /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora 3 # Generated by Oracle configuration tools. 4 5 SID_LIST_LISTENER = 6 (SID_LIST = 7 (SID_DESC = 8 (GLOBAL_DBNAME = vmdb) 9 (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) 10 (SID_NAME = vmdb) 11 ) 12 ) 13 14 LISTENER = 15 (DESCRIPTION = 16 (ADDRESS = (PROTOCOL = TCP)(HOST = CentOS)(PORT = 1521)) 17 ) 18 19 ADR_BASE_LISTENER = /u01/app/oracle
listener.ora文件典型配置:
1 SID_LIST_LISTENER = 2 (SID_LIST = 3 (SID_DESC = 4 (SID_NAME = PLSExtProc) 5 (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) 6 (PROGRAM = extproc) 7 ) 8 (SID_DESC = 9 (GLOBAL_DBNAME = vmdb) 10 (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) 11 (SID_NAME = vmdb) 12 ) 13 (SID_DESC = 14 (GLOBAL_DBNAME = sn01) 15 (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) 16 (SID_NAME = vmdb) 17 ) 18 (SID_DESC = 19 (GLOBAL_DBNAME = sn02) 20 (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1) 21 (SID_NAME = vmdb) 22 ) 23 ) 24 25 LISTENER = 26 (DESCRIPTION = 27 (ADDRESS = (PROTOCOL = TCP)(HOST = CentOS)(PORT = 1521)) 28 )
以下解釋來自老蓋的《深入淺出ORACLE》:
監聽器文件主要包含兩個部分:
- 第一部分LISTENER信息,這部分包含了監聽的協議、地址以及端口等信息。
- 第二部分SID_LIST_LISTENER信息,這部分信息用於提供對外的數據庫服務列表。第一個SID_DESC部分(SID_NAME = PLSExtProc)是數據庫缺省就包含的對外部存儲過程提供的本地監聽,此外三個SID_DESC部分是對數據庫的三個SERVICE_NAMES所設置的監聽服務,對於同一個SID對應的數據庫,可以對外提供多個服務名供客戶端訪問。
設置服務名的參數為GLOBAL_DBNAME,當處理客戶端連接請求時,監聽器首先嘗試將GLOBAL_DBNAME和客戶端請求中的SERVICE_NAME相匹配;如果客戶端連接請求的是SID信息,則Oracle不檢查GLOBAL_DBNAME設置,而是對監聽器中設置的SID_NAME進行匹配。
啟動這個監聽后,可以看到對於不同服務名Oracle所啟動的監聽信息。首先輸出的信息顯示了監聽器文件地址以及監聽日志文件位置(監聽器日志在診斷數據庫異常或攻擊信息時非常有用)。
通過服務名,Oracle可以將客戶端和服務器徹底隔離開來,對於客戶端來說,它不用關心數據庫的名字、實例名到底是什么,它只需要知道數據庫對外提供的服務名就行了,這個名字可能和實例名相同,也可能不相同。
(注:通過查詢會話視圖v$session的service_names,可以區分哪些會話來自哪個service_name,所以可以通過提供不同的service_name給不同的下游系統,用來區分哪些會話由哪些系統創建)
從8i開始,oracle引入了動態服務注冊(Dynamic Service Registration)的功能,所謂動態注冊是指當實例啟動之后,由后台進程PMON在監聽器中注冊數據庫服務信息。在動態注冊機制下,原來監聽器中的SID_LIST部分將不再需要。動態注冊的服務名,由於監聽器確切地知道實例的狀態,所以正常狀態通常顯示為READY,而對於靜態注冊的服務名,則狀態顯示為UNKNOW。
以下演示,刪除監聽配置文件listener.ora后,監聽器依然可以知道動態注冊的服務名:
1 [oracle@CentOS ~]$ cd /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/ 2 [oracle@CentOS admin]$ ll 3 總用量 16 4 -rw-r--r-- 1 oracle oinstall 461 3月 26 18:17 listener.ora 5 drwxr-xr-x. 2 oracle oinstall 4096 5月 7 2017 samples 6 -rw-r--r--. 1 oracle oinstall 187 5月 7 2007 shrept.lst 7 -rw-r-----. 1 oracle oinstall 325 5月 7 2017 tnsnames.ora 8 [oracle@CentOS admin]$ lsnrctl stop 9 10 LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 27-MAR-2018 13:29:44 11 12 Copyright (c) 1991, 2009, Oracle. All rights reserved. 13 14 Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=CentOS)(PORT=1521))) 15 The command completed successfully 16 17 [oracle@CentOS admin]$ ll 18 總用量 16 19 -rw-r--r-- 1 oracle oinstall 461 3月 26 18:17 listener.ora 20 drwxr-xr-x. 2 oracle oinstall 4096 5月 7 2017 samples 21 -rw-r--r--. 1 oracle oinstall 187 5月 7 2007 shrept.lst 22 -rw-r-----. 1 oracle oinstall 325 5月 7 2017 tnsnames.ora 23 [oracle@CentOS admin]$ mv listener.ora listener.ora_bak 24 [oracle@CentOS admin]$ lsnrctl start 25 26 LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 27-MAR-2018 13:30:10 27 28 Copyright (c) 1991, 2009, Oracle. All rights reserved. 29 30 Starting /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnslsnr: please wait... 31 32 TNSLSNR for Linux: Version 11.2.0.1.0 - Production 33 Log messages written to /u01/app/oracle/diag/tnslsnr/CentOS/listener/alert/log.xml 34 Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=CentOS)(PORT=1521))) 35 36 Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521)) 37 STATUS of the LISTENER 38 ------------------------ 39 Alias LISTENER 40 Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production 41 Start Date 27-MAR-2018 13:30:11 42 Uptime 0 days 0 hr. 0 min. 1 sec 43 Trace Level off 44 Security ON: Local OS Authentication 45 SNMP OFF 46 Listener Log File /u01/app/oracle/diag/tnslsnr/CentOS/listener/alert/log.xml 47 Listening Endpoints Summary... 48 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=CentOS)(PORT=1521))) 49 The listener supports no services 50 The command completed successfully 51 [oracle@CentOS admin]$ lsnrctl status 52 53 LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 27-MAR-2018 13:35:54 54 55 Copyright (c) 1991, 2009, Oracle. All rights reserved. 56 57 Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521)) 58 STATUS of the LISTENER 59 ------------------------ 60 Alias LISTENER 61 Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production 62 Start Date 27-MAR-2018 13:30:11 63 Uptime 0 days 0 hr. 5 min. 43 sec 64 Trace Level off 65 Security ON: Local OS Authentication 66 SNMP OFF 67 Listener Log File /u01/app/oracle/diag/tnslsnr/CentOS/listener/alert/log.xml 68 Listening Endpoints Summary... 69 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=CentOS)(PORT=1521))) 70 Services Summary... 71 Service "sn01" has 1 instance(s). 72 Instance "vmdb", status READY, has 1 handler(s) for this service... 73 Service "sn02" has 1 instance(s). 74 Instance "vmdb", status READY, has 1 handler(s) for this service... 75 Service "vmdb" has 1 instance(s). 76 Instance "vmdb", status READY, has 1 handler(s) for this service... 77 Service "vmdbXDB" has 1 instance(s). 78 Instance "vmdb", status READY, has 1 handler(s) for this service... 79 The command completed successfully
可以看到只有動態注冊的服務名,沒有了UNKNOW。
啟動監聽時,雖然顯示The listener supports no services,但是由於動態注冊是PMON進程主動向監聽器注冊,所以監聽狀態依然能看到動態注冊的服務處於READY狀態,可以對外提供訪問服務。