DBA必备技能:通过truss跟踪解决监听无法启动案例

作者简介:刘斌,云和恩墨高级技术专家,擅长数据库故障诊断分析,数据库性能优化,自动化运维开发,坚持学习、写作、分享,


在Oracle DBA的日常工作中,通过各种跟踪手段,从数据库内外部发现问题,最终找到解决方案,是必备的重要技能。


以下这则案例,就是通过OS系统级别的跟踪,快速定位并解决问题的一个例证。在Oracle数据库的跟踪时,OS上Truss是非常重要的工具。

登录数据库主机发现一个节点监听异常:

尝试手工启动,一样报错:

grid@xxxxdbb:/home/grid $lsnrctl statuss

LSNRCTL for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production on 04-MAR-2016 01:23:34

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))

TNS-12541: TNS:no listener

 TNS-12560: TNS:protocol adapter error

  TNS-00511: No listener

   IBM/AIX RISC System/6000 Error: 79: Connection refused

第一怀疑就是hosts文件被改了,查看host没发现修改过。从上面看出是使用ipc方式启动,尝试truss看看能不能有信息。

在Linux上调用truss跟踪一个操作非常简单,以下跟踪了lsnrctl start操作的过程:

truss lsnrctl start

execve("/usr/bin/lsnrctl", 0x2FF22BF8, 0x200138A8) Err#2  ENOENT

execve("/etc/lsnrctl", 0x2FF22BF8, 0x200138A8)  Err#2  ENOENT

execve("/usr/sbin/lsnrctl", 0x2FF22BF8, 0x200138A8) Err#2  ENOENT

execve("/usr/ucb/lsnrctl", 0x2FF22BF8, 0x200138A8) Err#2  ENOENT

execve("/home/grid/bin/lsnrctl", 0x2FF22BF8, 0x200138A8) Err#2  ENOENT

execve("/usr/bin/X11/lsnrctl", 0x2FF22BF8, 0x200138A8) Err#2  ENOENT

execve("/sbin/lsnrctl", 0x2FF22BF8, 0x200138A8) Err#2  ENOENT

execve("./lsnrctl", 0x2FF22BF8, 0x200138A8)     Err#2  ENOENT

execve("/u01/app/11.2.0.4/grid/bin/lsnrctl", 0x2FF22BF8, 0x200138A8)  argc: 2

kusla(2, 0x09FFFFFFF0001170)                    Err#1  EPERM

read_sysconfig(0x09001000A07D1550,, 0x09001000A0806E68) = 0x0000000000000000

sbrk(0x0000000000000000)                        = 0x00000001101D54D8

vmgetinfo(0x0FFFFFFFFFFFF140, 7, 16)            = 0

sbrk(0x0000000000000000)                        = 0x00000001101D54D8

sbrk(0x0000000000000008)                        = 0x00000001101D54D8

__libc_sbrk(0x0000000000010020)                 = 0x00000001101D54E0

thread_init(0x0900000000520760, 0x09001000A0888470) =

sbrk(0x0000000000000000)                        = 0x00000001101E5500

vmgetinfo(0x0FFFFFFFFFFFF780, 7, 16)            = 0

smcr_procattr(0, 1, 0x0FFFFFFFFFFFF778)         Err#109 ENOSYS

getrpid(-1, -1, 648535941220675944)             = 8912948

_getpid()                                       = 8912948

getprocs64(0x00000001101D7BF0, 5024, , 1) = 1

appulimit(1005, 0)                              = 0x0FFFFFFFFE000000

_thread_self()                                  = 66453675

thread_setmystate(0x0000000000000000, 0x0FFFFFFFFFFFF2A0) = 0

.....省略....

_getpid()                                       = 8912948

accessx("/etc/secvars.cfg", 04, 0)              = 0

statx("/etc/secvars.cfg", 0x0FFFFFFFFFFF6FB0, 176, 0) = 0

_getpid()                                       = 8912948

accessx("/etc/passwd", 04, 0)                   = 0

statx("/etc/passwd", 0x0FFFFFFFFFFF6E20, 176, 0) = 0

accessx("/etc/security/passwd", 04, 0)          Err#13 EACCES

