前言

对于oracle的内存的管理,截止到9iR2,都是相当重要的环节,管理不善,将可能给数据库带来严重的性能问题。下面我们将一步一步就内存管理的各个方面进行探讨。

oracle的内存可以按照共享和私有的角度分为系统全局区和进程全局区,也就是SGA和PGA(process global area or private global area)。对于SGA区域内的内存来说,是共享的全局的,在UNIX上,必须为oracle设置共享内存段(可以是一个或者多个),因为oracle在UNIX上是多进程;而在WINDOWS上oracle是单进程(多个线程),所以不用设置共享内存段。PGA是属于进程(线程)私有的区域。在oracle使用共享服务器模式下(MTS),PGA中的一部分,也就是UGA会被放入共享内存large_pool_size中。

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

SQL> select * from v$sga;

NAMEVALUE

------------------------------

Fixed Size454032

Variable Size109051904

Database Buffers385875968

Redo Buffers667648

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

包含了shared_pool_size、java_pool_size、large_pool_size等内存设置和用于管理数据缓冲区等内存结构的hash table、块头信息(比如x$bh消耗内存)等

指数据缓冲区,在8i中包含default pool、buffer_pool_keep、buffer_pool_recycle三部分内存。在9i中包含db_cache_size、db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size。这里要注意在8i中三部分内存总和为db_block_buffers*db_block_size。

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

SQL>select substr(name,1,10) name,substr(value,1,10) value

2from v$parameter where name = 'log_buffer';

NAMEVALUE

----------------------------------------

log_buffer524288

SQL> select * from v$sgastat ;

POOLNAMEBYTES

------------------------------

fixed_sga454032

buffer_cache385875968

log_buffer656384

SQL> select * from v$sga;

NAMEVALUE

------------------------------

Fixed Size454032

Variable Size 109051904

Database Buffers385875968

Redo Buffers667648

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

、SGA的大小

那么我们现在来考察内存参数的设置。实际上,对于特定的环境,总是存在着不同的最优设置的,没有任何一种普遍适用的最优方案。但为什么在这里我们还要来谈设置这个话题呢,那仅仅是出于一个目的,避免过度的犯错误。事实上,在任何一个生产系统正式投入使用之前,我们不拥有任何系统运行信息让我们去调整,这样就只有两种可能,一是根据文档推荐设置,另外一种就是根据经验设置。相对来说,根据经验的设置比根据文档的设置要可靠一些。尤其是那些24*7的系统,我们更要减少错误的发生。那么我们尝试去了解不同的系统不同的应用的具体设置情况,从而提供一个参照信息给大家。

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

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

一:物理内存多大

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

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

四:有多少并发连接

五:应用是OLTP类型还是OLAP类型

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

首先:物理内存多大是最容易回答的一个问题,使用命令:systeminfo查看.

然后:操作系统估计使用多少内存呢?从经验上看,不会太多,通常应该在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> show parameters area_size

NAMETYPEVALUE

--------------------------------------------------------

bitmap_merge_area_sizeinteger1048576

create_bitmap_area_sizeinteger8388608

hash_area_sizeinteger131072

sort_area_sizeinteger65536

在这部分内存中我们最关注的通常是sort_area_size,这是当查询需要排序的时候,数据库会话将使用这部分内存进行排序,当内存大小不足的时候,使用临时表空间进行磁盘排序。由于磁盘排序效率和内存排序效率相差好几个数量级,所以这个参数的设置很重要。

这四个参数都是针对会话进行设置的,是单个会话使用的内存的大小,而不是整个数据库使用的。偶尔会看见有人误解了这个参数以为是整个数据库使用的大小,这是极其严重的错误。假如设置了MTS,则UGA被分配在large_pool_size,也就是说放在了共享内存里面,不同进程(线程)之间可以共享这部分内存。在这个基础上,我们假设数据库存在并发执行serverprocess为100个,根据上面我们4个参数在oracle8.1.7下的默认值,我们来计算独立模式下PGA的大致大小。由于会话并不会经常使用create_bitmap_area_size、bitmap_merge_area_size,所以我们通常不对四个参数求和。在考虑到除这四个参数外会话所保存的变量、堆栈等信息,我们估计为2M,则100个进程最大可能使用200M的PGA。

