【新书连载】应用无法连接数据库问题分析

编辑说明:《Oracle性能优化与诊断案例精选》出版以来,收到很多读者的来信和评论,我们会通过连载的形式将书中内容公布出来,希望书中内容能够帮助到更多的读者朋友们。

前不久某运营商客户反映某套业务系统在2016年8月4日凌晨出现过无法访问数据库的情况。当接到客户请求之后我才通过VPN登录进行日志分析。

首先我分析数据库告警日志发现,8月4日凌晨54分开始出现unable to spawn jobq slave process相关错误,如下所示。

从上述告警日志来看,没有明显的ORA相关错误。但是我们细心一点就会发现上述日志中存在一些告警信息,比如kkjcrelp:unableto spawn jobq slave process,该告警也值得我们关注。那么这个告警信息的产生一般有哪些原因呢?

根据kkjcrelp:unableto spawn jobq slave process错误来看,一般有以下几种原因。

(1)数据库进程参数processes参数设置偏小。

(2)job 参数job_queue_processes设置过小。

(3)系统资源(CPU/IO/Memory)不足,例如内存不足,导致新产生的进程无法获取资源。

根据经验我们知道,这极有可能是资源的问题。因为如果是数据库实例processes参数设置偏小,那么alert log通常会伴随 ORA-00200 类似的错误,然而我们却并没有发现。因此我们可以很容易的排除第一种可能性。

至于第2种和第3种可能原因,这里我们暂时还无法排除,还需要进一步分析相关日志才能下结论。

既然是应用程序无法访问,那么数据库监听日志应该会有一些相关记录。我继续检查数据库监听日志发现,4日凌晨确实出现了大量的TNS相关错误,如下所示。

上面这部分内容,我相信大家并不陌生,这是非常常见的一些错误。我相信很多人第一感觉是搜索Oracle MOS,确认TNS-12518 是什么意思,什么原因。想必大家应该会看到这样的文章,ORA-12518 / TNS-12518 Troubleshooting (ID 556428.1)。

该文档描述的解决方案有很多种,这里我大致描述一下,有如下几种。

  • 操作系统时钟问题,建议设置如下参数。

stener.ora: INBOUND_CONNECT_TIMEOUT_listenername SQLnet.ora: SQLNET.INBOUND_CONNECT_TIMEOUT。

  • 操作系统可用内存不足,建议增加内存。
  • 数据库参数processes设置过小,建议调大一些。启用大内存支持,突破内核的单进程只能消耗1GB内存的限制,这实际上通常是指的windows环境。
  • PGA内存不足,而SGA设置过大,导致进程内存不足。建议缩小SGA,给PGA预留更多内存。
  • 配置MTS共享模式。如果监听报错TNS-12518,并进程crash,那么很可能是命中一些因为系统压力过大或者内存溢出等相关oracleBug,例如6139856。

实际上当我们遇到上述类似错误时,不应该直接往下判断。首先在分析这个问题时,我们要确认一点客户所说是否是真实的。也就是说这个问题之前是否出现过,还是仅仅是8月4日凌晨出现过1次。带着这样的疑问,我继续检查分析监听日志,发现实际上8月3日也出现了无法连接数据库的情况。

对于Oracle 的错误分析,我给大家的建议都是应该从下往上看,比如下面所列的错误。

TNS-12518: TNS:listener could not hand off clientconnection TNS-12547: TNS:lost contact TNS-12560: TNS:protocoladapter error TNS-00517: Lost contact SolarisError: 32: Broken pipe

Oracle 监听日志在这里其实抛出了一连串的告警信息,我们需要有所判断,确认其中的哪行信息是关键信息,是产生问题的根源。很明显最后一行的Solaris Error:32:Broken pipe 是此问题的关键所在。针对Solaris error:32 broken pipe错误,这里我不自行进行解释,我选择引用Oracle官方的解释。

The error 32 indicates the communication has been broken while the listener is trying tohand off the client connection to the server process or dispatcher process.

这里我简单解释一下上述文档内容的描述,简单地讲就是:Oracle 监听程序尝试去处理客户端到服务器端进程或者调度器(dispatcherprocesses)进程之前的连接时,将客户端进程通信强行中断了

那么监听程序为什么要终止连接呢?文档解释说有如下几种可能性原因。

1. One of reason would beprocesses parameter being low, and can be verified by the v$resource_limitview. 2. In Shared Server mode,check the 'lsnrctl services' output and see if the dispatcher has refused anyconnections, if so, then consider increasing the number of dispatchers. 3. Check the alert log forany possible errors. 4. Memory resource is alsoanother cause for this issue. Check the swap, memory usage of the OS. 5. IfRAC/SCAN or listener is running in separate home, check the following note。

