Oracle 内存分配与调整.docx

上传人:b****1 文档编号:12518585 上传时间:2023-04-19 格式:DOCX 页数:10 大小:22.13KB
下载 相关 举报
Oracle 内存分配与调整.docx_第1页
第1页 / 共10页
Oracle 内存分配与调整.docx_第2页
第2页 / 共10页
Oracle 内存分配与调整.docx_第3页
第3页 / 共10页
Oracle 内存分配与调整.docx_第4页
第4页 / 共10页
Oracle 内存分配与调整.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

Oracle 内存分配与调整.docx

《Oracle 内存分配与调整.docx》由会员分享,可在线阅读,更多相关《Oracle 内存分配与调整.docx(10页珍藏版)》请在冰豆网上搜索。

Oracle 内存分配与调整.docx

Oracle内存分配与调整

Oracle内存分配与调整

一、前言

对于oracle的内存的管理,截止到9iR2,都是相当重要的环节,管理不善,将可能给数据库带来严重的性能问题。

下面我们将一步一步就内存管理的各个方面进行探讨。

二、概述

oracle的内存可以按照共享和私有的角度分为系统全局区和进程全局区,也就是SGA和PGA(processglobalareaorprivateglobalarea。

对于SGA区域内的内存来说,是共享的全局的,在UNIX上,必须为oracle设置共享内存段(可以是一个或者多个,因为oracle在UNIX上是多进程;而在WINDOWS上oracle是单进程(多个线程,所以不用设置共享内存段。

PGA是属于进程(线程私有的区域。

在oracle使用共享服务器模式下(MTS,PGA中的一部分,也就是UGA会被放入共享内存large_pool_size中。

对于SGA部分,我们通过sqlplus中查询可以看到:

SQL>select*fromv$sga;

NAMEVALUE

FixedSize454032

VariableSize109051904

DatabaseBuffers385875968

RedoBuffers667648

其中:

FixedSize:

oracle的不同平台和不同版本下可能不一样,但对于确定环境是一个固定的值,里面存储了SGA各部分组件的信息,可以看作引导建立SGA的区域。

VariableSize:

包含了shared_pool_size、java_pool_size、large_pool_size等内存设置DatabaseBuffers:

指数据缓冲区,在8i中包含db_block_buffer*db_block_size、buffer_pool_keep、buffer_pool_recycle三部分内存。

在9i中包含db_cache_size、

db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size。

RedoBuffers:

指日志缓冲区,log_buffer。

在这里要额外说明一点的是,对于v$parameter、v$sgastat、v$sga查询值可能不一样。

v$parameter里面的值,是指用户在初始化参数文件里面设置的值,v$sgastat是oracle实际分配的日志缓冲区大小(因为缓冲区的分配值实际上是离散的,也不是以block为最小单位进行分配的,v$sga里面查询的值,是在oracle分配了日志缓冲区后,为了保护日志缓冲区,设置了一些保护页,通常我们会发现保护页大小大约是11k(不同环境可能不一样。

参考如下内容

SQL>selectsubstr(name,1,10name,substr(value,1,10value

2fromv$parameterwherename='log_buffer';

NAMEVALUE

log_buffer524288

SQL>select*fromv$sgastat;

POOLNAMEBYTES

fixed_sga454032

buffer_cache385875968

log_buffer656384

SQL>select*fromv$sga;

NAMEVALUE

FixedSize454032

VariableSize109051904

DatabaseBuffers385875968

RedoBuffers667648

关于各部分内存的作用,参考oracle体系结构,在此不再叙述。

l、SGA的大小

那么我们现在来考察内存参数的设置。

实际上,对于特定的环境,总是存在着不同的最优设置的,没有任何一种普遍适用的最优方案。

但为什么在这里我们还要来谈设置这个话题呢,那仅仅是出于一个目的,避免过度的犯错误。

事实

上,在任何一个生产系统正式投入使用之前,我们不拥有任何系统运行信息让我们去调整,这样就只有两种可能,一是根据文档推荐设置,另外一种就是根据经验设置。

相对来说,根据经验的设置比根据文档的设置要可靠一些。

尤其是那些24*7的系统,我们更要减少错误的发生。

那么我们尝试去了解不同的系统不同的应用的具体设置情况,从而提供一个参照信息给大家。

为了得出一个参照设置,我们就必须假定一个参照环境。

以下所有设置我们基于这样一个假定,那就是硬件服务器上只考虑存在操作系统和数据库,在这个单一的环境中,我们来考虑内存的设置。

在设置参数之前呢,我们首先要问自己几个问题

1物理内存多大

2操作系统估计需要使用多少内存

3数据库是使用文件系统还是裸设备

4有多少并发连接

5应用是OLTP类型还是OLAP类型

根据这几个问题的答案,我们可以粗略地为系统估计一下内存设置。

那我们现在来逐个问题地讨论,首先物理内存多大是最容易回答的一个问题,然后操作系统估计使用多少内存呢?

从经验上看,不会太多,通常应该在200M以内(不包含大量进程PCB。

接下来我们要探讨一个重要的问题,那就是关于文件系统和裸设备的问题,这往往容易被我们所忽略。

操作系统对于文件系统,使用了大量的buffer来缓存操作系统块。

这样当数据库获取数据块的时候,虽然SGA中没有命中,但却实际上可能是从操作系统的文件缓存中获取的。

而假如数据库和操作系统支持异步IO,则实际上当数据库写进程DBWR写磁盘时,操作系统在文件缓存中标记该块为延迟写,等到真正地写入磁盘之后,操作系统才通知DBWR写磁盘完成。

对于这部分文件缓存,所需要的内存可能比较大,作为保守的估计,我们应该考虑在0.2—0.3倍内存大小。

但是如果我们使用的是裸设备,则不考虑这部分缓存的问题。

这样的情况下SGA就有调大的机会。

关于数据库有多少并发连接,这实际上关系到PGA的大小(MTS下还有large_pool_size。

事实上这个问题应该说还跟OLTP类型或者OLAP类型相关。

对于OLTP类型oracle倾向于可使用MTS,对于OLAP类型使用独立模式,同时OLAP还可能涉及到大量的排序操作的查询,这些都影响到我们内存的使用。

那么所有的问题综合起来,实际上主要反映在UGA的大小上。

UGA主要包含以下部分内存设置

SQL>showparametersarea_size

NAMETYPEVALUE

bitmap_merge_area_sizeinteger1048576

create_bitmap_area_sizeinteger8388608

hash_area_sizeinteger131072

sort_area_sizeinteger65536

SQL>

OS使用内存+SGA+并发执行进程数*(sort_area_size+hash_ara_size+2M<

0.7*总内存

(公式是死的,系统是活的,实际应用的调整不必框公式,这不过是一个参考建议在我们的实际应用中,假如采用的是裸设备,我们可适当的增大SGA(如果需要的话。

由于目前几乎所有的操作系统都使用虚拟缓存,所以实际上如果就算SGA设置的比较大也不会导致错误,而是可能出现频繁的内存页的换入与换出(pagein/out。

在操作系统一级如果观察到这个现象,那么我们就需要调整内存的设置。

lSGA内参数设置

Log_buffer

对于日志缓冲区的大小设置,通常我觉得没有过多的建议,因为参考LGWR写的触发条件之后,我们会发现通常超过3M意义不是很大。

作为一个正式系统,可能考虑先设置这部分为log_buffer=1—3M大小,然后针对具体情况再调整。

Large_pool_size对于大缓冲池的设置,假如不使用MTS,建议在20—30M足够了。

这部分主要用来保存并行查询时候的一些信息,还有就是RMAN在备份的时候可能会使用到。

如果设置了MTS,则由于UGA部分要移入这里,则需要具体根据serverprocess数量和相关会话内存参数的设置来综合考虑这部分大小的设置。

Java_pool_size

假如数据库没有使用JAVA,我们通常认为保留10—20M大小足够。

事实上可以更少,甚至最少只需要32k,但具体跟安装数据库的时候的组件相关(比如httpserver。

shared_pool_size

这是迄今为止最具有争议的一部分内存设置。

按照很多文档的描述,这部分内容应该几乎和数据缓冲区差不多大小。

但实际上情况却不是这样的。

首先我们要考究一个问题,那就是这部分内存的作用,它是为了缓存已经被解析过的SQL,而使其能被重用,不再解析。

这样做的原因是因为,对于一个新的SQL(shared_pool里面不存在已经解析的可用的相同的SQL,数据库将执行硬解析,这是一个很消耗资源的过程。

而若已经存在,则进行的仅仅是软分析(在共享池中寻找相同SQL,这样消耗的资源大大减少。

所以我们期望能多共享一些SQL,并且如果该参数设置不够大,经常会出现ora-04031错误,表示为了解析

新的SQL,没有可用的足够大的连续空闲空间,这样自然我们期望该参数能大一些。

但是该参数的增大,却也有负面的影响,因为需要维护共享的结构,内存的增大也会使得SQL的老化的代价更高,带来大量的管理的开销,所有这些可能会导致CPU的严重问题。

在一个充分使用绑定变量的比较大的系统中,shared_pool_size的开销通常应该维持在300M以内。

除非系统使用了大量的存储过程、函数、包,比如oracleerp这样的应用,可能会达到500M甚至更高。

于是我们假定一个1G内存的系统,可能考虑设置该参数为100M,2G的系统考虑设置为150M,8G的系统可以考虑设置为200—300M。

对于一个没有充分使用或者没有使用绑定变量系统,这可能给我们带来一个严重的问题。

所谓没有使用bindvar的SQL,我们称为LiteralSQL。

也就是比如这样的两句SQL我们认为是不同的SQL,需要进行2次硬解析:

select*fromEMPwherename=‘TOM’;

select*fromEMPwherename=‘JERRY’;

假如把’TOM’和‘JERRY’换做变量V,那就是使用了bindvar,我们可以认为是同样的SQL从而能很好地共享。

共享SQL本来就是shared_pool_size这部分内存存在的本意,oracle的目的也在于此,而我们不使用bindvar就是违背了oracle的初衷,这样将给我们的系统带来严重的问题。

当然,如果通过在操作系统监控,没有发现严重的cpu问题,我们如果发现该共享池命中率不高可以适当的增加shred_pool_size。

但是通常我们不主张这部分内存超过800M(特殊情况下可以更大。

事实上,可能的话我们甚至要想办法避免软分析,这在不同的程序语言中实现方式有差异。

我们也可能通过设置session_cached_cursors参数来获得帮助(这将增大PGA。

Databuffer

现在我们来谈数据缓冲区,在确定了SGA的大小并分配完了前面部分的内存后,其余的,都分配给这部分内存。

通常,在允许的情况下,我们都尝试使得这部分内存更大。

这部分内存的作用主要是缓存DBBLOCK,减少甚至避免从磁盘上获取数据,在8i中通常是由db_block_buffers*db_block_size来决定大小的。

如果我们设置了buffer_pool_keep和buffer_pool_recycle,则应该加上后面

这两部分内存的大小。

9i下参数的变化

oracle的版本的更新,总是伴随着参数的变化,并且越来越趋向于使得参数的设置更简单,因为复杂的参数设置使得DBA们经常焦头烂额。

关于内存这部分的变化,我们可以考察下面的参数。

事实上在9i中数据库本身可以给出一组适合当前运行系统的SGA相关部分的参数调整值(参考V$DB_CACHE_ADVICE、V$SHARED_POOL_ADVICE,关于PGA也有相关视图V$PGA_TARGET_ADVICE等。

Databuffer

9i中保留了8i中的参数,如设置了新的参数,则忽略旧的参数。

9i中用db_cache_size来取代db_block_buffers,用db_keep_cache_size取代buffer_pool_keep,用db_recycle_cache_size取代buffer_pool_recycle;这里要注意9i中设置的是实际的缓存大小而不再是块的数量。

另外9i新增加了db_nk_cache_size,这是为了支持在同一个数据库中使用不同的块大小而设置的。

对于不同的表空间,可以定义不同的数据块的大小,而缓冲区的定义则依靠该参数的支持。

其中n可以为2、4、6、8、16等不同的值。

在这里顺便提及的一个参数就是db_block_lru_latches,该参数在9i中已经成为了保留参数,不推荐手工设置。

PGA

在9i里面这部分也有了很大的变化。

在独立模式下,9i已经不再主张使用原来的UGA相关的参数设置,而代之以新的参数。

假如workarea_size_policy=AUTO(缺省,则所有的会话的UGA共用一大块内存,该内存由pga_aggregate_target设置。

在我们根据前面介绍的方法评估了所有进程可能使用的最大PGA内存之后,我们可以通过在初始化参数中设置这个参数,从而不再关心其他”*_area_size”参数。

SGA_MAX_SIZE

在9i中若设置了SGA_MAX_SIZE,则在总和小于等于这个值内,可以动态的调整数据缓冲区和共享池的大小

SQL>showparameterssga_max_size

NAMETYPEVALUE

sga_max_sizeunknown193752940

SQL>

SQL>altersystemsetdb_cache_size=30000000;

Systemaltered.

SQL>altersystemsetshared_pool_size=20480000;

Systemaltered.

Lock_sga=true的问题

由于几乎所有的操作系统都支持虚拟内存,所以即使我们使用的内存小于物理内存,也不能避免操作系统将SGA换到虚拟内存(SWAP。

所以我们可以尝试使得SGA锁定在物理内存中不被换到虚拟内存中,这样减少页面的换入和换出,从而提高性能。

但在这里遗憾的是,windows是无法避免这种情况的。

下面我们来参考在不同的几个系统下怎么实现

lock_sga

logonaixasroot

cd/usr/samples/kernel

./vmtune(信息如下v_pingshm已经是1

./vmtune-S1

然后oracle用户修改initSID.ora中lock_sga=true

重新启动数据库

HPUNIX

Root身份登陆

Createthefile"/etc/privgroup":

vi/etc/privgroup

Addline"dbaMLOCK"tofile

Asroot,runthecommand"/etc/setprivgrp-f/etc/privgroup":

$/etc/setprivgrp-f/etc/privgroup

oracle用户修改initSID.ora中lock_sga=true

重新启动数据库

SOLARIS(solaris2.6以上

8i版本以上数据库默认使用隐藏参数use_ism=true,自动锁定SGA于内存中,不用设置lock_sga,如果设置lock_sga=true使用非root用户启动数据库将返回错误。

WINDOWS不能设置lock_sga=true,可以通过设置pre_page_sga=true,使得数据库启动的时候就把所有内存页装载,这样可能起到一定的作用。

关于内存参数的调整

关于参数调整,是oracle的复杂性的一个具体体现。

通常来讲,我们更倾向于让客户做statspack报告,然后告诉我们os监控的状况,在这些的信息的基础上,再向客户索取具体的详细信息以诊断问题的所在。

系统的调整,现在我们通常采用从等待事件入手的方法。

因为一个系统感觉到慢,必然是在某个环节上出现等待,那么我们从等待最多的事件入手逐步诊断并解决问题。

对于内存的调整,相对来说简单一些,我们首先可以针对数据缓冲区的大小来看。

首先观察命中率

数据缓冲区命中率

SQL>selectvaluefromv$sysstatwherename='physicalreads';

VALUE

14764

SQL>selectvaluefromv$sysstatwherename='physicalreadsdirect';

VALUE

50

SQL>selectvaluefromv$sysstatwherename='physicalreadsdirect(lob';

VALUE

SQL>selectvaluefromv$sysstatwherename='consistentgets';

VALUE

167763

SQL>selectvaluefromv$sysstatwherename='dbblockgets';

VALUE

14305

这里命中率的计算应该是令x=physicalreadsdirect+physicalreadsdirect(lob命中率=100-(physicalreads-x/(consistentgets+dbblockgets-x*100通常如果发现命中率低于90%,则应该调整应用可可以考虑是否增大数据缓冲区共享池的命中率

SQL>selectsum(pinhits-reloads/sum(pins*100"hitradio"fromv$librarycache;

hitradio

99.809291

假如共享池的命中率低于95%,就要考虑调整应用(通常是没使用bindvar或者增加内存

关于排序部分

SQL>selectname,valuefromv$sysstatwherenamelike'%sort%';

NAMEVALUE

sorts(memory67935

sorts(disk1

sorts(rows7070

SQL>

假如我们发现sorts(disk/(sorts(memory+sorts(disk的比例过高,则通常意味着sort_area_size部分内存较小,可考虑调整相应的参数。

关于log_buffer

SQL>selectname,valuefromv$sysstat

wherenamein('redoentries','redobufferallocationretries';

NAMEVALUE

redoentries2325719

redobufferallocationretries10

假如redobufferallocationretries/redoentries的比例超过1%我们就可以考虑增大log_buffer通常来说,内存的调整的焦点就集中在这几个方面,更多更详细的内容,建议从statspack入手来一步一步调整。

最后关于内存的调整,再强调这一点,一定要结合操作系统来衡量,任何理论都必须要实践来检验。

在操作系统中观察pagein/out状况,发现问题严重,应该考虑调小SGA。

l32bit和64bit的

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 育儿理论经验

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1