有关监听日志的清理问题

时间:2022-07-08 22:40:15

近日,有开发人员向我反馈:“代码时有连不上数据库的情况发生”。在了解了一些基本信息之后,希望能通过查看监听日志获取问题线索。首先是通过如下方式确定监听日志的存放路径:

LSNRCTL for Linux: Version 10.2.0.4.0 - Production on 21-JUN-2016 21:19:56

Copyright (c) 1991, 2007, Oracle. All rights reserved.

Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 10.2.0.4.0 - Production
Start Date 21-JUN-2016 12:02:41
Uptime 0 days 9 hr. 17 min. 15 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/10.2.0/db_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/product/10.2.0/db_1/network/log/listener_rac1.log
Listening Endpoints Summary...

监听日志被用于记录客户端向服务端的建立连接的情况,同时也会记录监听注册和动态注册等方面的信息。在查看监听日志的过程中,发现日志文件较大,vi编辑器打开较慢,只好通过tail -10000 listener_rac1.log > view.txt的方式转储其内容,其中并无开发人员所描述的连接不上的情况记录。日志节选部分内容如下:

21-JUN-2016 21:22:13 * service_update * dsdb1 * 0
21-JUN-2016 21:22:13 * service_update * dsdb1 * 0
21-JUN-2016 21:22:33 * (CONNECT_DATA=(SID=dsdb1)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=root))) * (ADDRESS=(PROTOCOL=tcp)(HOST=198.168.9.53)(PORT=36304)) * establish * dsdb1 * 0
21-JUN-2016 21:22:33 * (CONNECT_DATA=(SID=dsdb1)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=root))) * (ADDRESS=(PROTOCOL=tcp)(HOST=198.168.9.53)(PORT=36303)) * establish * dsdb1 * 0
21-JUN-2016 21:23:03 * (CONNECT_DATA=(SID=dsdb1)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=root))) * (ADDRESS=(PROTOCOL=tcp)(HOST=198.168.9.53)(PORT=36907)) * establish * dsdb1 * 0

在寻找答案的过程中发现“LISTENER.LOG日志大小不能超过2GB,超过会导致LISTENER监听器无法处理新的连接”这样一条线索。但是又说该类问题“只是发生在老旧的32bit Linux或Unix系统下面,真实的原因是一些32bit OS自带的文件系统不支持2GB以上的文件,导致监听服务进程(tnslsnr)append write日志文件出错”。我的环境可是64位的Linux系统啊,不管怎么样,还是希望清理一下过大的日志文件(722MB)。那么该如何处理这个文件呢?是否可以基于处理alert日志的经验,直接删除或重命名文件呢?

实践证明,这样做是不可行的。尽管已经将日志文件重命名,但是连接信息依旧记录到了重命名后的日志文件中。怎样才是正确的截断监听日志的做法呢?其实大可不必去百度和Google,只用LSNRCTL的help就可以解决问题(有时候Oracle工具的内置帮助还是很贴心的):

LSNRCTL> help
The following operations are available
An asterisk (*) denotes a modifier or extended command:

start stop status
services version reload
save_config trace spawn
change_password quit exit
set* show*

没错。就是用set命令!!!那么set命令要怎么用呢?我们还可以继续help,方法如下:

LSNRCTL> set help
The following operations are available after set
An asterisk (*) denotes a modifier or extended command:

password rawmode
displaymode trc_file
trc_directory trc_level
log_file log_directory
log_status current_listener
inbound_connect_timeout startup_waittime
save_config_on_stop dynamic_registration

所以,截断监听日志的正确做法应该按如下步骤进行:

  1. 停止监听服务进程记录日志:set log_status off
  2. 重命名或删除监听日志文件
  3. 开启监听服务进程记录日志:set log_status on

另外,log_file命令用于指定监听日志的存放路径。通常,在截断监听日志之后,监听服务进程会在默认的路径下创建一个名为Listener.log的文件,如果你希望将监听日志以非默认路径和文件名保存,就会用到这个命令。还要注意一点的是,log_file命令只有在log_status为ON的状态下才能正常的使用。

一个平时看起来毫不起眼的监听日志的清理就有这么多学问,Oracle的复杂性还真是名不虚传!

开发人员反馈的问题没有解决,但是也没有重现。学到了一些过去没有注意到的知识,权当是收获了!