accessx("/etc/passwd", 04, 0)                   = 0

statx("/etc/passwd", 0x0FFFFFFFFFFF6B50, 176, 0) = 0

accessx("/etc/passwd", 04, 0)                   = 0

statx("/etc/passwd", 0x0FFFFFFFFFFF6C20, 176, 0) = 0

_getpid()                                       = 8912948

accessx("/etc/passwd", 04, 0)                   = 0

statx("/etc/passwd", 0x0FFFFFFFFFFF6E20, 176, 0) = 0

accessx("/etc/security/passwd", 04, 0)          Err#13 EACCES

accessx("/etc/passwd", 04, 0)                   = 0

statx("/etc/passwd", 0x0FFFFFFFFFFF6B50, 176, 0) = 0

accessx("/etc/passwd", 04, 0)                   = 0

statx("/etc/passwd", 0x0FFFFFFFFFFF6C20, 176, 0) = 0

accessx("/etc/security/passwd", 04, 0)          Err#13 EACCES

close(5)                                        = 0

gethostname(0x0FFFFFFFFFFF9C00, 512)            = 0

access("/tmp/.oracle", 0)                       = 0

chmod("/tmp/.oracle", 01777)                    Err#1  EPERM

socket(1, 1, 0)                                 = 5

access("/tmp/.oracle/sLISTENER", 0)             = 0

connext(5, 0x0FFFFFFFFFFF5BA8, 1025)            Err#79 ECONNREFUSED  

-->注意这里,发现要读取/tmp/.oracle/sLISTENER

access("/tmp/.oracle/sLISTENER", 0)             = 0

_nsleep(0x0FFFFFFFFFFF5580, 0x0FFFFFFFFFFF5650) = 0

close(5)                                        = 0

socket(1, 1, 0)                                 = 5

connext(5, 0x0FFFFFFFFFFF5BA8, 1025)            Err#79 ECONNREFUSED

access("/tmp/.oracle/sLISTENER", 0)             = 0

-->注意,这里大量读取出错的信息抛出

_nsleep(0x0FFFFFFFFFFF5580, 0x0FFFFFFFFFFF5650) = 0

close(5)                                        = 0

socket(1, 1, 0)                                 = 5

connext(5, 0x0FFFFFFFFFFF5BA8, 1025)            Err#79 ECONNREFUSED

access("/tmp/.oracle/sLISTENER", 0)             = 0

_nsleep(0x0FFFFFFFFFFF5580, 0x0FFFFFFFFFFF5650) = 0

close(5)                                        = 0

。。。。。

socket(1, 1, 0)                                 = 5

connext(5, 0x0FFFFFFFFFFF5BA8, 1025)            Err#79 ECONNREFUSED

access("/tmp/.oracle/sLISTENER", 0)             = 0

_nsleep(0x0FFFFFFFFFFF5580, 0x0FFFFFFFFFFF5650) = 0

close(5)                                        = 0

socket(1, 1, 0)                                 = 5

connext(5, 0x0FFFFFFFFFFF5BA8, 1025)            Err#79 ECONNREFUSED

access("/tmp/.oracle/sLISTENER", 0)             = 0

close(5)                                        = 0

kopen("/u01/app/11.2.0.4/grid/network/mesg/tnsus.msb", O_RDONLY) = 5

kfcntl(5, F_SETFD, 0x0000000000000001)          = 0

lseek(5, 0, 0)                                  = 0

