背景概述
n 2014 年12月29日9:30至11:00,2015年1月7日23:00左右,2015年1月12日11:00左右,某客户数据库分别出现不同程度的故障,最终都通过重启数据库或者主机解决。
问题详细描述
2014 年12月29日9:30至11:00,2015年1月7日23:30左右,2015年1月12日11:00左右,数据库分别出现不同程度的故障,最终都通过重启数据库或者主机解决。通过查看其它厂商的故障分析报告,仔细分析故障前后的Oracle的AWR报告、操作系统日志,veritas等软件日志,得出如下结论:
数据库故障主要是由于数据库内部的局部故障导致大量业务进程重连积压,进一步消耗了系统内存。在交换空间配置不合理的情况下(故障时系统内存为32GB,交换空间配置为8GB),交换空间使用率为100%,进而导致数据库全面故障,业务操作几乎hang。
|
时间点 |
故障处理关键点 |
|
6/09 9:30~16:30 |
现场收集日志,分析故障 |
|
6/10 8:30 |
写故障分析报告 |
n
事件支持细节
事后故障分析,依赖于各类日志,经过采集。故障发生前后,各类日志收集如下:
|
故障时间点 |
AWR 报告 |
系统日志 |
Veritas 日志 |
Oracle alert log |
Oracle CRS log |
|
12 月29日9:30至11:00 |
无,但有故障前报告(9:00至9:30) |
有,但无明显报错 |
有 |
有 |
有 |
|
1 月7日23:30左右 |
无,但有故障前报告(19:00至22:30) |
有,但无明显报错 |
有 |
有 |
有 |
|
1 月12日11:00左右 |
无 |
有,但无明显报错 |
有 |
有 |
有 |
由于 1 月12日故障,缺少AWR报告,所以无法分析业务层面的故障原因。本次故障报告我们重点分析12月29日和1月7日的故障。
12 月29日的故障发生在9:30分至11:00左右,属于业务高峰期。故障发生时刻,szybdb1系统交换空间使用率已经达到91%以上,engine_A.log日志如下所示:
查看故障前一刻1号节点的AWR报告,主要等待事件如下:

等待事件enq:TC-contention,gc current request,enq:TX-row lock contention,enq:RO-fast object reuse耗时都达到了500ms以上,这是极不正常的。当系统出现以上长时间的等待事件时,业务程序肯定接近于hang。正常情况下,以上等待事件耗时应该在1ms以下。
根据经验,enq:TC-contention,gc current request,enq:RO-fast object reuse ,enq:TX-row lock contention同时出现长时间等待往往是由于交换空间紧张引起的,这跟观察到的交换空间使用接近100%相吻合。enq:TX-row lock contention是值得注意的等待事件, 进一步查看1号节点AWR报告显示,发现insert KC66表是引起enq:TX-row lock contention的最大原因,AWR报告采样期间改SQL没有执行成功,如下所示:

在2号节点insert KC66表执行次数较为频繁,如下所示:

基于以上分析,很可能是存储过程SIM_UserPack.oraP033和SIM_UserPack.oraP028或者SIM_UserPack.oraP029执行时产生了冲突,应用程序不停的发起重连接,进而导致数据库会话数急剧上涨 。截止数据库重启前,单个节点的会话数由平时的90个左右上升到672个。Oracle警告日志如下所示:

故障时,主机内存为32G,SGA分配16G。按照每个会话占用5M左右的内存,操作系统占用内存2GB来估算,那么总体需要内存为:16*1024+5*672+2*1024=16384+3360+2048=21792MB。 根据以上算法,总体来讲,内存应该是够的。HP-UX在早期版本时,进程在内存中运行前需要在交换设备上预留相同大小的空间,所以要求交换空间的大小和内存大小保持一致。也就是说如果操作系统内存为32GB,交换空间只有8GB,那么原则上只能使用8GB的内存,当内存使用量超过8GB时,则会出现交换空间使用100%,进程无法malloc 或 fork 失败,严重情况下会导致数据库hang死故障。如本次故障时,数据库进程则无法fork,警告日志如下所示:

为了节省交换空间,HP-UX推出了pseudo swap 特性。Pseudo swap 可使系统管理员利用具有较大物理 内存的系统,而无须配置较大的 swap 区域。Pseudo swap 不是设备 swap 的替代品,而是 swap 的增强。当系统引导时,会计算 pseudo swap 的数量。此计算是 75% 的物理内存,此值是不可调整内核参数。该 Kernel 会此增强看作是产生新进程时可以分配的附加 swap 区域。系统只会将 pseudo swap 用作保留空间,而不会将进程分页进出 pseudo swap。如果进程需要分页出物理内存,Kernel 则会 swap 到设备或文件系统 swap。医保系统使用了pseudo swap特性,即在32GB内存,8GB交换空间的情况下,总的交换空间可以达到8GB+32GB*0.75=32GB。但需要注意的是, pseudo swap特性不适用于负载比较重的的系统,当负载比较重时,pseudo swap和swap物理设备的协调就会出现问题,进而瞬间导致swap空间使用率达到100%。所以12月19日的故障是由于应用程序insert kc66不成功,应用程序不停的发起重连接,进而导致数据库会话数急剧上涨(达到了672个),进一步消耗了操作系统内存。由于交换空间设置不足,从而导致业务大规模hang死。
需要指出的是,insert KC66操作应该是特定时间段的操作,在已有的其他的AWR报告中没有发现此类SQL或者很少,这个需要跟业务开发商再次确认。
需要说明的是,1月7日故障发生时23:30,即szybdb1和szybdb2主机的SWAP空间相对空闲, 这跟12月29日发生的故障现象有所区别:


而数据库层面除了运行正常的SQL之外,还在执行统计信息分析操作,AWR报告如下图所示:

统计信息收集为Oracle后台自动发起,主要为CBO产生SQL执行计划时提供参考,从而优化数据库性能(绝大多数情况下)。在个别情况下,统计信息自动收集时会影响部分SQL的执行性能。如果业务变化不大或者数据库规模变化不大的情况下,从稳定性角度出发建议关闭统计信息自动收集。
结论及解决方案
1 、目前系统内存配置为64GB,交换空间由原来的8GB增加到32GB。在64GB的情况下,建议交换空间增加到64GB。否则依然有swap空间不足的风险,但发生概率会降低。
2 、重连接时控制中间件tuxedo连接池数量,比如每个节点150(正常情况下在100左右),从而防止大量的重连操作急剧消耗主机内存。
3 、建议业务厂商调查储过程SIM_UserPack.oraP033和SIM_UserPack.oraP028或者SIM_UserPack.oraP029执行时产生冲突的可能性。
4 、关闭统计信息自动执行。