listener,oracle
http://blog.csdn.net/tianlesoftware/article/details/5543166
一.什么是注册
注册就是将数据库作为一个服务注册到监听程序。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库。这个服务名可能与实例名一样,也有可能不一样。
在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务(无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。)
相当于是这样:在数据库服务器和客户端之间有一监听程序(Listener),在监听程序中,会记录相应数据库对应的服务名(一个数据库可能对应有多个服务名),当客户端需要连接数据库时,只需要提供服务名,就可以建立客户端和服务器之间的连接。
二、动态注册
动态注册是在instance启动的时候PMON进程根据init.ora中的instance_name,service_names两个参数将实例和服务动态注册到listener中。
首先要在init.ora中指定instance_name,service_names两个参数的值。在sqlplus下通过show parameter service_names 和show parameter instance_name可以查看这两个参数的值。
注册到监听器中的实例值从init.ora文件中的instance_name参数取得。如果该参数没有设定值,那么它将取init.ora文件中的db_name的值。如果在RAC中配置,您必须将集群中每个实例的instance_name参数设置为一个唯一的值。
注册到监听器中的服务值从init.ora文件中的参数service_names取得。如果该参数没有设定值,数据库将拼接init.ora文件中的 db_name和db_domain的值来注册自己。如果选择提供service_names值,您可以使用完全限定的名称(比如 orcl.oracle.com)或缩写的名称(比如orcl)。如果选择缩写的名称并设置了db_domain参数,注册到监听器中的服务将是 service_name值和db_domain值的拼接。例如下面的设置将导致服务orcl.oracle.com被注册到监听器中:
db_domain=oracle.com
service_names=orcl ;
采取动态注册方法时,listener.ora中的内容如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = D:/oracle/product/10.2.0/db_1)
(PROGRAM = extproc)
)
)
可选择的是,您可以在service_names参数中指定多个服务值,值之间用逗号格开,这对于共享服务器配置是很有用的。
动态注册默认只注册到默认的监听器上(名称是LISTENER、端口是1521、协议是TCP),因为pmon只会动态注册port等于1521的监听,否则pmon不能动态注册listener,如果需要向非默认监听注册,则需要配置local_listener参数!
将监听的信息添加到tnsnames.ora 文件中。 注意,是tnsnames.ora 文件, 因为pmon在动态注册监听时要从tnsnames.ora中读取相关信息。
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = DaveDai)(PORT = 1522))
)
然后以sys用戶运行:
SQL> alter system set local_listener=listener;
SQL> alter system register;
或者:
SQL> alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL = TCP)(HOST = DaveDai)(PORT = 1522))';
SQL> alter system register;
系统已更改。
$lsnrctl status listener
如果没有显式设置service_names和instance_name的值,那么仅当数据库在监听器运行之后启动时,动态注册才会发生;在这种情况下,如果监听器后来发生了重启,动态注册信息将会丢失。显然,最好在所有的数据库启动之前先启动监听器,这样就会避免没有显式设置 service_names和instance_name的值时,若重启监听器带来的动态注册信息丢失的情况。
为初始化参数service_names和instance_name设置显式的值是个很好的实践,尽管如果您没有设置它们,Oracle也会为动态注册而生成默认值(基于db_name和db_main)。这样做的原因是,如果监听器在数据库启动之后重新启动,其动态注册行为将会有一些微妙的区别.如果监听器在数据库运行之后重新启动,你们仅当您在init.ora文件中显式地设置了service_names和instance_name的值时,每个数据库的PMON进程才会在很短的时间之后自动注册数据库。
如果需要执行连接时故障转移或负载均衡,或者想要在RAC中配置在实例之间透明地分布连接,那么使用service_names参数将是必要的。为启用这些功能,您只需要将每个实例的数据库参数文件中的service_names设置为同一个值,并在客户端连接请求的service_name设置中引用该值。
如果没有显式设置service_names和instance_name的值,那么仅当数据库在监听器运行之后启动时,动态注册才会发生;在这种情况下,如果监听器后来发生了重启,动态注册信息将会丢失。显然,最后在启动任何数据库之前启动服务器上的监听器,并完全避免监听器的重启。
另外,您还可以在SQL*PLUS中使用命令:
SQL>ALTER SYSTEM REGISTER;
在数据库打开时的任何时候,手工地在监听器中注册服务值。这个命令对于替换因监听器重启而丢失地服务值很有用,并且它所注册地值与在数据库启动时由动态注册所设置的值完全一样。
动态监听:
oracle监听器运行后,oracle实例在open时,会动态向监听程序注册其service_names和instance_name。
其中instance_name默认是:db_name
而service_names默认是:db_name.db_domain
三、静态注册
静态注册就是实例启动时读取listener.ora文件的配置,将实例和服务注册到监听程序。无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。
静态注册时,listener.ora中的GLOBAL_DBNAME向外提供服务名,listener.ora中的SID_NAME提供注册的实例名。
采取静态注册方法时,listener.ora中的内容如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = D:/oracle/product/10.2.0/db_1)
(PROGRAM = extproc)
)
(SID_DESC =
(GLOBAL_DBNAME =orcl)
(ORACLE_HOME = D:/oracle/product/10.2.0/db_1)
(SID_NAME =orcl)
)
(SID_DESC =
(GLOBAL_DBNAME =orcl1)
(ORACLE_HOME = D:/oracle/product/10.2.0/db_1)
(SID_NAME =orcl)
)
)
该文件表明数据库是单实例的,实例名为orcl,向外提供了两个服务:orcl和orcl1
静态监听:
oracle实例运行后,监听程序启动时,根据listener.ora的配置注册相应的服务。
其中global_dbname对应的是oracle对外的服务名,即初始化参数里的service_names
而sid_name对应的是oralce实例的名称,即初始化参数里的instance_name
既然有动态监听为什么还要静态监听呢?原因如下:
1.监听器不是最早启动,oracle实例先启动
2.监听器重启
3.oracle实例没有open
可以使用命令lsnrctl status来查看某服务是静态注册还是动态注册。
实例状态为UNKNOWN值时表明此服务是静态注册的设置。这时监听器用来表明它不知道关于该实例的任何信息,只有当客户发出连接请求时,它才检查该实例是否存在。
动态注册的数据库通过状态信息中的状态READY或状态BLOCKED(对于一个备用数据库)来指明。不管关闭何时数据库,动态注册的数据库都会动态地从 监听器注销,而与之相关的信息将从状态列表中消失。这样,不管数据库是在运行还是已经关闭,监听器总是知道它的状态。该信息将被用于连接请求的回退(fallback)和负载平衡。
http://www.chenjunlu.com/2011/04/discussion-about-oracle-listener/
Oracle 监听器 Listener 是一个重要的数据库服务器组件,在整个 Oracle 体系结构中,扮演着重要的作用。它负责管理 Oracle 数据库和客户端之间的通讯,它在一个特定的网卡端口(默认是TCP 1521端口)上监听连接请求,并将连接转发给数据库,下面的部分,会从几个方面对监听器进行简单介绍。
1.监听器的功能
从当前的 Oracle 版本看,Listener 主要负责下面的几方面功能:
- 监听客户端请求。监听器运行在数据库服务器之上,与 Oracle 实例(可为多个)相关关联,是一个专门的进程 process,在 Windows 的服务项目或者 Linux 的运行进程列表中,都会看到对应的运行进程。Windows 上名为 TNSLSNR,Linux/Unix 平台上是 lsnrctl。监听器守候在服务器制定端口(默认为:1521),监听客户端的请求。
- 为客户端请求分配 Server Process。监听器只负责接听请求,之后将请求转接给 Oracle Server Process。在 Oracle 的服务模式下,客户端进程是不允许直接操作数据库实例和数据,而是通过一个服务进程 Server Process(也称为影子进程)作为代理。监听器接受到请求之后,就向操作系统(或者 Dispatcher 组件)要求 fork(或分配)一个 Server Process 与客户端相连。
- 注册实例服务。本质上讲,Listener 是建立实例和客户端进程之间联系的桥梁。Listener 与实例之间的联系,就是通过注册的过程来实现的。注册的过程就是实例告诉监听器,它的数据库数据库实例名称 instance_name 和服务名 service_names。监听器注册上这样的信息,对客户端请求根据监听注册信息,找到正确的服务实例名称。目前 Oracle 版本中,提供动态注册和静态注册两种方式。
- 错误转移 failover。failover 是 RAC 容错的一个重要方面功能,其功能是在数据库实例崩溃的时候,可以自动将请求转移到其他可用实例上的一种功能。可以提供很大程度上的可用性(Availability)功能。这个过程中,发现实例已经崩溃,并且将请求转移到其他实例上,就属于是 Listener 的功能。
- 负载均衡衡量。在 RAC 架构中,Oracle 实现了负载均衡。当一个客户请求到来时,Oracle 会根据当前 RAC 集群环境中所有实例的负载情况,避开负载较高的实例,将请求转移到负载较低的实例进行处理。在早期 RAC 版本中,负载轻重的衡量是根据监听器当前维护连接数目来确定的,而不是实时查看多实例的负载。RAC 环境中的监听器之间进行沟通通信。
2.监听器的操作
监听器在 Windows 和 Linux/Unix 平台上,都是可以直接操作的。下面以 Linux 平台操作为例,其他平台类似。
在命令行窗口(CMD),输入 lsnrctl,就可以进入监听器控制窗口。
[oracle@newtest ~]$ lsnrctl
LSNRCTL for Linux: Version 10.2.0.4.0 – Production on 06-APR-2011 14:31:46
Copyright (c) 1991, 2007, Oracle. All rights reserved.
Welcome to LSNRCTL, type “help” for information.LSNRCTL>
通过输入命令 help,可以查看支持的监听器操作。下面仅介绍常用的几个:
查看当前监听器状态:
敲入 status,可以查看当前监听器的状态,对应操作日志信息和服务注册信息等内容。如下:
LSNRCTL> status
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))
STATUS of the LISTENER
————————
Alias LISTENER
Version TNSLSNR for Linux: Version 10.2.0.4.0 – Production
Start Date 18-MAR-2011 18:03:56
Uptime 18 days 20 hr. 28 min. 37 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFFListener Parameter File /home/oracle/product/10.2.0/db_1/network/admin/listener.ora
Listener Log File /home/oracle/product/10.2.0/db_1/network/log/listener.log
Listening Endpoints Summary…
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
Services Summary…
Service “Test” has 2 instance(s).
Instance “Test”, status UNKNOWN, has 1 handler(s) for this service…
Instance “Test”, status READY, has 1 handler(s) for this service…
Service “TestXDB” has 1 instance(s).
Instance “Test”, status READY, has 1 handler(s) for this service…
Service “Test_XPT” has 1 instance(s).
Instance “Test”, status READY, has 1 handler(s) for this service…
The command completed successfullyLSNRCTL>
需要额外注意的下面几项内容:
1. 监听程序参数文件 $ORACLE_HOME/network/admin/listener.ora
监听器启动时依据参数文件的,当然没有参数文件监听器也是可以启动,那时监听器依据默认的行为操作。这个参数指定了监听器参数文件的位置,listener.ora。这个文件是一个文本类型参数文件,描述了监听器监听端口,主机名称和静态注册信息。Listener.ora是随着数据库实例的建立之后,建立监听器的过程中动态配置的。
2. 监听程序日志文件 $ORACLE_HOME/network/log/listener.log
监听器日志,是一个记录和描述监听器工作和错误的信息库。通过仔细研究日志内容,可以帮助我们发现当前的监听器的问题、解决连接故障和深入理解监听器工作原理。
上文中已经说明,监听器有注册功能,通过 status 命令(services 命令同样效果)。可以查看到当前有什么服务被注册上,用来检查连接服务失败,是常用的工具。
3. 开启/关闭监听器:
监听器的行为受到参数文件的控制,我们有时候需要调整监听器的参数。调整监听参数的方法,可以通过 Oracle 提供的 GUI 界面完成,还可以通过手工修改 listener.ora 来完成。
因为参数文件 listener.ora 是一个文本文件。Oracle 对于文本类型的参数文件,大多数情况下是不支持热加载的。pfile 和 listener.ora 都是如此。
使用界面 GUI,就是使用 Net Configuration Assistant 来配置。配置完成后,配置程序会自动重新启动监听器程序,来加载修改的参数文件。如果采用手工修改 listener.ora,就必须要手工的进行监听程序关闭和启动。
LSNRCTL> stop
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))
The command completed successfullyLSNRCTL> start
Starting /home/oracle/product/10.2.0/db_1/bin/tnslsnr: please wait…
TNSLSNR for Linux: Version 10.2.0.4.0 – Production
System parameter file is /home/oracle/product/10.2.0/db_1/network/admin/listener.ora
Log messages written to /home/oracle/product/10.2.0/db_1/network/log/listener.log
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))STATUS of the LISTENER
————————
Alias LISTENER
Version TNSLSNR for Linux: Version 10.2.0.4.0 – Production
Start Date 06-APR-2011 14:35:27
Uptime 0 days 0 hr. 0 min. 0 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /home/oracle/product/10.2.0/db_1/network/admin/listener.ora
Listener Log File /home/oracle/product/10.2.0/db_1/network/log/listener.log
Listening Endpoints Summary…(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
Services Summary…
Service “Test” has 1 instance(s).
Instance “Test”, status UNKNOWN, has 1 handler(s) for this service…
The command completed successfullyLSNRCTL>
这里多说一句关于监听器的参数配置。使用 GUI 可以满足大部分的情况,而且可以避免拼写错误引发的监听器故障(监听器不会检查配置项目的正确与否)。但是,在一些比较复杂的情况下,比如一台机器绑定多个IP的情况,或者 RAC 的复杂功能配置上,还是倾向于使用手工编写 listener.ora 的方法。
此外,lsnrctl 提示行还提供了 reload 命令,可以在 Listener 启动的情况下,重新加载文件和 SID 信息。但是我还是比较喜欢 stop+start 的组合。
如果是在 Windows 平台下,启动关闭监听器还可以在系统服务项目列表中操作,效果是一样的。
3.监听器的工作过程
下面我们谈谈监听器的工作过程。一般,监听器作为一个独立 process 在操作系统中运行,守候在特定网络端口(默认为:1521),等待客户端请求的到来。注意:我们在客户端配置命名服务的时候,输入的1521也就是为了与监听器程序建立连接。
当一个请求“如期而至”,监听器对照已经注册的服务列表,查找对应的数据库实例信息,获取到指定实例的 ORACLE_HOME 路径。相当于表明可以进行连接。
客户端与实例的交互不是直接的,是通过 Server Process 作为代理中介来实现的。所有指令 SQL 都是客户端通过 Server Process 发送到实例中,这种体系结构是 Oracle 对于实例和数据库文件一种保护机制。
当监听器获得请求之后,要从 Oracle 实例中分配一个 Server Process 与之对应。这里不同的 Oracle 连接方式存在一些差别。
如果是专用连接模式,也就是一个客户端连接对应一个 Server Process。监听器就会向 OS 请求 fork(创造)出一个 Server Process,与监听器尝试交互。
如果是共享连接模式,也就是多个客户端共享一个 Server Process(注意:这里还不是连接池)。监听器就会向 Dispatcher 进程(管理共享模式连接的进程)请求一个 Server Process 与之交互。
Server Process 与监听器的连接,实际上就是相互信息的交换。Server Process 将自身在 OS 中的进程编号、连接地址信息发给监听器。监听器将客户端信息传递给 Server Process。
监听器获取到 Server Process 的信息之后,将其返回给客户端连接程序。客户端获取到信息之后,进行重连接,根据返回的信息与 Server Process 在制定的服务器端口进行联系。
直到这个时候,客户端程序才将连接用户名、密码等信息发给 Server Process,进行登录验证等操作。监听器的工作也就到此结束。
这里面有一个技术细节,就是 Server Process 与客户端连接的时候,是允许不使用1521端口的。具体连接的端口,是带有随机因素的。在9i版本 Windows 平台下,如果安装了防火墙,只允许1521端口通信,是会带来一些连接问题。好在在其他平台上和之后的版本中,实现了一种端口共享技术,连接可以和监听器一起使用1521端口。
4.监听器的动/静态注册机制
介绍了监听器工作原理,下面我们说说动静态注册的机制。在上面的内容中,我们已经初步了解了注册的作用,注册就是将数据库作为一个服务注册到监听程序。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库。这个服务名可能与实例名一样,也有可能不一样。在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务(无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。)相当于是这样:在数据库服务器和客户端之间有一监听程序(Listener),在监听程序中,会记录相应数据库对应的服务名(一个数据库可能对应有多个服务名),当客户端需要连接数据库时,只需要提供服务名,就可以建立客户端和服务器之间的连接。目前的 Oracle,支持静态注册和动态注册两种注册方式。
静态注册顾名思义,就是显示的指定出监听器程序要为那个实例以哪个服务名做监听。在启动监听器的时候,监听程序是不知道所监听实例服务是否存在。直到有客户端请求指定的服务。
静态注册就是实例启动时读取 listener.ora 文件的配置,将实例和服务注册到监听程序。无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。
静态注册时,listener.ora 文件中的 GLOBAL_DBNAME 向外提供服务名,listener.ora 文件中的 SID_NAME 提供注册的实例名。下面是一个典型参数文件的结构:
# listener.ora Network Configuration File: /home/oracle/product/10.2.0/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /home/oracle/product/10.2.0/db_1)
(PROGRAM = extproc)
)(SID_DESC =
(GLOBAL_DBNAME = Test)
(ORACLE_HOME = /home/oracle/product/10.2.0/db_1)
(SID_NAME = Test)
)
)LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
)
)
其中,SID_LIST 配置节点中的 SID_DESC 就是配置静态注册的节点项目。SID_LIST 里用来配置当前监听器注册的服务项目,通过多个 SID_DESC 进行配置,每个 SID_DESC 基本上就是一个配置项目。默认是动态注册的时候,只有 PLSExtProc 项目。
默认安装时,会安装一个 PL/SQL 外部程序(ExtProc)条目在 listener.ora 中,是 Oracle 为调用外部程序默认配置的监听,它的名字通常是 ExtProc 或 PLSExtProc,但一般不会使用它,可以直接从 listener.ora 中将这项移除,因为对 ExtProc 已经有多种攻击手段了,在不使用外部程序时,Oracle 也是建议删除的。PLSExtProc 是 PL/SQL external procdure 的意思,就是在 PL/SQL 中调用外部语句,如 C,Java 写的过程。现在,Oracle 已经全面支持 Java 了,这东西也就过时了,之所以继续保留是考虑到兼容以前老版本的数据库实例。有时可能会在多个数据库实例之间拷贝 listener.ora,请检查拷贝来的文件中是否含有不需要的服务,确保只留下的确需要的服务项目,减少监听器受攻击的面。其实 Oracle DBA 应该特别重视监听器的安全性,因为黑客可以轻易的侵入没有进行安全配置监听器的 Oracle 数据库实例。如果你想了解 Oracle 监听器安全配置方面的知识,请点击 这里 学习。
静态配置项目中,通过 GLOBAL_NAME 配置服务项目,通过 SID_NAME 指定数据库实例的名称,通过 ORACLE_HOME 配置 Oracle 数据库软件安装的基本目录。
动态注册是与静态注册相对应的一种注册方法。同样也是通过 listener.ora 进行配置。下面是一个典型的配置参数文件:
# listener.ora Network Configuration File: /home/oracle/product/10.2.0/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /home/oracle/product/10.2.0/db_1)
(PROGRAM = extproc)
)
)LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
)
)
对比上面的静态注册文件,可以发现显示指定服务名称和数据库实例名的项目不见了。只有本地地址和监听器端口信息。
动态注册的动作是监听器所在主机上数据库实例完成。动态注册是 Oracle 上一个不能关闭的功能。实例的 background process PMON,每隔一段时间(一到两分钟)就会将实例的参数信息注册到监听器上,实现动态注册。
注册的信息是数据库参数 service_name 和 instance_name。可以通过 Show Parameter 命令查看。
SQL> show parameter instance_name;
NAME TYPE VALUE
———————————— ———– ——————————
instance_name string TestSQL> show parameter service_names;
NAME TYPE VALUE
———————————— ———– ——————————
service_names string Test
一般数据库在建立的时候,这两个参数都是已经设置好的,不会轻易的发生变化。
如果 instance_name 参数没有设置,则系统会选取参数 db_name 作为实例名称返回。如果 service_names 没有设置,则会将 db_name 和 db_domain 两个参数组合成服务名实现注册。
值得注意的一个问题是,service_names 参数是一个可以指定多个服务名称的参数,以逗号分隔。也就是说,一个 Oracle 实例时可以同时作为多个服务名向外提供服务的。service_name 是 Oracle 在新近版本中提出,替代 SID_NAME 的概念。使用 Service 的指定方式,多个 Oracle 实例就可以统一提供一致的数据访问服务(也就是 RAC)。
通常,对 instance_name 和 service_name 两个参数,还是建议设置上。因为会在一定程度上影响到动态注册的效果。
如果没有显示的指定这两个参数,那么只有在数据库实例启动在监听器实例之后的时候,才会一次动态注册。一旦之后监听器重新启动,动态注册的信息就不会存在,而且很难再次注册上。所以,我们是推荐将这两个参数设置上的。
只有显示设置两个值的情况下,PMON 才会周期性的将注册信息加以注册。通过命令行,也可以强迫 PMON 立即执行一次注册操作。
SQL> alter system register ;
System altered
最后,我们聊一聊动态注册的作用,支持错误转移 failover。注册操作的发动方是 PMON 后台进程,PMON 是 Oracle 实例最重要的后台进程,很多资料和 DBA 都是以该进程的状态确定数据库实例的状态。PMON 负责动态注册,如果不能进行动态注册,说明 PMON 已经失去了工作能力,也就意味着监听程序所服务的实例已经不能工作。
通过动态注册的机制,监听程序是可以知道所服务的服务器实例已经崩溃,对于客户端的请求,可以实现错误转移。
当然,我们这里谈到的崩溃是实例的崩溃。如果监听器程序崩溃了,情况又是另一种样子了。
我们可以使用命令 lsnrctl status 来查看某服务是静态注册还是动态注册。实例状态为 UNKNOWN 值时表明此服务是静态注册的设置。这时监听器用来表明它不知道关于该实例的任何信息,只有当客户发出连接请求时,它才检查该实例是否存在。动态注册的数据库通过状态信息中的状态 READY 或状态 BLOCKED(对于一个备用数据库)来指明。不管关闭何时数据库,动态注册的数据库都会动态地从 监听器注销,而与之相关的信息将从状态列表中消失。这样,不管数据库是在运行还是已经关闭,监听器总是知道它的状态。该信息将被用于连接请求的回退 (fallback)和负载平衡。
http://www.cn-java.com/www1/?action-viewnews-itemid-103377
一、配置初衷
oracle虽然用了多年,但是一直仅仅是用而已,没有深入看过oracle的东东。第一次,自己在服务器上完整创建并且配置一个oracle服务器,问题马上就出现了:
严重: 监听程序未启动或数据库服务未注册到该监听程序。启动该监听程序并注册数据库服务, 然后重新运行 EM Configuration Assistant。
所以,决定拎起袖子,跨界学习一下oracle中的监听器吧。
二、监听器的原理理解
以下,就谈谈我自己的浅薄的理解吧:
首先,我觉得监听器的设计使用了代理模式,而监听器正正是代理模式中所描述的代理。当客户端对数据库发生请求的时候,监听器就作为这个客户端的代理,发出对数据库实例的请求。当数据库实例的server 进程收到监听器转发过来的请求时候,会做出响应。而这个响应也是通过监听器转发给客户端。不难发现,客户端与数据库实例之间的交互是间接完成的,在他们中间就存在着一个中间人-监听器。
但是,有一点我们需要注意的,客户端永远不知道他请求的数据库实例是什么,唯一知道的只是数据库所在的服务器的某个服务的名字以及这个数据库分配给他的用户名和密码。这就好比我们去买苹果产品,我们买的时候去的只是代理商的店面,只知道产品是苹果公司卖的,但产品到底是由哪家代工公司生产的,作为消费者的我们一无所知。
但是,归根到底,总该有那么一个机制,负责维护“服务”,“监听器”,“数据库实例”三者之间的关系吧。答案是有的,请看下面的内容。
三、相应的三个配置文件:sqlnet.ora,tnsnames.ora,listener.ora(路径:$oracle_home\NETWORK\ADMIN;默认情况下安装的话,大概如此:D:\app\Administrator\product\11.2.0\dbhome_2\NETWORK\ADMIN)
考虑一下,以下的一种情况:
假如,我们需要连接到一个数据库上的名字为mzoa的实例并且这个数据库实例里面有一个密码为:a,用户名为:sysman的账号。但是,我们不知道这个数据库实例的名字,只知道这个数据库服务器向外提供了一个名为“mzoa”的“服务”,至于我们需要请求的数据库的实例的名字是什么,我们一无所知。但是,尽管如此,我们还是能够连接上我们需要找到的数据库实例-mzoa。(ps:实例名字“mzoa”与服务名字“mzoa”不是必然相同的,可以在创建实例的时候加以修改的!)
不信?可以看看下面……
我们可以在cmd里面完成以下的连接操作:
C:\Users\Administrator>sqlplus sysman/a@I_AM_SERIVCE
SQL*Plus: Release 11.2.0.1.0 Production on 星期二 9月 2714:15:162011
Copyright (c) 1982, 2010, Oracle. All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0- Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
至于为什么能这样子?我想上面的三个配置文件:sqlnet.ora,tnsnames.ora,listener.ora足以说明问题。
我们先将这三个配置文件分分类。sqlnet.ora,tnsnames.ora属于客户端,listener.ora属于服务器端。
第一类,客户端文件:sqlnet.ora,tnsnames.ora
在我们上面的操作过程中,我们使用了以下的语句:
sqlplus sysman/a@I_AM_SERIVCE
“I_AM_SERIVCE”不是一个“服务”的名字,但是至于这个名字有什么内涵。我们需要oracle客户端做出解释。(注意:这里的oracle客户端指的是oracle客户端软件对应的进程集)
oracle客户端是这样子完成对“I_AM_SERIVCE”这一个名字作出解释的:
步骤一:
查看sqlnet.ora配置文件,内容如下:
SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES,HOSTNAME,EZCONNECT)
其中第二个条目NAMES.DIRECTORY_PATH,从左至右,指示首先由哪些文件来解释名字。
如上面的例子,就是指示,先由TNSNAMES.ora文件,然后是客户端所在系统的hosts文件……解释名字
步骤二:
因为,sqlnet.ora文件指出先由TNSNAMES.ora文件解释。
我们查看TNSNAMES.ora文件,里面关于“I_AM_SERIVCE”有以下的内容:
I_AM_SERIVCE=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST =127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = mzoa)
)
)
在这里我们可以清晰看到关于这个“I_AM_SERIVCE”的名字的详细信息了。通过这个名字,我们可以请求数据库服务器所在地址:127.0.0.1,“服务”的名字是“mzoa”。
而端口号:1521正是我们这篇文章的主人公监听器(listener)正在监听的端口号。
通过以上信息,我们可以知道客户端的请求可以通过访问服务器“服务”的形式发送到监听器(listener)上。
第二类,服务器端:listener.ora。
内容以及解释如下:
# listener.ora Network Configuration File: D:\app\Administrator\product\11.2.0\dbhome_2\network\admin\listener.ora
# Generated by Oracle configuration tools.
#下面定义监听器(LISTENER)进程为哪个实例提供服务
#revised by kaiwii
SID_LIST_LISTENER =
(SID_LIST =
#实例描述条目1:
(SID_DESC = #被提供服务的实例;desc:description
(SID_NAME = CLRExtProc)
(ORACLE_HOME = D:\app\Administrator\product\11.2.0\dbhome_2)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\product\11.2.0\dbhome_2\bin\oraclr11.dll")
)
#实例描述条目2:
(SID_DESC = #被提供服务的实例;desc:description
(SID_NAME = mzoa)
(ORACLE_HOME = D:\app\Administrator\product\11.2.0\dbhome_2)
(GLOBAL_DBNAME = mzoa)
)
)
#一台数据库可以有不止一个监听器。接下来是,其中一个监听器的详细描述。
#这个监听器的名字为“LISTENER”,通过 “LISTENER =”来指定。
#再向下面就是指定监听器(“LISTENER”)所监听的位置(位置可以不止一个)。而某一个位置,我们可以通过
#设定监听的协议,ip,端口等信息来指明。#revised by kaiwii
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = SuDa-20110705FF)(PORT = 1521))
)
)
ADR_BASE_LISTENER = D:\app\Administrator
从中,我们不难发现,其实客户端中考究的“服务”名字貌似在服务器端不起什么作用。监听器都是通过监听某个host下的端口,得到客户端发来的请求的,然后,再将此请求发送到实例中去的。但是,到底是不是这回事。希望看到这篇文章的朋友,可以跟我交流一下。
三、修改监听器的信息
具体步骤,可以参考这篇文章:
oracle: listener.ora 、sqlnet.ora 、tnsnames.ora的配置及例子
接下来,就说说我自己的一些看法。
1、每次修改监听器所涉及到的三个配置文件:sqlnet.ora,tnsnames.ora,listener.ora,必须首先关闭监听器,修改成功后再打开。具体做法:a、windows用户可以通过关闭/开启服务的方式完成b、通过命令的方式
2、推荐通过修改配置文件的方式,完成修改工作。
好吧,就说这些,希望上面的内容对你有用!!!!!!!
http://g.51cto.com/database/23073
例如我们客户端输入
sqlplus sys/oracle@orcl
假如我的sqlnet.ora是下面这个样子
SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES,HOSTNAME)
那么,客户端就会首先在tnsnames.ora文件中找orcl的记录.如果没有相应的记录则尝试把orcl当作一个主机名,通过网络的途径去解析它的 ip地址然后去连接这个ip上GLOBAL_DBNAME=orcl这个实例,当然我这里orcl并不是一个主机名
如果我是这个样子
NAMES.DIRECTORY_PATH= (TNSNAMES)
那么客户端就只会从tnsnames.ora查找orcl的记录,括号中还有其他选项,如LDAP等并不常用。
2. Tnsnames.ora------这个文件类似于unix 的hosts文件,提供的tnsname到主机名或者ip的对应,只有当sqlnet.ora中类似
NAMES.DIRECTORY_PATH= (TNSNAMES) 这样,也就是客户端解析连接字符串的顺序中有TNSNAMES是,才会尝试使用这个文件。
PROTOCOL:客户端与服务器端通讯的协议,一般为TCP,该内容一般不用改。
HOST:数据库侦听所在的机器的机器名或IP地址,数据库侦听一般与数据库在同一个机器上,所以当我说数据库侦听所在的机器一般也是指数据库所在的机 器。在UNIX或WINDOWS下,可以通过在数据库侦听所在的机器的命令提示符下使用hostname命令得到机器名,或通过ipconfig(for WINDOWS) or ifconfig(for UNIX)命令得到IP地址。需要注意的是,不管用机器名或IP地址,在客户端一定要用ping命令ping通数据库侦听所在的机器的机器名,否则需要在 hosts文件中加入数据库侦听所在的机器的机器名的解析。
PORT:数据库侦听正在侦听的端口,可以察看服务器端的listener.ora文件或在数据库侦听所在的机器的命令提示符下通过lnsrctl status [listener name]命令察看。此处Port的值一定要与数据库侦听正在侦听的端口一样。
SERVICE_NAME:在服务器端,用system用户登陆后,sqlplus> show parameter service_name命令察看。
ORCL 对应的本机,SALES对应的另外一个IP地址,里边还定义了使用主用服务器还是共享服务器模式进行连接
ORCL =
(DESCRIPTION =
(ADDRESS_LIST =
#下面是这个TNSNAME对应的主机,端口,协议
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
)
(CONNECT_DATA =
#使用专用服务器模式去连接需要跟服务器的模式匹配,如果没有就根据服务器的模式自动调节
(SERVER = DEDICATED)
#对应service_name,SQLPLUS>;show parameter service_name; 进行查看
(SERVICE_NAME = orcl)
)
)
#下面这个类似
SALES =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.188.219)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = sales)
)
)
注意:如果数据库服务器用MTS,客户端程序需要用database link时最好明确指明客户端用dedicated直连方式,不然会遇到很多跟分布式环境有关的ORACLE BUG。一般情况下数据库服务器用直接的连接会好一些,除非你的实时数据库连接数接近1000。
关于listener进程就不多说了,接受远程对数据库的接入申请并转交给oracle的服务器进程。所以如果不是使用的远程的连接,listener进程就不是必需的,同样的如果关闭listener进程并不会影响已经存在的数据库连接。
Listener.ora文件的例子
#listener.ora Network Configuration File: #E:oracleproduct.1.0Db_2NETWORKADMINlistener.ora
# Generated by Oracle configuration tools.
#下面定义LISTENER进程为哪个实例提供服务 这里是ORCL,并且它对应的ORACLE_HOME和GLOBAL_DBNAME 其中GLOBAL_DBNAME不是必需的除非
#使用HOSTNAME做数据库连接
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = boway)
(ORACLE_HOME = E:oracleproduct.1.0Db_2)
(SID_NAME = ORCL)
)
)
#监听器的名字,一台数据库可以有不止一个监听器
#再向下面是监听器监听的协议,ip,端口等,这里使用的tcp1521端口,并且使#用的是主机名
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = boway)(PORT = 1521))
)
上面的例子是一个最简单的例子,但也是最普遍的。一个listener进程为一个instance(SID)提供服务。
监听器的操作命令
$ORACLE_HOME/bin/lsnrctl start,其他诸如stop,status等。具体敲完一个lsnrctl后看帮助。
$ORACLE_HOME/netca 向导形式的
$ORACLE_HOME/netmgr
本人比较习惯netmgr,
profile 配置的是sqlnet.ora也就是名称解析的方式
service name 配置的是tnsnames.ora文件
listeners配置的是listener.ora文件,即监听器进程
具体的配置可以尝试一下然后来看一下配置文件。
当你输入sqlplus sys/oracle@orcl的时候
1. 查询sqlnet.ora看看名称的解析方式,发现是TNSNAME
2. 则查询tnsnames.ora文件,从里边找orcl的记录,并且找到主机名,端口和service_name
3. 如果listener进程没有问题的话,建立与listener进程的连接。
4. 根据不同的服务器模式如专用服务器模式或者共享服务器模式,listener采取接下去的动作。默认是专用服务器模式,没有问题的话客户端就连接上了数据库的server process。
5. 这时候网络连接已经建立,listener进程的历史使命也就完成了。
几种连接用到的命令形式
1.sqlplus / as sysdba 这是典型的操作系统认证,不需要listener进程
2.sqlplus sys/oracle 这种连接方式只能连接本机数据库,同样不需要listener进程
3.sqlplus sys/oracle@orcl 这种方式需要listener进程处于可用状态。最普遍的通过网络连接。
以上连接方式使用sys用户或者其他通过密码文件验证的用户都不需要数据库处于可用状态,操作系统认证也不需要数据库可用,普通用户因为是数据库认证,所以数据库必需处于open状态。
init.ora中的Remote_Login_Passwordfile对身份验证的影响
三个可选值:
NONE:默认值,指示Oracle系统不使用密码文件,通过操作系统进行身份验证的特权用户拥有SYSORA和SYSOPER权限
EXCLUSIVE:
1.表示只有一个数据库实例可以使用密码文件
2.允许将SYSORA和SYSOPER权限赋值给SYS以外的其它用户
SHARED:
1.表示可以有多个数据库实例可以使用密码文件
2.不允许将SYSORA和SYSOPER权限赋值给SYS以外的其它用户
所以,如果要以操作系统身份登录,Remote_Login_Passwordfile应该设置为NONE
当登录用户不是ORA_DBA组和ORA_OPER组成员时,登录数据库需要在Oracle中创建当前操作系统用户相同的用户名,如果当前用户是域用 户,则名称为:domainnameyourname,如果是本地计算机用户,则名称为:computernameyourname
创建方法:
create "domainnameyourname" identified externally;
操作系统,修改HKEY_LOCAL_MACHINESOFTWAREORACLEHOME0下面添加AUTH_PREFIX_DOMAIN,值设为FALSE,在创建Oracle用户时可以忽略 掉域名
这种方式下,init.ora中有一个参数将影响数据库如何匹配一个windows用户和Oracle用户os_authent_prefix = ""
缺省为空,Oracle8i以前,无该参数,而使用OPS$作为用户名前缀.(Oracle用户名最大长度限制为30个字符)
/etc/hosts (UNIX)
或者windowshosts(WIN98) winntsystem32driversetchosts (WIN2000)
客户端需要写入数据库服务器IP地址和主机名的对应关系。
192.168.0.35 oracledb oracledb
192.168.0.45 tomcat tomcat
202.84.10.193 bj_db bj_db
但是sqlplus username/password@servicename不通,jdbc thin link 也不通的时候,
一定不要忘了在客户端做这一步,原因可能是DNS服务器里没有设置这个服务器IP地址和主机名的对应关系。
如果同时有私有IP和Internet上公有IP,私有IP写在前面,公有IP写在后面。
编辑前最好留一个备份,增加一行时也最好用复制粘贴,避免编辑hosts时空格或者tab字符错误。
ORACLE_SID=appdb;export ORACLE_SID
TWO_TASK=appdb;export TWO_TASK
来指定默认的目标数据库
平时排错可能会用到的
1.lsnrctl status查看服务器端listener进程的状态
LSNRCTL>; help
The following operations are available
An asterisk (*) denotes a modifier or extended command:
start stop status
services version reload
save_config trace change_password
quit exit set*
show*
LSNRCTL>; status
:em11:
2.tnsping 查看客户端sqlnet.ora和tnsname.ora文件的配置正确与否,及对应的服务器的listener进程的状态。
C:>tnsping orcl
TNS Ping Utility for 32-bit Windows: Version 10.1.0.2.0 - Production on 16-8月 -
2005 09:36:08
Copyright (c) 1997, 2003, Oracle. All rights reserved.
Used parameter files:
E:oracleproduct.1.0Db_2 etworkdminsqlnet.ora
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = 127.0.0.1)(PORT = 1521))) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_
NAME = orcl)))
OK (20 msec)
3.
SQL>;show sga 查看instance是否已经启动
SQL>; select open_mode from v$database; 查看数据库是打开还是mount状态。
OPEN_MODE
----------
READ WRITE
使用hostname访问数据库而不是tnsname的例子
使用tnsname访问数据库是默认的方式,但是也带来点问题,那就是客户端都是需要配置tnsnames.ora文件的。如果你的数据库服务器地址发生改变,就需要重新编辑客户端这个文件。通过hostname访问数据库就没有了这个麻烦。
需要修改
服务器端listener.ora
#监听器的配置文件listener.ora
#使用host naming则不再需要tnsname.ora文件做本地解析
# listener.ora Network Configuration File: d:oracleproduct.1.0db_1NETWORKADMINlistener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
# (SID_NAME = PLSExtProc)
(SID_NAME = orcl)
(GLOBAL_DBNAME = boway)
(ORACLE_HOME = d:oracleproduct.1.0db_1)
# (PROGRAM = extproc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = boway)(PORT = 1521))
)
)
客户端sqlnet.ora 如果确认不会使用TNSNAME访问的话,可以去掉TNSNAMES
# sqlnet.ora Network Configuration File: d:oracleproduct.1.0db_1NETWORKADMINsqlnet.ora
# Generated by Oracle configuration tools.
SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (HOSTNAME)
Tnsnames.ora文件不需要配置,删除也无所谓。
下面就是网络和操作系统的配置问题了,怎么样能够解析我的主机名的问题了
可以通过下面的方式连接
sqlplus sys/oracle@boway
这样的话,会连接boway这台服务器,并且listener来确定你所要连接的service_name
常见故障解决办法:
TNS-12154 (ORA-12154):TNS:could not resolve service name
该错误表示用于连接的网络服务名在tnsnames.ora文件中不存在,如上面的tnsnames.ora中的网络服务名只有test,假如用户在连接时用sqlplus system/manager@test1则就会给出TNS-12154错误。
要注意的是,有时即使在tnsnames.ora文件中有相应的网络服务名,可是用该网络服务名连接时还会出错,出现这种情况的典型配置如下(在客户端的机器上):
sqlnet.ora文件:
NAMES.DIRECTORY_PATH = (TNSNAMES, ….)
NAMES.DEFAULT_DOMAIN = server.com
tnsnames.ora文件:
test =
(DESCRIPTION=
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)
)
)
sql*plus运行基本机理:
在用户输入sqlplus system/manager@test后,sqlplus程序会自动到sqlnet.ora文件中找NAMES.DEFAULT_DOMAIN参数,假 如该参数存在,则将该参数中的值取出,加到网络服务名的后面,即此例中你的输入由sqlplussystem/manager@test自动变为sqlplus system/manager@test.server.com ,然后再到tnsnames.ora文件中找test.server.com网络服务名,这当然找不到了,因为该文件中只有test网络服务名,所以报 错。解决的办法就是将sqlnet.ora文件中的NAMES.DEFAULT_DOMAIN参数注释掉即可,如 #NAMES.DEFAULT_DOMAIN = server.com。假如NAMES.DEFAULT_DOMAIN参数不存在,则sqlplus程序会直接到tnsnames.ora文件中找 test网络服务名,然后取出其中的host,port,tcp,service_name,利用这些信息将连接请求发送到正确的数据库服务器上。
另外原则上tnsnames.ora中的配置不区分大小写,但是我的确遇到区分大小写的情况,所以最好将使用的网络服务与tnsnames.ora中配置的完全一样。
ORA-12514: TNS:listener could not resolve SERVICE_NAME given in connect Descriptor.
该错误表示能在tnsnames.ora中找到网络服务名,但是在tnsnames.ora中指定的SERVICE_NAME与服务器端的 SERVICE_NAME不一致。解决的办法是修改tnsnames.ora中的SERVICE_NAME。
易混淆术语介绍:
Db_name:对一个数据库(Oracle database)的唯一标识,该数据库为Oracle database。这种表示对于单个数据库是足够的,但是随着由多个数据库构成的分布式数据库的普及,这种命令数据库的方法给数据库的管理造成一定的负 担,因为各个数据库的名字可能一样,造成管理上的混乱。为了解决这种情况,引入了Db_domain参数,这样在数据库的标识是由Db_name和 Db_domain两个参数共同决定的,避免了因为数据库重名而造成管理上的混乱。这类似于互连网上的机器名的管理。我们将Db_name和 Db_domain两个参数用’.’连接起来,表示一个数据库,并将该数据库的名称称为Global_name,即它扩展了Db_name。 Db_name参数只能由字母、数字、’_’、’#’、’$’组成,而且最多8个字符。
Db_domain:定义一个数据库所在的域,该域的命名同互联网的’域’没有任何关系,只是数据库管理员为了更好的管理分布式数据库而根据实际情况决定的。当然为了管理方便,可以将其等于互联网的域。
Global_name:对一个数据库(Oracle database)的唯一标识,oracle建议用此种方法命令数据库。该值是在创建数据库是决定的,缺省值为Db_name. Db_domain。在以后对参数文件中Db_name与Db_domain参数的任何修改不影响Global_name的值,如果要修改 Global_name,只能用ALTER DATABASE RENAME GLOBAL_NAME TO <db_name.db_domain>命令进行修改,然后修改相应参数。
Service_name:该参数是oracle8i新引进的。在8i以前,我们用SID来表示标识数据库的一个实例,但是在Oracle的并行环境中, 一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了Service_name参数,该参数对应一个数据库, 而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为Db_name. Db_domain,即等于Global_name。一个数据库可以对应多个Service_name,以便实现更灵活的配置。该参数与SID没有直接关 系,即不必Service name 必须与SID一样。
Net service name:网络服务名,又可以称为数据库别名(database alias)。是客户端程序访问数据库时所需要,屏蔽了客户端如何连接到服务器端的细节,实现了数据库的位置透明的特性。
如何利用配置的网络服务名连接到数据库:
用sqlplus程序通过test网络服务名进行测试,如sqlplus system/manager@test。如果不能连接到数据库,则在tnsname.ora文件中的test网络服务名(net service)后面加上Oracle数据库的DB_Domain参数值,通过用sqlplus> show parameter db_domain命令察看。此处db_domain参数值为testserver.com,将其加到网络服务名后面,修改后的tnsname.ora中 关于该网络服务名的内容为:
应该改为:
如何利用配置的网络服务名连接到数据库:
用sqlplus程序通过test网络服务名进行测试,如果不能连接到数据库,则在tnsname.ora文件中的test网络服务名(net service)后面加上sqlnet.ora文件中NAMES.DEFAULT_DOMAIN参数的值,此处我的参数值为 testserver.com,将其加到网络服务名后面,修改后的tnsname.ora中关于该网络服务名的内容为:
出现这种情况的典型环境为windows的客户端的‘我得电脑à属性à计算机名à更改à其它…à此计算机的主DNS后缀’中设置了‘primary dns suffix’,因为在这种情况下安装客户端时,会在sqlnet.ora文件中自动设置NAMES.DEFAULT_DOMAIN参数,或许当把计算机 加入域中安装oracle客户端时也会出现这种情况,有条件的话大家可以试一下。
在用oracle的图形配置软件''net assistant''或‘Net Configuration Assistant’配置网络服务名时,假如已经设置了‘primary dns suffix’,但是在图形配置软件中写的网络服务名的名字中没有‘primary dns suffix’,如只是写了test,则图形配置软件会自动在后面加上‘primary dns suffix’,使之变为test.testserver.com,并存在tnsnames.ora中,而不管你的sqlnet.ora文件中是否有 NAMES.DEFAULT_DOMAIN参数。此时,用图形工具进行测试连接是通过的,但是假如此时sqlnet.ora文件中没有 NAMES.DEFAULT_DOMAIN参数,则你在使用网络服务名时应该使用在tnsnames.ora中的 test.testserver.com,而不是你在图形配置软件中键入的test。解决的办法为:
<1>可以在sqlnet.ora文件中设置NAMES.DEFAULT_DOMAIN= testserver.com,这时你可以用test或test.testserver.com连接数据库
<2>在sqlnet.ora文件中不设置NAMES.DEFAULT_DOMAIN参数,在tnsnames.ora文件中将 test.testserver.com中的.testserver.com去掉,这时你可以用test连接数据库
文档说明:
1)、对于oracle网络写的不是很全,有的地方可能有误,希望大家多多提出意见!
2)、本文档适合有一定oracle基础的人员阅读。
3)、此文档解决了oracle监听的基本配置、一些网络组件的基本概念、常见问题排错方法、怎么配置动态监听和静态监听以及非默认监听、安装多个实例时如何配置监听
4)、如果对监听很感兴趣请参考oracle 官方联机文档,已经打包。
Oracle® Database
Net Services Administrator's Guide
11g Release 2 (11.2)
E10836-06
Oracle® Database
Net Services Reference
11g Release 2 (11.2)
E10835-05
1、数据库监听配置
1.1监听器(LISTENER)
监听器是Oracle基于服务器端的一种网络服务,主要用于监听客户端向数据库服务器端提出的连接请求。既然是基于服务器端的服务,那么它也只存在于数据库服务器端,进行监听器的设置也是在数据库服务器端完成的。
1.2本地服务名(Tnsnames)
Oracle客户端与服务器端的连接是通过客户端发出连接请求,由服务器端监听器对客户端连接请求进行合法检查,如果连接请求有效,则进行连接,否则拒绝该连接。
本地服务名是Oracle客户端网络配置的一种,另外还有Oracle名字服务器(Oracle Names Server)等。Oracle常用的客户端配置就是采用的本地服务名,本文中介绍的也主要是基于本地服务名的配置。以下的例子都是以oracle 11g r2为例。
1.3 Oracle网络连接配置方法
配置Oracle服务器端与客户端都可以在其自带的图形化Oracle网络管理器(Oracle Net Manager)里完成(建议在图形化的工具下完成Oracle服务端或客户端的配置)。在Windows下,点击“开始/程序/Oracle – Ora11gHome/Configuration and Migration Tools/Net Manager”启动Oracle网络管理器工具,在Linux/Unix下(windows 是在cmd命令窗口),利用netmgr命令来启动图形化Oracle网络管理器,如:
[oracle@resoft Desktop]$ netmgr
Linux RHEL6.0下启动Net Manager图形窗口如下图示:
图(一)
1.4 Oracle监听器配置(LISTENER)
如 图(一)示,选中树形目录中监听程序项,再点击左上侧“+”按钮添加监听程序,点击监听程序目录,默认新加的监听器名称是LISTENER(该名称也可以 由任意合法字符命名)。选中该名称,选中窗口右侧栏下拉选项中的“监听位置”,点击添加地址按钮。在出现的网络地址栏的协议下拉选项中选中 “TCP/IP”,主机文本框中输入主机名称或IP地址(如果主机即用作服务端也作为客户端,输入两项之一均有效;如果主机作为服务端并需要通过网络连 接,建议输入IP地址),端口文本框中输入数字端口,默认是1521,也可以自定义任意有效数字端口。配置好的监听位置如下图示:
图(二)
选 中窗口右侧栏下拉选项中的“数据库服务”,点击添加数据库按钮。在出现的数据库栏中输入全局数据库名,如myoracle。注意这里的全局数据库名与数据 库SID有所区别,全局数据库名实际通过域名来控制在同一网段内数据库全局命名的唯一性,就如Windows下的域名控制器,如这里可以输入 myoracle。Oracle主目录填写oracle home地址我这里是/u01/app/oracle/product/11.2.0/dbhome_1,输入SID,如ORCL。完整的数据库服务配置如下图示:
图(三)
保 存以上配置,默认即可在Oracle安装目录下找到监听配置文件 (Windows下如D:\oraclec\product\11.2.0\orcl\network\admin Linux/Unix下$ ORACLE_HOME/network/admin/listener.ora)。至此,Oracle服务端监听器配置已经完成。
服务器端监听(listener.ora)还是比较好配置的,大部分情况下在数据库安装完成时已经根据向导配置好了。
1.5 本地服务名配置(Tnsnames)
本 地服务名是基于Oracle客户端的网络配置,所以,如果客户端需要连接数据库服务器进行操作,则需要配置该客户端,其依附对象可以是任意一台欲连接数据 库服务器进行操作的pc机,也可以是数据库服务器自身。在客户端配置tnsnames时首先确保oracle客户端已经安装(下载地址:http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.htm)如前面所介绍,可以利用Oracle自带的图形化管理工具Net Manager来完成Oracle客户端的配置。选中如图(一)中的服务命名,再点击左上侧“+”按钮,弹出如下图示对话框:
图(四)
输入Net服务名,如myoracle,点击下一步,进入下图示对话框:
图(五)
选中TCP/IP(Internet协议),点击下一步,如下图示:
图(六)
输入主机名与端口号。注意这里的主机名与端口号必须与数据库服务器端监听器配置的主机名和端口号相同,主机名可以是IP也可以是主机名。点击下一步,如下图示:
图(七)
输入服务名。这里的服务名实际上就是数据库服务器端监听器配置中的全局数据库名,前者与后者必须相同。服务名(service name)必须写正确。查看服务名方法:SQL> select value from v$parameter where name = 'service_names';
连接类型 通常选专用服务器,这要视数据库服务器的配置而定,如果配置的共享数据库服务器,这里的连接类型就要选共享服务器,否则建议选专用服务器(关于专用服务器 的介绍请参阅相关文档)。配置好后点击下一步,如下图示:
图(八)
如 果数据库服务器端相关服务启动了,可以点击测试按钮进行连接测试。Oracle默认是通过scott/tiger用户进行测试连接,由于scott用户是 Oracle自带的示例用户,对于正式的业务数据库或专业测试数据库可能没有配置这个用户,所以需要更改成有效的用户登录才可能测试成功。如果这里测试连 接不成功,也不要紧,先点完成按钮结束配置。
回 到Oracle网络管理器(Oracle Net Manager)主窗口,保存配置,默认即可在Oracle安装目录下找到本地服务名配置文件 (Windows下如: D:\oraclec\product\11.2.0\orcl\network\admin\tnsnames.ora Linux/Unix下$ ORACLE_HOME/network/admin/tnsnames.ora)。配置完成的本地服务名如下图示:
图(九)
树形目录下的服务命名可以通过编辑菜单里的重命名菜单更改成任意合法字符组成的服务名称,注意服务名称前不能有空格字符,否则可能无法连接数据库服务器。
1.6 连接数据库服务器
(1) 启动服务器端监听器与数据库服务
Linux/Unix下,启动监听器:
$ lsnrctl start
关闭监听器:
$ lsnrctl stop
查看监听状态:
$ lsnrctl status
启动数据库:
$ sqlplus /nolog
SQL>conn sys@myoracle as sysdba --这里的myoracle是前面配置的客户端本地服务名
或
SQL>conn / as sysdba
SQL>startup
Windows下,启动监听器:
C: lsnrctl start
以上服务必须同时启动,客户端才能连接数据库。由于默认配置的监听器名称是Listener,上述命令可以正常启动监听器,如果监听器名称是其它名称,如aListener,则需要用下列方式才能启动:
Linux/Unix下:
$ lsnrctl start aListener
Windows下:
C:lsnrctl start aListener
(2) 测试连接数据库服务器
测试的方法多种多样,可以在上面配置本地服务名时进行测试,也可以是第三方客户端工具,如PL/SQL Developer,最方便的是用Oracle自带的sqlplus工具,以下利用sqlplus进行测试:
[oracle@resoft Desktop]$ sqlplus /nolog
SQL*Plus: Release 11.2.0.3.0 Production on Tue Feb 19 17:06:32 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
SQL> conn scott/tiger@myoracle
Connected.
2、oracle listener动态注册和静态注册
也就是我们经常说的静态监听和动态监听
2.1 什么是注册
注册就是将数据库作为一个服务注册到监听程序。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库。这个服务名可能与实例名一样,也有可能不一样。比如上面查看到的服务名就是:SQL> select value from v$parameter where name = 'service_names';
VALUE
--------------------------------------------------------------------------------
ORCL
在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务(无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。)
相当于是这样:在数据库服务器和客户端之间有一监听程序(Listener),在监听程序中,会记录相应数据库对应的服务名(一个数据库可能对应有多个服务名),当客户端需要连接数据库时,只需要提供服务名,就可以建立客户端和服务器之间的连接。
2.2 动态注册
动态注册是在instance启动的时候PMON进程根据init.ora(服务器参数文件)中instance_name,service_names两个参数将实例和服务动态注册到listener中。
首先要在init.ora中指定instance_name,service_names两个参数的值。在sqlplus下通过show parameter service_names 和show parameter instance_name可以查看这两个参数的值。
注册到监听器中的实例值从init.ora文件中的instance_name参数取得。如果该参数没有设定值,那么它将取init.ora文件中的db_name的值。如果在RAC中配置,您必须将集群中每个实例的instance_name参数设置为一个唯一的值。
注册到监听器中的服务值从init.ora文件中的参数service_names取得。如果该参数没有设定值,数据库将拼接init.ora文件中的 db_name和db_domain的值来注册自己。如果选择提供service_names值,您可以使用完全限定的名称(比如 orcl.oracle.com)或缩写的名称(比如orcl)。如果选择缩写的名称并设置了db_domain参数,注册到监听器中的服务将是 service_name值和db_domain值的拼接。例如下面的设置将导致服务orcl.oracle.com被注册到监听器中:
db_domain=oracle.com
service_names=orcl ;
采取动态注册方法时,listener.ora中的内容如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(PROGRAM = extproc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
可选择的是,您可以在service_names参数中指定多个服务值,值之间用逗号格开,这对于共享服务器配置是很有用的。
动态注册默认只注册到默认的监听器上(名称是LISTENER、端口是1521、协议是TCP),因为pmon只会动态注册port等于1521的监听,否则pmon不能动态注册listener,如果需要向非默认监听注册,则需要配置local_listener参数!
将监听的信息添加到tnsnames.ora 文件中。 注意,是tnsnames.ora 文件, 因为pmon在动态注册监听时要从tnsnames.ora中读取相关信息。
如果没有显式设置service_names和instance_name的值,那么仅当数据库在监听器运行之后启动时,动态注册才会发生;在这种情况下,如果监听器后来发生了重启,动态注册信息将会丢失。显然,最好在所有的数据库启动之前先启动监听器,这样就会避免没有显式设置 service_names和instance_name的值时,若重启监听器带来的动态注册信息丢失的情况。
为初始化参数service_names和instance_name设置显式的值是个很好的实践,尽管如果您没有设置它们,Oracle也会为动态注册而生成默认值(基于db_name和db_main)。这样做的原因是,如果监听器在数据库启动之后重新启动,其动态注册行为将会有一些微妙的区别.如果监听器在数据库运行之后重新启动,你们仅当您在init.ora文件中显式地设置了service_names和instance_name的值时,每个数据库的PMON进程才会在很短的时间之后自动注册数据库。
如果需要执行连接时故障转移或负载均衡,或者想要在RAC中配置在实例之间透明地分布连接,那么使用service_names参数将是必要的。为启用这些功能,您只需要将每个实例的数据库参数文件中的service_names设置为同一个值,并在客户端连接请求的service_name设置中引用该值。
如果没有显式设置service_names和instance_name的值,那么仅当数据库在监听器运行之后启动时,动态注册才会发生;在这种情况下,如果监听器后来发生了重启,动态注册信息将会丢失。显然,最后在启动任何数据库之前启动服务器上的监听器,并完全避免监听器的重启。
另外,您还可以在SQL*PLUS中使用命令:
SQL>ALTER SYSTEM REGISTER;
在数据库打开时的任何时候,手工地在监听器中注册服务值。这个命令对于替换因监听器重启而丢失地服务值很有用,并且它所注册地值与在数据库启动时由动态注册所设置的值完全一样。
动态监听:
oracle监听器运行后,oracle实例在open时,会动态向监听程序注册其service_names和instance_name。
其中instance_name默认是:db_name
而service_names默认是:db_name.db_domain
2.3 静态注册
静态注册就是实例启动时读取listener.ora文件的配置,将实例和服务注册到监听程序。无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务。
静态注册时,listener.ora中的GLOBAL_DBNAME向外提供服务名,listener.ora中的SID_NAME提供注册的实例名。
采取静态注册方法时,listener.ora中的内容如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = myoracle)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(SID_NAME = ORCL)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1521))
)
)
该文件表明数据库是单实例的,实例名为orcl,向外提供了1个服务:ORCL
静态监听:
oracle实例运行后,监听程序启动时,根据listener.ora的配置注册相应的服务。
其中global_dbname对应的是oracle对外的服务名,即初始化参数里的service_names
而sid_name对应的是oralce实例的名称,即初始化参数里的instance_name
既然有动态监听为什么还要静态监听呢?原因如下:
1).监听器不是最早启动,oracle实例先启动
2).监听器重启
3).oracle实例没有open
2.4查询某服务是静态注册还是动态注册
可以使用命令lsnrctl status来查看某服务是静态注册还是动态注册。
实例状态为UNKNOWN值时表明此服务是静态注册的设置。这时监听器用来表明它不知道关于该实例的任何信息,只有当客户发出连接请求时,它才检查该实例是否存在。
动态注册的数据库通过状态信息中的状态READY或状态BLOCKED(对于一个备用数据库)来指明。举例:已经注册的动态监听(最常用)
[oracle@resoft admin]$ lsnrctl status
LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 19-FEB-2013 18:11:48
Copyright (c) 1991, 2011, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=resoft)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 11.2.0.3.0 - Production
Start Date 19-FEB-2013 22:48:26
Uptime 248 days 13 hr. 13 min. 56 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/resoft/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=resoft)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "ORCL" has 1 instance(s).
Instance "ORCL", status READY, has 1 handler(s) for this service...
Service "ORCLXDB" has 1 instance(s).
Instance "ORCL", status READY, has 1 handler(s) for this service...
The command completed successfully
不管何时关闭数据库,动态注册的数据库都会动态地从 监听器注销,而与之相关的信息将从状态列表中消失。这样,不管数据库是在运行还是已经关闭,监听器总是知道它的状态。该信息将被用于连接请求的回退(fallback)和负载平衡。
3、配置非默认监听
上面配置的监听都是默认监听 监听名:listener 端口:1521 这是会自动注册的,但是实际生产中基本上都是非默认监听。
以下测试直接修改服务器端监听文件listener.ora或者tnsnames.ora
目前测试数据库上已经有实例ORCL现在创建一个新的实例UPRR,设置监听名字listener1 端口1522
3.1 使用dbca数据库向导创建一个新实例UPRR
其它步骤省略,如下图所示:
3.2 配置服务器端监听
在listener.ora文件中添加以下内容
SID_LIST_LISTENER1 =
(SID_LIST =
(SID_DESC =
(SID_NAME = UPRR)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(PROGRAM = extproc)
)
)
LISTENER1 =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1522))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
3.3 注册非默认监听
然后以sys用戶运行:
[oracle@resoft admin]$ export ORACLE_SID=UPRR
[oracle@resoft admin]$ sqlplus / as sysdba
SQL> alter system set local_listener=listener1 scope=spfile;
SQL> alter system register;
或者:
SQL> alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1522))';
SQL> alter system register;
系统已更改。
3.4 在tnsnames.ora中添加解析文件
Tnsnames.ora中添加以下内容
UPRR =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1522))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = UPRR)
)
)
SID_LIST_LISTENER1 =
(SID_LIST =
(SID_DESC =
(SID_NAME = UPRR)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(PROGRAM = extproc)
)
)
LISTENER1 =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1522))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
3.5 启动非默认监听listener1
[oracle@resoft admin]$ lsnrctl
LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 19-FEB-2013 19:40:23
Copyright (c) 1991, 2011, Oracle. All rights reserved.
Welcome to LSNRCTL, type "help" for information.
LSNRCTL> stop listener --先关闭之前已经启动的监听listener
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=resoft)(PORT=1521)))
The command completed successfully
LSNRCTL> start listener1
Starting /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 11.2.0.3.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/resoft/listener1/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=resoft)(PORT=1522)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=resoft)(PORT=1522)))
STATUS of the LISTENER
------------------------
Alias listener1
Version TNSLSNR for Linux: Version 11.2.0.3.0 - Production
Start Date 19-FEB-2013 19:41:04
Uptime 0 days 0 hr. 0 min. 1 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/resoft/listener1/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=resoft)(PORT=1522)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "UPRR" has 1 instance(s).
Instance "UPRR", status UNKNOWN, has 1 handler(s) for this service... –此时监听的状态是没有注册,重启下数据库实例UPRR即可
The command completed successfully
3.6 重启实例
SQL> startup
ORACLE instance started.
Total System Global Area 636100608 bytes
Fixed Size 1346812 bytes
Variable Size 184550148 bytes
Database Buffers 444596224 bytes
Redo Buffers 5607424 bytes
Database mounted.
Database opened.
SQL> show parameter listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
listener_networks string
local_listener string LISTENER1
remote_listener string
[oracle@resoft admin]$ lsnrctl status listener1
LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 19-FEB-2013 19:52:18
Copyright (c) 1991, 2011, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=resoft)(PORT=1522)))
STATUS of the LISTENER
------------------------
Alias listener1
Version TNSLSNR for Linux: Version 11.2.0.3.0 - Production
Start Date 19-FEB-2013 19:41:04
Uptime 0 days 0 hr. 11 min. 14 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/resoft/listener1/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=resoft)(PORT=1522)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "UPRR" has 2 instance(s).
Instance "UPRR", status UNKNOWN, has 1 handler(s) for this service...
Instance "UPRR", status READY, has 1 handler(s) for this service...
Service "UPRRXDB" has 1 instance(s).
Instance "UPRR", status READY, has 1 handler(s) for this service...
The command completed successfully
至此,配置非默认监听结束。环境中在同一个数据库软件上安装两个实例:ORCL和UPRR。
ORCL使用监听listener 端口1521 UPRR 使用listener1 端口1522
3.7 同时启动两个实例和两个监听
刚才看到了在启动listener1的时候必须把listener关闭,其实可以让实例ORCL和UPRR使用一个监听listener 但是ORCL使用1521端口,UPRR使用1522端口。
修改后的listener.ora文件如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(SID_NAME = ORCL)
)
(SID_DESC =
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(SID_NAME = UPRR)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1521))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1522))
)
)
修改完listener.ora后,把内容贴到tnsnames.ora中
3.8 使用远程PC测试
在我本机oracle client 的tnsnames.ora中添加如下内容:
注意:别名如:ORCL第一行要顶格写
ORCL =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.220.200)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = ORCL)
)
)
UPRR =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.220.200)(PORT = 1522))
)
(CONNECT_DATA =
(SERVICE_NAME = UPRR)
)
)
使用sqlplus 登录连个实例
C:\>sqlplus scott/tiger@orcl
SQL*Plus: Release 11.2.0.1.0 Production on 星期二 2月 19 20:45:53 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> exit
从 Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options 断开
C:\>sqlplus scott/tiger@uprr
SQL*Plus: Release 11.2.0.1.0 Production on 星期二 2月 19 20:46:05 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
4、Orace 监听配置修改说明
4.1 监听日志说明
Oracle的监听(Listener)在缺省情况下,会在文件中记录日志,记录数据库实例注册操作、客户端的连接等。
Oracle 11g中的信息如下:
[oracle@dave ~]$ lsnrctl status
LSNRCTL for Linux: Version 11.2.0.3.0 - Productionon 22-DEC-2012 21:36:43
Copyright (c) 1991, 2011, Oracle. All rights reserved.
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version11.2.0.3.0 - Production
Start Date 22-DEC-2012 21:31:53
Uptime 0 days 0 hr. 4 min. 50 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/dave/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.4)(PORT=1521)))
Services Summary...
Service "dave" has 2 instance(s).
Instance "dave", status UNKNOWN, has 1 handler(s) for thisservice...
Instance "dave", status READY, has 1 handler(s) for thisservice...
Service "daveXDB" has 1instance(s).
Instance "dave", status READY, has 1 handler(s) for thisservice...
The command completed successfully
这个是Oracle 11g里的listener 的保存位置。在Oracle 11g中使用的是ADR,ADR是11G的新特性,欲详细了解百度之。
这里是个xml文件,不方便文件,我们可以去trace目录下,看文本格式的:
[oracle@dave trace]$ pwd
/u01/app/oracle/diag/tnslsnr/dave/listener/trace
[oracle@dave trace]$ ls
listener.log
[oracle@dave trace]$
[oracle@dave trace]$ tail -20 listener.log
Sat Dec 22 21:33:39 2012
22-DEC-2012 21:33:39 * service_update *dave * 0
22-DEC-2012 21:33:42 * service_update *dave * 0
22-DEC-2012 21:33:45 * service_update *dave * 0
Sat Dec 22 21:34:18 2012
22-DEC-2012 21:34:18 * service_update *dave * 0
22-DEC-2012 21:34:21 * service_update *dave * 0
22-DEC-2012 21:34:24 * service_update *dave * 0
22-DEC-2012 21:34:27 * service_update *dave * 0
Sat Dec 22 21:34:48 2012
22-DEC-2012 21:34:48 * service_update *dave * 0
Sat Dec 22 21:35:06 2012
22-DEC-2012 21:35:06 * service_update *dave * 0
Sat Dec 22 21:36:18 2012
22-DEC-2012 21:36:18 * service_update *dave * 0
Sat Dec 22 21:36:43 2012
WARNING: Subscription for node down eventstill pending
22-DEC-2012 21:36:43 *(CONNECT_DATA=(CID=(PROGRAM=)(HOST=dave)(USER=oracle))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER)(VERSION=186647296))* status * 0
Sat Dec 22 21:37:34 2012
22-DEC-2012 21:37:34 * service_update *dave * 0
对于一些使用短连接的,频繁的连接数据库的应用,listener.log增长很快。有的可以在比较短的时间内(十几天)就可以超过2GB。对于一些平台的某些版本的Oracle,在监听日志增大到2GB以后会导致监听不能正常工作。
对于这种listener.log增长非常迅速的系统,可以关闭监听日志,不让监听写日志到文件。也可以写个job定期清理。
关于Oracle Listener 的说明,官网有更多详细描述。
Listener Control Utility
http://docs.oracle.com/cd/E11882_01/network.112/e10835/lsnrctl.htm#NETRF118
这里我们看2个比较常用的操作。
4.2停止写listener log
在某些特定的场合可能会有这样的需求。控制这个功能的参数是LOG_STATUS。 官网对这个参数的说明:To turn listenerlogging on or off.
--在OS层面直接使用:
lsnrctl SET LOG_STATUS {on | off}
--在LSNRCTL 工具中使用:
LSNRCTL> SET LOG_STATUS {on | off}
--查看log_status状态:
LSNRCTL> show log_status
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
LISTENER parameter "log_status"set to ON
The command completed successfully
说明:
之前遇到一个很奇怪的问题,就是log_status状态是on,但是listener就是不写日志,再次手工设置为on后,又正常写日志。
LSNRCTL> setlog_status off
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
LISTENER parameter "log_status"set to OFF
The command completed successfully
LSNRCTL> showlog_status
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
LISTENER parameter "log_status"set to OFF
The command completed successfully
LSNRCTL> setlog_status on
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
LISTENER parameter "log_status"set to ON
The command completed successfully
LSNRCTL> showlog_status
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
LISTENER parameter "log_status" setto ON
The command completed successfully
4.3 保存listener 的修改
保存又参数:SAVE_CONFIG控制,官网的说明:
To save the current configuration state of the listener, includingtrace level, trace file, trace directory, and logging tothe listener.ora file. Any changes are stored in listener.ora,preserving formatting, comments, and case as much as possible. Beforemodification of the listener.ora file, a backup of the file,called listener.bak, is created.
我们在第一部分修改了log_status 的配置,如果没有保存,那么在重启监听之后,修改就会失效,所以这里要保存,才能永久的生效。
LSNRCTL> save_config
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
Saved LISTENER configuration parameters.
Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
Old Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.bak
The command completed successfully
注意:
这里使用的是默认的listner,如果不是默认的,就需要加上listener_name. 如:
LSNRCTL> SAVE_CONFIG listener_name
保存之后,修改的内容就会写入listener.ora 文件。
这里是我的的测试环境,其中listener.ora 文件多了如下内容:
/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
#----ADDED BY TNSLSNR 22-DEC-201221:59:58---
LOGGING_LISTENER = ON
#--------------------------------------------
4.4 加密listener
有时候处于安全考虑,会需要对listener设置密码。
4.4.1 设置监听名
如果有多个监听,那么需要先设置当前的监听
LSNRCTL>set current_listener listener_name
4.4.2设置密码
使用change_password设置listener口令。
LSNRCTL> change_password
Old password: --如果原来没有设置口令就直接回车,否则输入原来的口令
New password:
Reenter new password:
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
Password changed for LISTENER
The command completed successfully
--保存密码:
LSNRCTL> save_config
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
Saved LISTENER configuration parameters.
Listener Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
Old Parameter File /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.bak
The command completed successfully
--加密之前:
[oracle@dave ~]$ lsnrctl status
LSNRCTL for Linux: Version 11.2.0.3.0 -Production on 22-DEC-2012 22:54:55
Copyright (c) 1991, 2011, Oracle. All rights reserved.
Connecting to(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version11.2.0.3.0 - Production
Start Date 22-DEC-2012 21:57:46
Uptime 0 days 0 hr. 57 min. 9 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/dave/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.4)(PORT=1521)))
Services Summary...
Service "dave" has 2 instance(s).
Instance "dave", status UNKNOWN, has 1 handler(s) for thisservice...
Instance "dave", status READY, has 1 handler(s) for thisservice...
Service "daveXDB" has 1instance(s).
Instance "dave", status READY, has 1 handler(s) for thisservice...
--加密之后:
LSNRCTL> status
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.4)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version11.2.0.3.0 - Production
Start Date 22-DEC-2012 22:56:19
Uptime 0 days 0 hr. 11 min. 2 sec
Trace Level off
Security ON: Password or Local OSAuthentication
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/dave/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.4)(PORT=1521)))
Services Summary...
Service "dave" has 2 instance(s).
Instance "dave", status UNKNOWN, has 1 handler(s) for thisservice...
Instance "dave", status READY, has 1 handler(s) for thisservice...
Service "daveXDB" has 1instance(s).
Instance "dave", status READY, has 1 handler(s) for this service...
The command completed successfully
--在listener.ora 文件中也会多一个配置参数:
[oracle@dave ~]$ cat/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
…
#----ADDED BY TNSLSNR 22-DEC-201221:59:58---
LOGGING_LISTENER = ON
#--------------------------------------------
#----ADDED BY TNSLSNR 22-DEC-201223:06:31---
PASSWORDS_LISTENER =1DF5C2FD0FE9CFA2
#--------------------------------------------
[oracle@dave ~]$
4.4.3 解除密码
listener的密码策略是防止stop,所以在stop时需要确认密码,在start时不需要输入密码。
LSNRCTL> set password
Password:
The command completed successfully
使用set password输入正确的密码后,就可以进行stop操作了。
5、oracle sqlnet.ora说明
sqlnet.ora作用类似于linux或者其他unix的nsswitch.conf文件,通过这个文件来决定怎么样找一个连接中出现的连接字符串。可以没有此文件。
例如我们客户端输入
sqlplus system/oracle@orcl
假如我的sqlnet.ora是下面这个样子
SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES,HOSTNAME)
那么,客户端就会首先在tnsnames.ora文件中找orcl的记录.如果没有相应的记录则尝试把orcl当作一个主机名,通过网络的途径去解析它的 ip地址然后去连接这个ip上GLOBAL_DBNAME=orcl这个实例,当然我这里orcl并不是一个主机名
如果我是这个样子
NAMES.DIRECTORY_PATH= (TNSNAMES)
那么客户端就只会从tnsnames.ora查找orcl的记录,括号中还有其他选项,如LDAP等并不常用。
Sqlnet.ora还有一个重要作用就是限制IP访问Oracle。与防火墙类似的功能,Oracle 提供限制与允许特定的IP或主机名通过Oracle Net来访问数据库。这个功能由sqlnet.ora配置文件来实。通过监听器的限制,比在数据库内部通过触发器进行限制效率要高。
限制IP例子:
通过在sqlnet.ora文件中增加下列记录来实现
tcp.validnode_checking = yes
tcp.invited_nodes = (hostname1, hostname2,ip1,ip2)
tcp.excluded_nodes = (10.103.11.17,hostname1,hostname2)
tcp.validnode_checking = yes
tcp.invited_nodes = (hostname1, hostname2,ip1,ip2)
tcp.excluded_nodes = (10.103.11.17,hostname1,hostname2)
当使用invited_nodes时,则所有没有包含在invited_nodes值中的IP或主机将无法通过Oracel Net连接到数据库。而如果使用excluded_nodes时,除了excluded_nodes值中列出的IP和主机不可访问之外,其余的节点都可以访问数据库。通常情况下,更倾向于使用excluded_nodes参数。
6、其它oracle network配置说明
工作压力关系,在这里不再介绍,有兴趣参考官方文档
Oracle® Database Net Services Administrator's Guide 11g Release 2
7、常见的问题排除方法
7.1 ora-01031:insufficient privileges
sqlplus "/ as sysdba" 连不上,报ora-01031:insufficient privileges解决方法
注意多个数据库实例时候,set ORACLE_SID='',
1)、检查sqlnet.ora(WINDOWS下位于%ORACLE_HOME%NETWORKADMIN目录)是否包含这句:SQLNET.AUTHENTICATION_SERVICES=(NTS),没有的话加上
2)、检查登陆windows的用户(administrator或安装oracle时候使用的用户)是不是在包含在ORA_DBA组中,域用户没有连上域服务器时就可能出现这种现象。
3)、 要保证 remote_login_passwordfile 参数 = EXCLUSIVE .
4)、看看是否需要使用orapassw生成口令文件 .
一种解决方法案例:
(1)、检查系统参数:
SQL> show parameter password
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_login_passwordfile string EXCLUSIVE
(2)、
select * from v$pwfile_users;
SQL>
为空
(3)、
SQL> grant sysdba to sys;
grant sysdba to sys
*
ERROR at line 1:
ORA-01994: GRANT failed: password file missing or disabled
(4)、建立password文件
D:/>orapwd file="D:/oracle/product/10g/db_1/database/PWDoratest.ora" password=gp
oswong entries=10
(5)、
SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
------------------------------ ----- -----
SYS TRUE TRUE
SYS正常显示出来。
(6)、重新在远程以SYSDBA登录,可正常使用。
如果口令文件创建的有问题,也是会报如下的错误:
ora-01031:insufficient privileges
口令文件的命名格式应为orapwsid,并且sid是区分大小写的。由于Target Database连接Auxiliary Database时需要验证口令,
如果违反了以上规则,将会提示ORA-01031: insufficient privileges。
我在用linux创建duplicate数据库的时候 就是因为口令文件创建的路径和名称不对才遇到这个错误
7.2 ORA-12514:TNS监听程序当前无法识别连接描述副中请求的服务
这是最常见的错误。
1)、打开Net Manager,选中服务名称,检查服务标识栏里的服务名输入是否正确。该服务名必须与服务器端监听器配置的全局数据库名一致。
2)、如果使用动态监听,检查监听是否注册到oracle实例中。解决方法:监听启动的状态下,重启oracle实例。
7.3 ORA-12541: TNS: 没有监听器
显而易见,服务器端的监听器没有启动,另外检查客户端IP地址或端口填写是否正确。启动监听器:
$ lsnrctl start
或
C:lsnrctl start
7.4 ORA-12154: TNS: 无法处理服务名
检查输入的服务名与配置的服务名是否一致。另外注意生成的本地服务名文件tnsnames.ora里每项服务的首行服务名称前不能有空格。
7.5 ORA-12535: TNS: 操作超时
出现这个问题的原因很多,但主要跟网络有关。解决这个问题,首先检查客户端与服务端的网络是否畅通,如果网络连通,则检查两端的防火墙是否阻挡了连接。
7. 6 Windows下启动监听服务提示找不到路径
用命令或在服务窗口中启动监听提示找不到路径,或监听服务启动异常。打开注册表,进入HKEY_LOCAL_MACHINE/SYSTEM/Current ControlSet/Services/OracleOraHome11GTNSListener项,查看ImagePath字符串项是否存在,如果没 有,设定值为实际安装路径,不同的安装路径设定值做相应的更改。这种方法同样适用于Oracle实例服务,同 上,找到如同HKEY_LOCAL_MACHINE/SYSTEM/Current ControlSet/Services/Oracle ServiceMYORACLE项,查看ImagePath字符串项是否存在,如果没有,则新建,设定值为安装路径。
7.7 windows 修改计算机名后监听出问题
1)、修改C:\Windows\System32\drivers\etc\hosts文件使计算机名和Ip映射正确
如:127.0.0.1 bj-pe2-chenqy
2)、修改oralce解析文件tnsnames.ora中(ADDRESS = (PROTOCOL = TCP)(HOST = resoft)(PORT = 1521)) host=后面的主机名