kread(5, "1513 "011303\t\t\0\0\0\0".., 256)     = 256

lseek(5, 512, 0)                                = 512

kread(5, " 19B\0\0\0\0\0\0\0\0\0\0".., 512)     = 512

lseek(5, 1024, 0)                               = 1024

kread(5, "\0\t\012\01A\0 &\0 -\0 F".., 172)     = 172

lseek(5, 19456, 0)                              = 19456

kread(5, "\00F04 $\0\0\0 b04 %\0\0".., 512)     = 512

Starting /u01/app/11.2.0.4/grid/bin/tnslsnr: please wait...

kwrite(1, " S t a r t i n g   / u 0".., 61)     = 61

kfcntl(1, F_GETFL, 0x0000000000000008)          = 67110914

pipe(0x0FFFFFFFFFFF80E0)                        = 0

pipe(0x0FFFFFFFFFFF80D8)                        = 0

sigprocmask(0, 0x09001000A090DB70, 0x09001000A090DB90) = 0

kfork()                                         = 19988596

kread(8, " N T P 0   1 4 4 8 3 5 7".., 64)      = 14

_getpid()                                       = 8912948

kfcntl(8, F_SETFD, 0x0000000000000001)          = 0

kwrite(7, "\0 \001\0\0\001 :01 ,".., 179)    = 179

kread(8, "\0\f\0\004\0\0\0 "\001 ., 8208)    = 492

close(7)                                        = 0

close(8)                                        = 0

--> 在经过了连续的尝试无法锁定文件后,出错,提示无法启动:

TNSLSNR for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production

System parameter file is /u01/app/11.2.0.4/grid/network/admin/listener.ora

Log messages written to /u01/app/grid/diag/tnslsnr/xxxxdbb/listener/alert/log.xml

Error listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))

TNS-12555: TNS:permission denied

 TNS-12560: TNS:protocol adapter error

  TNS-00525: Insufficient privilege for operation

   IBM/AIX RISC System/6000 Error: 1: Not owner

kwrite(1, " T N S L S N R   f o r  ".., 470)    = 470

kwrite(1, "\n", 1)                              = 1

lseek(5, 19968, 0)                              = 19968

kread(5, "\0\r04 5\0\0\0 V04 6\0\0".., 512)     = 512

Listener failed to start. See the error message(s) above...

kwrite(1, " L i s t e n e r   f a i".., 61)     = 61

kfcntl(1, F_GETFL, 0x0000000000000008)          = 67110914

close(4)                                        = 0

kfcntl(1, F_GETFL, 0x0000000000000008)          = 67110914

close(5)                                        = 0

kfcntl(1, F_GETFL, 0x0000000013F600AB)          = 67110914

kfcntl(2, F_GETFL, 0x0000000013F600AB)          = 67110914

_exit(1)

尝试删除/tmp/.oracle/sLISTENER后监听正常启动.

事实上,在 /tmp/.oracle 目录,或者有些平台在 /var/tmp/.oracle 目录,存放一些数据库运行时的临时文件,包括基于socket的协议监听临时文件。在某些异常情况下,数据库关闭时没有及时清理这些文件,导致启动出现问题。这个案例就是这样的情况之一。

以下是一段相关描述:

The hidden directory '/var/tmp/.oracle' (or /tmp/.oracle on some platforms) or its content was removed while instances & the CRS stack were up and running. Typically this directory contains a number of "special" socket files that are used by local clients to connect via the IPC protocol (sqlnet) to various Oracle processes including the TNS listener, the CSS, CRS & EVM daemons or even database or ASM instances. These files are created when the "listening" process starts.

这是应用truss的诊断案例一则,与大家分享。

本文出自数据和云公众号,原文链接

时间: 2024-11-03 21:11:15

DBA必备技能:通过truss跟踪解决监听无法启动案例的相关文章

mybatis-tomcat集群+oscache 启动服务时 log4j 打印缓存监听jgroups启动失败

问题描述 tomcat集群+oscache 启动服务时 log4j 打印缓存监听jgroups启动失败 使用两个虚拟机搭建了一个小型tomcat集群,发布web项目(内置oscache缓存机制) oscache.properties广播配置为官方配置,网上资料一大堆,不再描述. tomcat服务器正常启动,具体问题描述如下: 问题1:启动tomcat服务器,log4j打印oscache错误信息如下: 2015-03-05 15:14:47,697 INFO GeneralCacheAdminis

oracle中一次监听不能启动实例

登录测试环境发现一个节点监听异常 root@xxxxdbb:/ #crsctl status res -t -------------------------------------------------------------------------------- NAME           TARGET  STATE        SERVER                   STATE_DETAILS ----------------------------------------

请问.如何监听JBoss启动时的异常?