现在,根据上面这些假定,我们来看SGA实际能达到多少内存。在1G的内存的服务器上,我们能分配给SGA的内存大约为400—500M。若是2G的内存,大约可以分到1G的内存给SGA,8G的内存可以分到5G的内存给SGA。当然我们这里是以默认的排序部分内存sort_area_size=64k进行衡量的,假如我们需要调大该参数和hash_area_size等参数,然后我们应该根据并发的进程的数量,来衡量考虑这个问题。

事实上,通常我们更习惯通过直观的公式化来表达这样的问题:

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

(公式是死的,系统是活的,实际应用的调整不必框公式,这不过是一个参考建议)

在我们的实际应用中,假如采用的是裸设备,我们可适当的增大SGA(如果需要的话)。由于目前几乎所有的操作系统都使用虚拟缓存,所以实际上如果就算SGA设置的比较大也不会导致错误,而是可能出现频繁的内存页的换入与换出(page in/out)。在操作系统一级如果观察到这个现象,那么我们就需要调整内存的设置。

、SGA内参数设置

对于日志缓冲区的大小设置,通常我觉得没有过多的建议,因为参考LGWR写的触发条件之后,我们会发现通常超过3M意义不是很大。作为一个正式系统,可能考虑先设置这部分为log_buffer=1—3M大小,然后针对具体情况再调整。

对于大缓冲池的设置,假如不使用MTS,建议在20—30M足够了。这部分主要用来保存并行查询时候的一些信息,还有就是RMAN在备份的时候可能会使用到。如果设置了MTS,则由于UGA部分要移入这里,则需要具体根据server process数量和相关会话内存参数的设置来综合考虑这部分大小的设置。

假如数据库没有使用JAVA,我们通常认为保留10—20M大小足够。事实上可以更少,甚至最少只需要32k,但具体跟安装数据库的时候的组件相关(比如http server)。

这是迄今为止最具有争议的一部分内存设置。按照很多文档的描述,这部分内容应该几乎和数据缓冲区差不多大小。但实际上情况却不是这样的。首先我们要考究一个问题,那就是这部分内存的作用,它是为了缓存已经被解析过的SQL,而使其能被重用,不再解析。这样做的原因是因为,对于一个新的SQL(shared_pool里面不存在已经解析的可用的相同的SQL),数据库将执行硬解析,这是一个很消耗资源的过程。而若已经存在,则进行的仅仅是软分析(在共享池中寻找相同SQL),这样消耗的资源大大减少。所以我们期望能多共享一些SQL,并且如果该参数设置不够大,经常会出现ora-04031错误,表示为了解析新的SQL,没有可用的足够大的连续空闲空间,这样自然我们期望该参数能大一些。但是该参数的增大,却也有负面的影响,因为需要维护共享的结构,内存的增大也会使得SQL的老化的代价更高,带来大量的管理的开销,所有这些可能会导致CPU的严重问题。

在一个充分使用绑定变量的比较大的系统中,shared_pool_size的开销通常应该维持在300M以内。除非系统使用了大量的存储过程、函数、包,比如oracle erp这样的应用,可能会达到500M甚至更高。于是我们假定一个1G内存的系统,可能考虑设置该参数为100M,2G的系统考虑设置为150M,8G的系统可以考虑设置为200—300M。

对于一个没有充分使用或者没有使用绑定变量系统,这可能给我们带来一个严重的问题。所谓没有使用bind var的SQL,我们称为Literal SQL。也就是比如这样的两句SQL我们认为是不同的SQL,需要进行2次硬解析:

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12330444/viewspace-310095/,如需转载,请注明出处,否则将追究法律责任。

