Oracle 监听器是驻留在 Oracle 实例所在服务器上的独立进程. 作为客户端进程连接实例的重要沟通组件, Oracle 监听器扮演着重要的地位. 本篇将从监听器日志入手, 分析阅读监听器日志和日常监听器常见行为.
1,Oracle 监听器功能
在笔者说说 Oracle 监听器(http://space.itpub.net/17203031/viewspace-682627)系列中, 已经比较清楚的介绍过 Oracle 监听器的工作方式和体系地位. 这里简要加以累述.
Oracle 监听器是一个独立的操作系统进程, 运行在操作系统进程列表中. 拥有独立于数据库实例的启动, 终止命令控制台(lsnrctl);
Oracle 监听器进程伺候在服务器一个特定端口上(默认为 1521), 等待通过 Oracle Net Service 连入到服务器的客户端请求;
另一方面, Oracle 监听器根据系统设置情况 (各种环境变量) 接受数据库实例的服务列表. 服务 Service 是对外提供的服务名称, 供本地命名服务依据 Service 名称连入到其中. Service 是对应数据库 SID, 也就是指定的 Oracle 实例数据库位置. 建立和维护服务列表的过程叫做注册 register;
注册 register 过程分为两种, 静态注册和动态注册. 静态注册就是通过直接将服务名写死在 listener.ora 文件中. 动态注册是通过 pmon 后台进程周期性的到监听器来注册;
当一个 client 请求通过 TCP 协议访问到特定端口的监听程序, Oracle 监听器会对比请求中的 Service 名称和掌握的注册 Service 列表. 如果不匹配, 就拒绝. 如果匹配, 就定位到了特定的实例, 包括 Oracle_home 地址;
监听程序不负责进行用户名密码的验证, 此时会向 Oracle 实例请求一个 Server Process 与 client Process 进行你个交互;
2,Oracle 监听器状态信息
在大部分平台下, 我们可以通过 lsnrctl 监听器控制程序与监听器进行交互和控制操作. 其中, 使用 status 命令, 可以获取到当前监听器状态信息.
C:\Documents and Settings\Administrator>lsnrctl status
LSNRCTL for 32-bit Windows: Version 10.2.0.1.0 - Production on 29-6 月 -2011 13:41:27
Copyright (c) 1991, 2005, Oracle. All rights reserved.
正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=acca-119hs63yxc)(PORT=1521)
))
LISTENER 的 STATUS
------------------------
别名 LISTENER
版本 TNSLSNR for 32-bit Windows: Version 10.2.0.1.0 - Produ
ction
启动日期 29-6 月 -2011 10:51:26
正常运行时间 0 天 2 小时 50 分 3 秒
跟踪级别 off
安全性 ON: Local OS Authentication
SNMP OFF
监听程序参数文件 C:\tool\oracle\oracle\product\10.2.0\db_1\network\admi
n\listener.ora
监听程序日志文件 C:\tool\oracle\oracle\product\10.2.0\db_1\network\log\listener.log
监听端点概要...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=acca-119hs63yxc)(PORT=1521)))
服务摘要..
服务 "OTSXDB" 包含 1 个例程.
例程 "ots", 状态 READY, 包含此服务的 1 个处理程序...
服务 "OTS_XPT" 包含 1 个例程.
例程 "ots", 状态 READY, 包含此服务的 1 个处理程序...
服务 "ots" 包含 1 个例程.
例程 "ots", 状态 READY, 包含此服务的 1 个处理程序...
命令执行成功
命令 status 可以查看当前监听器的所有信息. 当前监听器对应的服务包括三个, 分别为 otsxdb,otx_xpt 和 ots. 三个服务名是对外使用的, 本质上对应的 Oracle 实例都是 ots.
监听器进程工作都有对应的日志信息, 在状态显示中, 我们也可以看到日志文件位置(C:\tool\oracle\oracle\product\10.2.0\db_1\network\log\listener.log). 下面我们从一个新的日志文件, 看监听器工作.
3,Oracle 监听器日志解析
下面是我们截取的监听器片段, 篇幅原因, 有省略.
以 pid=2736 开始
监听: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=acca-119hs63yxc)(PORT=1521)))
Listener completed notification to CRS on start
TIMESTAMP * CONNECT DATA [* PROTOCOL INFO] * EVENT [* SID] * RETURN CODE
29-6 月 -2011 10:51:27 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=)(USER=Administrator))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER)(VERSION=169869568)) * status * 0
29-6 月 -2011 10:51:39 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=)(USER=Administrator))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER)(VERSION=169869568)) * status * 0
29-6 月 -2011 10:52:00 * (CONNECT_DATA=(SID=OTS)(CID=(PROGRAM=C:\tool\oracle\oracle\product\10.2.0\db_1\perl\5.8.3\bin\MSWin32-x86-multi-thread\perl.exe)(HOST=ACCA-119HS63YXC)(USER=SYSTEM))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.1.39.93)(PORT=3126)) * establish * OTS * 12505
TNS-12505: TNS: 监听程序当前无法识别连接描述符中所给出的 SID
29-6 月 -2011 10:52:00 * service_register * ots * 0
29-6 月 -2011 10:52:11 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=)(USER=Administrator))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER)(VERSION=169869568)) * status * 0
29-6 月 -2011 10:52:48 * service_update * ots * 0
29-6 月 -2011 10:53:00 * service_update * ots * 0
(有省略...)
29-6 月 -2011 10:53:17 * ping * 0
29-6 月 -2011 10:53:18 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=)(USER=SYSTEM))(COMMAND=status)(ARGUMENTS=64)(SERVICE=(ADDRESS=(PROTOCOL=TCP)(HOST=acca-119hs63yxc)(PORT=1521)))(VERSION=169869568)) * status * 0
29-6 月 -2011 10:53:29 * (CONNECT_DATA=(SID=OTS)(CID=(PROGRAM=C:\tool\oracle\oracle\product\10.2.0\db_1\perl\5.8.3\bin\MSWin32-x86-multi-thread\perl.exe)(HOST=ACCA-119HS63YXC)(USER=SYSTEM))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.1.39.93)(PORT=3141)) * establish * OTS * 0
29-6 月 -2011 10:53:57 * (CONNECT_DATA=(SERVICE_NAME=ots)(CID=(PROGRAM=D:\PLSQL Developer\plsqldev.exe)(HOST=LIUZIYU-PC)(USER=Liuziyu))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.1.39.40)(PORT=1760)) * establish * ots * 0
29-6 月 -2011 10:54:00 * (CONNECT_DATA=(SERVICE_NAME=ots)(CID=(PROGRAM=D:\PLSQL Developer\plsqldev.exe)(HOST=LIUZIYU-PC)(USER=Liuziyu))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.1.39.40)(PORT=1761)) * establish * ots * 0
29-6 月 -2011 10:54:00 * (CONNECT_DATA=(SERVICE_NAME=ots)(CID=(PROGRAM=D:\PLSQL Developer\plsqldev.exe)(HOST=LIUZIYU-PC)(USER=Liuziyu))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.1.39.40)(PORT=1762)) * establish * ots * 0
29-6 月 -2011 10:54:03 * service_update * ots * 0
29-6 月 -2011 10:54:09 * service_update * ots * 0
日志内容很多, 我们分为重点的几个部分.
在日志头, Oracle 告知了我们日志格式, 使用 * 进行内容分割.
TIMESTAMP * CONNECT DATA [* PROTOCOL INFO] * EVENT [* SID] * RETURN CODE
其中包括连接时间时间, 请求数据 Data 和其他相关事件信息. 这些可以帮助我们分析日志内容.
监听器无法找到指定服务
对应片段:
29-6 月 -2011 10:52:00 * (CONNECT_DATA=(SID=OTS)(CID=(PROGRAM=C:\tool\oracle\oracle\product\10.2.0\db_1\perl\5.8.3\bin\MSWin32-x86-multi-thread\perl.exe)(HOST=ACCA-119HS63YXC)(USER=SYSTEM))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.1.39.93)(PORT=3126)) * establish * OTS * 12505
TNS-12505: TNS: 监听程序当前无法识别连接描述符中所给出的 SID
分析日志格式后, 可以发现在这个时间(10:52),Oracle 监听器接受到程序的访问, 程序来自主机(ACCA-119HS63YXC), 使用 system 用户登录, 程序名称是 perl.exe. 由于当前系统没有注册 Service 信息, 也没有注册 SID 信息, 所以不能够连接识别对 SID=OTS 请求.
报错无法识别 SID.
实例主动进行动态注册
此时, 数据库服务器先于监听程序启动, 默认要等待很长的时间才会发生动态注册. 我们使用 alter system register; 命令手动启动动态注册过程. 监听程序上发现 pmon 进程的注册进程, 并且记录在日志中.
29-6 月 -2011 10:52:00 * service_register * ots * 0
将数据库 sid=ots 对应的三个实例进行注册.
用户 Client 连接进程
当出现连接请求的时候, 日志记录.
29-6 月 -2011 10:55:19 * (CONNECT_DATA=(SERVICE_NAME=ots)(CID=(PROGRAM=D:\PLSQL Developer\plsqldev.exe)(HOST=LIUZIYU-PC)(USER=Liuziyu))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.1.39.40)(PORT=1782)) * establish * ots * 0
根据日志格式, 可以理解为从远程 (HOST=LIUZIYU-PC,IP=10.1.39.40) 主机通过 TCP 协议访问到监听程序, 要求连接到 ots 服务上. 使用的程序是 pl/sql developer.
周期性 pmon 注册
动态注册是一种经常性的注册行为, pmon 每隔几分钟的时间就会向监听器进行一次注册动作.
29-6 月 -2011 10:55:33 * service_update * ots * 0
4, 结论
监听器是我们经常打交道的数据库组件之一. 同数据库的 alert_log 一样, 监听器日志能够帮助我们解决很多日常故障问题.
来源: http://www.bubuko.com/infodetail-2593278.html