一条数据引发的4030问题

作者简介:种英明,ORACLE数据库工程师,就职于北京海天起点南京分公司,拥有多年数据库开发,管理,维护经验,获有ORACLE OCP和MySQL OCP证书,擅长ORACLE安装升级,故障处理以及sql优化,了解SQL Server,Sybase等多种数据库技术。

环境

操作系统: Red Hat Enterprise Linux Server release 7.2
Cpus: 40
内存: 256G
数据库: Oracle 11.2.0.4
RAC

介绍

某业务系统上线前,开发人员在测试环境进行模拟数据割接,执行一个select语句,sql文本如下:

业务反馈每次执行这个sql,只能查询出来部分数据,其他的数据出不来,一直卡在那里,大概等待1-2分钟报下面的错误:

ORA-04030: 在尝试分配 8216 字节 (PLS PGA hp,PL/SQL STACK) 时进程内存不足。

分析

检查数据库alert日志,也存在ORA-04030错误信息,检查trace 文件xxxx_ora_38286.trc,部分内容如下:

对应的incident trace 文件:xxxx_ora_38286_i102286.trc,部分内容如下:

从上面可以看出:

大致可以判断4030错误是由FUNCTION SYSTEM.F_GET_BANK 函数引起。

该用户进程PGA最大使用了近4G的内存,PL/SQL STACK使用了几乎所有空间,

检查当前会话情况:


等待事件是SQL*Net message to client,一般是数据库向客户端发送数据,但是两张表里面就几百行的数据,客户端一直处于等待的状态,没有接收到任何数据,而其他窗口查询其他的大表没有任何问题,所以不存在网络瓶颈的问题。

查看会话当前使用的PGA:


这个会话已经使用达到4G的内存。

检查操作系统内存,还剩余120G的内存,而且swap空间也没有被使用。



检查操作系统的限制:

根据ulimit –a部分结果,操作系统上oracle用户在并没有内存方面的限制。

max_map_count参数用来设置操作系统单个进程最大使用的内存,上面的值操作系统是默认的,65530*64k 大约等于4G,操作系统默认对进程做了内存方面的限制。

数据库中,SGA是100G,pga_aggregate_target 10G    ,这个两个参数设置没有问题。

检查数据中参数限制:


_use_realfree_heap,当设置这个参数为true时,Oracle会为CGA、UGA单独分配堆,而不从PGA中分配。它的默认值为false,而当设置了pga_aggregate_target后,它的值自动被改为true。_realfree_heap_pagesize_hint参数是数据库对于PGA单进程允许的内存大小,默认值为65536,65536*64k=4GB。

数据库,操作系统没有出现内存紧张的情况,参数设置的也没有明显的问题;大致原因是select语句中的XXX.F_XXXXX函数导致进程达到操作系统设置的最大值内存,如果想具体看这个函数后台做了什么事情,可以使用10046事件,跟踪会话所执行的SQL语句

使用方法如下:

开启10046跟踪:

关闭10046:

检查trace文件内容如下:


检查发现trace一直在循环打印上面的内容,绑定变量的值104230,一个select语句为什么会产生循环调用?检查函数内容如下:

函数的主要作用是根据银行ID查找最上一级银行ID,当传进去的参数是104230,就会产生循环调用。也就是BANK_ID=104230所在的那一条记录BANK_ID,PARENT_BANK值是一样的,才导致内存不足4030错误。检查XXX.BANK表,BANK_ID,PARENT_BANK相等的只有这一条记录,最终让业务人员修改数据解决。

未经允许不得转载:Oracle一体机用户组 » 一条数据引发的4030问题

相关推荐