10月20日,由系统架构师敬勇老师在“DBA+长沙群”进行了一次关于Shell Limits设置引发的事故的线上主题分享。小编特别整理出其中精华内容,供大家学习交流。
嘉宾简介
敬勇,系统架构师(高级工程师)。ACOUG&CSOUG核心成员,Oracle Young Expert 。现就职于常德人力资源和社会保障局信息中心,政府信息化技术顾问。曾就职于东软,易联众,创智。从2007年开始从事社会保险系统开发,应用架构设计,数据库管理工作。擅长Oracle数据库故障诊断,性能调优。
演讲实录
主要介绍由于安装11G RAC没有设置Aix的Shell Limits而造成的查询故障。安装是使用Oracle数据库的前提,而Oracle给各种平台编写了安装指南,在安装指南中详细说明了安装操作。但是有多少人认真阅读过这些安装指南了,本次分享以一个真实案例来说明仔细阅读官方文档的必要性。
背景
某地市公安局户籍系统数据库是Oracle RAC 11.2.0.4,运行在IBM P720上(操作系统AIX 6.1),64G内存4颗4核CPU,使用ASM。这套系统与人社局的社保保障卡系统进行数据交换。
这是数据库服务器的一个配置情况,出现的问题如下:
业务人员反馈说在执行某个特定模块时间隙性报错(也就是在查询条件所查询的数据量不同时可能会出现这种问题)ORA-04030: 在尝试分配 123416 字节 (QERHJ hash-joi,kllcqas:kllsltba) 时进程内存不足,其它模块SQL执行正常。
当出现这种问题时,要开发人员在客户现场使用PL/SQL与SQL*Plus执行该报错SQL,仍然报错。看见到这种错误信息,第一时间可能想到的原因又是什么。
对于ORA-04030: 在尝试分配 123416 字节 (QERHJ hash-joi,kllcqas:kllsltba) 时进程内存不足这种信息,我当时的第一反应是,是不是物理内存不足所引起的。
所以诊断也就是从检查系统内存开始。
通过检查系统物理内存与分页情况,系统资源是充足的。不仅物理内存有空闲,且根本就没有使用分页。
上图中是该数据库的内存设置情况,从输出信息可以看到没有使用memory_max_target,memory_target,设置了sga_target与sga_max_size为16G,并且指定了db_cache_size与shared_pool_size的最小值,pga_aggregate_target为8G,操作系统的物理内存总大小是64G,所以Oracle使用的内存不到物理内存的一半。所以不应该是因为内存资源不足所引起的。
因为pga_aggregate_target指定了所有会话相关的服务器进程所使用的PGA总大小,但每个会话相关的
服务器进程可以使用的pga最大内存是由隐含参数_pga_max_size所控制的,它的默认大小是 200MB,
它的取值范围从10MB up to 4TB-1。
于是检查这两个隐含参数:
这里_pga_max_size它的大小是1310M。workarea_size_policy 设置为 AUTO,并且在自动模式下PGA中的SQL工作区所能使用的内存大小由隐含参数_smm_max_size控制,这里它的大小为128M。
如是将_smm_max_size设置为500M,再执行该SQL语句。
但执行结果仍然报错。
如是尝试使用手动PGA管理,workarea_size_policy设置为manual,将hash_area_size,sort_area_size设置为500M,再执行该SQL语句。
还是一样报错。
如果设置4030 trace name heapdump level 536870917'事件来获取进程转储信息。
从生成的跟踪文件中可以看到如下信息:
如上信息可以看到这个会话进程所分配的私有SQL区域(Private SQL Area):为111M。
从以上信息可以看到会话进程的内存分配top 10部分的详细信息,其中ERHJ hash-joi,kllcqas:kllsltba部分分配了 86M内存,并且从blksz=262144 分配的内存块个数,可知会话进程分配的PGA大小为262144个内存块,而AIX上每个内存块的大小是512Byte,所以是128M=262144/2/1024。从siz=116391936/1024/1024=111M,Freeable num=0 siz=0 Free num=0 siz=0
这就与前面分配的私有SQL区域大小111M联系起来了
从以上信息可以看到整个数据库实例实例分配的PGA私有SQL区域(Private SQL Area)总大小是420M,执行该SQL语句的会话进程私有SQL区域大小是111M。而PGA的总大小设置为8G,使用手动PGA管理,并且将hash_area_size,sort_area_size设置为500M,为何在分配11M内存后就不能分配内存了?
因为之前的测试一直都是通过TNS服务名来连接数据库,如是使用SQL*Plus来(通过OS认证与本地连接)来执行,结果执行成功。原因在哪里呢?
通过OS认证与本地连接来执行是没有通过监听的,基本可以确认与监听是有关系的。
rac中的监听是由clusterware来管理,并且从11g开始,安装clusterware从oracle用户分离给grid用户。
如是,我想到了会影响进程使用内存资源的shell limits,检查一下用户的shell limits情况。
从上面的资源限制信息可以看到,这里只给oracle用户设置了资源限制参数,grid用户并没有。
在没有设置的情况下,用户就会使用默认值。从默认值可以看到,软件文件大小fsize=2097151个数据块,软件核心文件大小core=2097151个数据块,每个进程的CPU使用时间cpu==-1没有限制,软件数据段大小data=262144个数据块,软件真实内存使用大小rss=-1没有限制,软件堆段大小stack=65536个数据块,软件文件描述限制nofiles=2000。
而且AIX的每个数据块大小是512 byte.之前的跟踪文件分配的PGA内存为262144个数据块与这里的data=262144是相关的。所以通过监听程序生成的服务器进程最多只能分配262144个数据块的内存(也就是128M)。
这就是为什么,只要查询的数据量大,需要使用的内存超过这个限制就是出现ORA-04030: 在尝试分配 123416 字节 (QERHJ hash-joi,kllcqas:kllsltba) 时进程内存不足的真正原因。
大家会想,为什么都给Oracle用户设置了shell limits,为什么没有给grid用户设置了。
oracle 的aix平台安装手册中是有shell limits配置的说明。
后来问了安装这套RAC的工程师,得到的说法是,他所看到的RAC安装攻略中没有给grid用户设置,只有给oracle用户设置。
解决方法也很简单,就是对grid用户设置shell limits,然后重启监听程序。
今天的主题分享目的在于希望大家不要为了完成任务从网上找一些什么攻略之类的文档,要想学习技术还是得认认真真的看官方资源,比如安装,Oracle提供了各种操作系统的安装指南。
Q&A精选
【问题1】:
这个grid管理监听的事情,引出了另外一个问题,ip白名单所在的sqlnet.ora文件,用哪个HOME的?
答:CRS_HOME
【问题2】:
4030 trace name heapdump level 536870917'事件,请问主要来做什么的?没听过这个事件呀,我应该搜什么关键词了解这个事件?
答:Gavin,就搜索错误号
【问题3】:
Server process 是由实例监听启动,一般不是由scan监听启动,为什么受grid用户的limit影响?
答:实例监听在rac中由集群软件来启动,集群软件由grid用户来管理。
本文来自云栖社区合作伙伴"DBAplus",原文发布时间:2015-10-21