为oracle分配空间,ORACLE内存分配与调整(一)相关推荐

  1. 静态内存分配与动态内存分配

    静态内存分配与动态内存分配 动机 平时看c/c++的书籍时,总会看到一种观点,说是C/C++语言使用的时候动态内存分配是最重要的,使用malloc等函数分配的内存必须要释放,否则及其容易出现内存泄露. ...

  2. 数组大小分配(动态内存分配)

    在使用数组的时候,总是有一个问题,数组应该有多大? 在很多情况下,我们无法确定要使用多大的数组.一般申请大于估计数目的固定大小,这样程序在运行时就申请了固定的大小,你觉得数组定义足够大,但是如果某种原 ...

  3. 【c++内存系列】二、c++动态内存分配和静态内存分配

    一.内存的静态分配与动态分配方式 先简单理解静态分配与动态分配: 静态内存分配和动态内存分配比较典型的例子就是数组和链表,数组的长度是预先定义好的,在整个程序中是固定不变的,所以他在内存分配时是以静态 ...

  4. oracle linux内存推荐分配,[20191114]linux内存分配的讨论.txt

    [20191114]linux内存分配的讨论.txt --//链接http://www.itpub.net/thread-2121531-1-1.html上的讨论. # sysctl -p net.i ...

  5. Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组...

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:什么是静态内存什么又是动态内存呢? 静态内存:是指在程序开始运行时由编译 ...

  6. C语言静态内存分配与动态内存分配

    C语言中,内存主要分为5个区,分别为栈区.堆区.全局/静态存储区.常量存储区.代码区. 其中代码区存放源程序的二进制代码,其余四个区都存储进程运行过程中需要的存储的变量. 变量的内存分配有两种:静态与 ...

  7. 动态内存分配与静态内存分配

    文章目录 一.静态内存管理 二.动态内存管理 1.为什么存在动态内存管理 2.动态内存函数的介绍 1).malloc 2.calloc 3.realloc 4.free 5.动态开辟空间代码的标准写法 ...

  8. 评估应用使用oracle磁盘空间,Oracle磁盘空间使用统计

    对于大型数据库,Oracle占用的磁盘空间非常大,掌握数据库中那些用户.表占用了多杀磁盘空间,以及增长情况,可以方便日后对磁盘系统进行维护和扩充. 对Oracle磁盘空间使用情况,可以分为按照表空间. ...

  9. 如何手动修改oracle表空间,ORACLE数据库创建和修改表空间

    -建立表空间(oracle中的tablespace(表空间)) CREATE TABLESPACE data01 DATAFILE 'D:\oracle\ora92\oradata\db\DATA01 ...

  10. linux内存分配机制,Linux内存分配机制:SLAB / SLUB / SLOB

    Linux内存分配机制:SLAB / SLUB / SLOB [日期:2011-07-15] 来源:Linux社区 作者:do2jiang [字体:大 中 小] slob: introduce the ...

最新文章

  1. 全自动安装 linux光盘,CentOS 7.1全自动安装光盘制作详解
  2. jquery基础选择器和层次选择器
  3. MR Shuffle流程 入门
  4. vb与mysql实现登录界面_VB连接SQL数据库做用户登录窗口
  5. 【人脸识别】arcface-pytorch代码解析
  6. 图片验证码的测试用例梳理
  7. 电商一定是一元化结构
  8. 浏览器主页被篡改劫持怎么办
  9. Orcad 16.6中批量修改网络名
  10. Windows上WinRAR.exe命令行参数说明
  11. KMPlayer播放mkv视频不出声音的解决办法
  12. Access Violation(非法访问)解析
  13. 远程服务器搭建建站助手,windows + 管理助手建站指南
  14. 通过Servlet生成验证码图片
  15. 胃与十二指肠溃疡的食疗方
  16. java浮点数减法_浮点数的相关运算Java实现
  17. python中,除法运算后取整数的几种情况
  18. cozmo vector的起源最详细的说明
  19. android 读取手机存储数据恢复,Android智能手机数据恢复方法浅析
  20. python x=[random.randint(0,100) for i in range(50)]什么意思?列表解析

热门文章

  1. 人的9种2266对联文字的世界纪录(图)
  2. 卫星星座 - 2021 年行业调查和趋势 Satellite Constellations - 2021 Industry Survey and Trends阅读报告
  3. CAD注册机注册码不能正常使用,解决方案
  4. 必须知道的python专属骚技巧25例
  5. html css ps切图教程,CSS切图学习之认识PHOTOSHOP(PS)
  6. 谷歌抢注18个“.中国”域名:下一盘很大的棋?
  7. Google新人的成长思考
  8. 微电影后期制作的流程
  9. 手绘类短视频怎么制作?从剪辑到配音,后期制作也很重要
  10. uva-10177 - (2/3/4)-D Sqr/Rects/Cubes/Boxes?