从Oracle 文档描述来看,产生该问题原因主要有如下几种。

(1)processes参数设置过小。

(2)共享服务器模式下,dispatcher不足。

(3)内存资源不足。

由于客户这里实际上是Oracle10.2.0.4 环境,因此就不需要考虑上述第5条描述了。

从上述问题描述的内容来看,与我们之前讲述TNS-12518 错误几种可能性的原因有些类似。那么我们如何去定位这个问题呢?针对类似的问题,我通常的建议是使用最简单的方法:排除法

首先我们来从数据库层面判断是否可以直接排除第1种可能性原因。我分析了数据库在8月4日凌晨1-2点的AWR数据库,发现数据库进程并没有达到processes参数设置限制,如图13-1所示。

所以可以排除第1种可能性原因。

同时由于数据库是专用模式,因此也可以排除第2种可能性原因。

因此,这里似乎可以大致断定导致此次问题的原因是第3种可能性了,即系统资源使用方面。

我们知道操作系统资源主要分为CPU/IO以及内存资源,接下来从数据库监控角度来判断一下数据库资源在故障期间内的使用情况如何。通过器监控发现,CPU资源消耗正常,swap内存消耗存在一定的波动,但是整体来看也是正常的,如图所示。

基于前面的分析不难看出,系统资源在使用上没有任何问题,没有出现资源过度消耗或资源不足的情况。到这里整个问题的分析似乎陷入了僵局。

Oracle数据库是基于操作系统,因此实际上,当数据库出现异常之后,我们在进行问题分析时,首先应该确认操作系统本身是否正常,比如内核参数设置是否正确等。因此自然而然应该进一步检查数据库服务器操作系统日志是否存在相关蛛丝马迹。

正如心中所想,再检查Solaris操作系统的日志发现,确实存在相关错误。

从上述日志来看,确实存在processes超过限制的情况。同时还能发现有监控用户由于缺乏权限,仍然在不断尝试登陆数据库,这也是一个安全隐患。

针对操作系统日志中的Max number ofDBMS processes execeeded 错误信息,Oracle 官方文档有如下类似解释。

There can be severalcontributors to this failure. Solariskernel may have resource (memory/cpu) shortage, performance problem or thedatabase itself could be having some issues for example:

detected errorDBMS_ERROR: 20 DEFAULT Action=NONE : Max. number of DBMS processes exceeded

说明:参考文档Solaris Cluster 3.x HA-Oracle FaultMonitor Dumps Core With "Aborting fault monitor child process" or"probe response time exceeded timeout" (ID 1381317.1)

根据OracleSolaris的文档解释来看,上述错误ERROR 20表示 Solaris 操作系统本身内核资源使用可能存在异常,或者存在性能问题,或者数据库本身可能存在某些问题。这个分析与我们前面的种种分析似乎比较接近。

这里我需要说明的是,我期间分析了故障前后的AWR和ASH 相关数据,没有发现明显异常,因此可以断定数据库本身是正常的

分析到这个层面,我相信大家心中已经有了答案。有没有可能是操作系统本身有问题呢?这里需要注意的是,操作系统本身有问题,并不代表是指的操作系统资源使用有问题,也有可能是Solaris 相关内核参数设置问题。实际上我们通过前面的操作系统监控信息就可以排除系统资源消耗异常的可能性。

所以这里我们很有必要对Solaris系统本身的相关内核参数进行全面检查一次,通过检查发现确实存在参数设置不合理的情况,如下所示。

---操作系统内核参数

root@nxfwktdb # cat /etc/system|grep 'sys' set semsys:seminfo_semmni=100 set semsys:seminfo_semmns=2048 set semsys:seminfo_semmsl=256 set semsys:seminfo_semvmx=32767 set shmsys:shminfo_shmmax=17179869184 set shmsys:shminfo_shmmin=1 set shmsys:shminfo_shmmni=100 set shmsys:shminfo_shmseg=10 root@nxfwktdb # cat /etc/project system:0:::: user.root:1:::: noproject:2:::: default:3:::: group.staff:10::::

---数据库会话总数

SQL> select count(1) from v$session; COUNT(1) ---------- 1866

对于上述的内核参数,这里我不做过多解释,大家可以参考Oracle官方安装文档,里面有详细的描述。从Soalris 10开始,已经废弃了如下几个参数:

semsys:seminfo_semmns——操作系统信号灯最大个数;

shmsys:shminfo_shmmin——共享内存段最小值;

semsys:seminfo_semvmx——操作系统信号灯的最大值。

同时,从Solaris 10开始,已经不再建议通过修改/etc/system的方式来调整内核参数了。建议通过project的方式来进行控制,而客户这里没有为Oracle用户单独创建project,而使用了默认的default project,如下:

root@nxfwktdb # id -p oracle uid=101(oracle) gid=100(dba) projid=3(default)

那么我们来进一步检查default project设置是否恰当。其中Solaris 10版本中使用process.max-sem-nsems来替代 semsys:seminfo_semmsl 参数的控制,该参数表示一个信号组中信号灯等最大数量,由于Oracle用户默认使用了default project,因此这里我们来检查default project的设置情况,如下所示。

我们可以看到default project中定义了project.max-sem-ids它表示系统中信号组的最大值,即128,表示目前该系统最大default project中所定义的用户创建的最大信号组之和不能超过128。同时/etc/system中的参数semsys:seminfo_semmsl 为256,表示该default project 的每一个信号组最大只能创建256个信号灯。可以通过ipcs 命令直接查看这一点。

上述查询结果的NSEMS 列即表示每个信号组中最大的信号灯数量。同时从NATTCH的值可以看出,目前当前Oracle用户已经创建了1 870个进程。实际上seminfo_semmsl参数的设置应该是大于processes参数设置的。目前数据库processes参数设置为2048,且数据库进程已经超过1850,因此建议将该参数调整的更大一些。

从前面的数据来看,目前default project中所有用户能够消耗的最大信号灯约等于128×256=32768。尽管这个数值看上去已经够大,其实不然。在操作系统命令来看,一个进程和信号灯等对应关系通常是一对多。而且从查询结果来看Oracle实际上只分配了9个信号组,每组最大的信号灯数量是256。如果根据这个计算也就是9×256=2304。而目前数据库实例的进程数量已经接近2000。

因此最后我们建议将seminfo_semmsl参数调整的更大一些,建议设置为512以上。

至此,本案例分析完毕。

对于DBA来说,具备全局的技术观非常重要。因为我们遇到的问题通常不是单一原因导致的,只有掌握多方面的知识,才能在遇到故障时思维不受限,且能更好地利用各类日志信息进行分析排查。

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2017-03-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏F-Stack的专栏

F-Stack Q&A 第一期

Q1:F-Stack有中断模式吗,有计划支持吗?在计算密集型的应用中,轮询模式会占用更多的CPU资源? A1:F-Stack暂时只支持轮询模式,后续会支持中断+...

4165
来自专栏一个番茄说

Swift中防止ptrace依附

在移动开发中,安全是一个很重要的话题,当然安全是没有绝对的,只能说尽可能的提高安全性。在iOS的开发中,为了防止别人窥视我们的App,我们得采用一些手段来进行防...

613
来自专栏磨磨谈

REDHAT 7.5beta 新推出的VDO功能

VDO的技术来源于收购的Permabit公司,一个专门从事重删技术的公司,所以技术可靠性是没有问题的

642
来自专栏Seebug漏洞平台

TP-LINK 远程代码执行漏洞 CVE-2017-13772 趣谈

原文地址:《A CURIOUS TALE OF REMOTE CODE EXECUTION, THE TP-LINK STORY – CVE-2017-1377...

7976
来自专栏coder修行路

python爬虫从入门到放弃(九)之 实例爬取上海高级人民法院网开庭公告数据

通过前面的文章已经学习了基本的爬虫知识,通过这个例子进行一下练习,毕竟前面文章的知识点只是一个 一个单独的散知识点,需要通过实际的例子进行融合 分析网站 其实爬...

1717
来自专栏landv

金蝶KIS&K3助记码SQL数据库批量刷新

913
来自专栏数据和云

Oracle 12.2中那些温暖人心的特性-之二

在OOW 2015大会上,Oracle已经发布了12.2的Beta版本,其中的很多亮点新特性引人瞩目,包括在IMO和Multitenant方面,以及在Shard...

2615
来自专栏后端技术探索

后端前端恩仇录

其实应该更多的是互相的磨合与学习,希望身边的人可以有自己的经验分享,与理解,互相进步才是大家需要的,作为一个 "年老" (我也是90后) 的开发者,我觉得一代胜...

633
来自专栏FreeBuf

注意了,使用Sqlmap的你可能踩中了“蜜罐”

* 本文原创作者:九如,本文属FreeBuf原创奖励计划,未经许可禁止转载 Par0:楔子 你站在桥上看风景,看风景的人在楼上看你, 明月装饰了你的窗子,你...

1766
来自专栏大数据和云计算技术

Redis 4.0的了解以及使用

Redis作为时下最火爆的NoSQL数据库以性能强悍、数据结构丰富著称,同时其成长的脚步也从未停止,自诞生伊始已经历多次蜕变不断推出新功能。

933

扫描关注云+社区