问题描述 先说下我的情况.现在是启动JBoss时 会抛出80端口被占的Exception然而.我想监听JBoss启动时抛出的异常..如果发现抛出80端口被占的异常.那么就Show一个Message出来 让用户知道现在我的问题是我不知道如何加这个监听器.以及如何配置到JBoss启动时 以及如何写这个监听器..谢谢各位. 问题补充:andilyliao 写道 解决方案 这个简单 应该让这个软件先启动 然后再启动jboss 写一个sh或者bat组织启动顺序 就可以了 呵呵 写的这个软件如果读不到文件或

空格字符的错误造成监听无法启动

listener.ora中配置了静态监听: 启动监听,却报了错误: 从提示看,应该很明确,listener.ora文件中SID_LIST_LISTENER指定的参数不正确,但再看所有参数拼写.路径好像都没有错误. TNS-01155: Incorrectly specified SID_LIST_LISTENER parameter in LISTENER.ORA NL-00303: syntax error in NV string 其实,这次忽视了一点,就是空格字符,光标扫描所有空格,发现确

Oracle监听服务启动失败案例

在ORACLE测试服务器上还原恢复了一个数据库后,启动监听服务时出现了TNS-12541, TNS-12560,TNS-00511之类的错误,具体情况如下所示: [oracle@getlnx01 admin]$ lsnrctl status LSNRCTL for Linux: Version 10.2.0.4.0 - Production on 09-MAR-2015 09:13:29 Copyright (c) 1991, 2007, Oracle. All rights reserved.

AIX ha切换不成功并重启主机导致oracle监听无法启动的处理

    2015年9月19日,ERP资金系统应急演练,切换AIX ORACLE双机数据库到备机,结果没有成功切换,导致数据库监听无法正常启动,下面是故障的排查及处理过程.     通过沟通发现,HA切换失败后监听就无法正常启动.数据库能正常启动,后来进行主节点重启,重启后监听程序依然无法启动.无论是启动监听.还是查看监听状态,命令都停留在connecting阶段,如下图所示:     检查监听的告警日志,发现报错与网卡适配器相关,如下图所示:     根据错误信息怀疑是监听程序引用的IP有问题,

DBA必备技能:数据库挂起时进行转储分析诊断案例

在上周末培训中,有同学问起:如何在数据库挂起时进行诊断和分析?这里就是这样一个案例.分析.深入,解数据库之疑难. 在 Oracle 数据库的运行过程中,可能会因为一些异常遇到数据库挂起失去响应的状况,在这种状况下,我们可以通过对系统状态进行转储,获得跟踪文件进行数据库问题分析:很多时候数据库也会自动转储出现问题的进程或系统信息:这些转储信息成为我们分析故障.排查问题的重要依据. 本章通过实际案例的详细分析,讲解如何逐层入手.层层剖析的分析数据库故障. 1.1  状态转储的常用命令 当数据库出现一

activiti 动态配置 activiti 监听引擎启动和初始化(高级源码篇)

1.1.1. 前言 用户故事:现在有这样一个需求,第一个需求:公司的开发环境,测试环境以及线上环境,我们使用的数据库是不一样的,我们必须能够任意的切换数据库进行测试和发布,对数据库连接字符串我们需要加密,保证我们的数据库连接不能被发现.必须确保我们的数据库不能暴露出去,第二个需求,我们需要监控activiti 工作流引擎,在流程启动的之前,我们要保证我们的所有属性都注入进去,如果有些属性没有注入进去,我们是不能让流程启动起来的.也就是进行必要饿属性检测,如果没有期望的属性,直接报错,在流程实例化

连接Oracle数据库时报ORA-12541:TNS:无监听程序的图文解决教程_oracle

在用PL/SQL Developer等客户端工具连接oracle服务器时出现ORA-12541:TNS:无监听程序的错误,如下图: 发现原来是oracle的监听没有启动,重启监听后就连接成功了,下面跟大家分享一下如何启动oracle的监听. 1.在安装Oracle服务器的主机上,打开Net Configuration Assistant 2.选择监听程序配置,下一步 3.选择重新配置,下一步 4.选择监听程序,默认,下一步 注:如果你的监听已启动,则出现提示框,选择是 5.选择协议,使用默认的T