鱼儿的Oracle空间

暂无签名

  • 博客访问: 1678466
  • 博文数量: 412
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-16 15:45
个人简介

暂无介绍

ITPUB论坛APP

ITPUB论坛APP



APP发帖 享双倍积分

文章分类

全部博文(412)

文章存档

2017年(2)

2016年(44)

2015年(74)

2014年(28)

2013年(33)

2012年(38)

2011年(80)

2010年(113)

微信关注

IT168企业级官微



微信号:IT168qiye



系统架构师大会



微信号:SACC2013

订阅
热词专题
Oracle SGA详解 2010-12-17 10:57:41

分类: Linux

    SGA(System Global Area)系统全局区。这是一个非常庞大的内存区间,也是为什么开启oracle之后占用了很大内存的原因。

    SGA分为不同的池,我们可以通过视图v$sgastat查看,如下所示。

SQL> select pool ,sum(bytes) bytes from v$sgastat group by pool;

POOL              BYTES
------------ ----------
              956298240
java pool      16777216
streams pool   16777216
shared pool   199783376
large pool     16777216

SQL>

    我们可以看到SGA由java pool(java 池)、shared pool(共享池)、large pool(大池) 和没有名字的池组成。其中那块没有名字的内存又包括块缓冲区(缓存的数据库块)、重做日志缓冲区和“固定SGA”区专用的内存。

oracle SGA内存结构如下所示:


 下面逐个介绍:

1、Fixed SGA 固定SGA

      可以把这个区想成是 SGA中的“自启”区,Oracle在内部要使用这个区来找到SGA的其他区。换一句话,就是在这个内存里面存有其他区的地址,我们可以通过访问这个区来查找到其他区的位置!

2、Redo Buffer 重做缓冲区

      如果数据需要写到在线重做日志中,则在写至磁盘之前要在重做缓冲区(redo buffer)中临时缓存这些数据。由于内存到内存的传输比内存到磁盘的传输快得多,因此使用重做日志缓冲区可以加快数据库的操作。我的理解是,如果没有这个区,那我们操作一次数据库就访问一次磁盘,而如果有的话,则可以操作很多次之后才访问一次磁盘。速度当然要快很多了。

3、Block Buffer 块缓冲区缓存

       Oracle将数据库块写至磁盘之前,另外从磁盘读取数据库块之后,就会把这些数据库块存储在块缓冲区缓存(block buffer cache)中。对我们来说,这是SGA中一个很重要的区。如果太小,我们的查询就会永远也运行不完。如果太大,又会让其他进程饥饿(例如,没有为专用服务器留下足够的空间来创建其PGA,甚至无法启动)。这个其实是缓存数据,也是为什么你第二次进行同一个操作的时候比第一次要快的原因,因为他可以直接从这个缓存里面取就可以了!但是如果你第二天来继续进行同一操作应该是比较慢的,因为在那个缓存里面已经没有你要取的数据了!( 就是通常说的内存老化,也就是缓存你数据的那块内存被别人用了。这就是LRU算法),为了使自己要的数据不那么快老化。oracle把这块内存划分为三种类型:

     默认池(default pool):所有段块一般都在这个池中缓存。这就是原先的缓冲区池(原来也只有一个缓冲区池)。
     保持池(keep pool):按惯例,访问相当频繁的段会放在这个候选的缓冲区池中,如果把这些段放在默认缓冲区池中,尽管会频繁访问,但仍有可能因为其他段需要空间而老化(aging)。
     回收池(recycle pool):按惯例,访问很随机的大段可以放在这个候选的缓冲区池中,这些块会导致过量的缓冲区刷新输出,而且不会带来任何好处,因为等你想要再用这个块时,它可能已经老化退出了缓存。要把这些段与默认池和保持池中的段分开,这样就不会导致默认池和保持池中的块老化而退出缓存。

4、shared pool(共享池)

     共享池就是Oracle缓存一些“程序”数据的地方。在解析一个查询时,解析得到的表示(representation)就缓存在那里。在完成解析整个查询的任务之前, Oracle会搜索共享池,看看这个工作是否已经完成。你运行的PL/SQL代码就在共享池中缓存,所以下一次运行时,Oracle不会再次从磁盘重新读取。PL/SQL代码不仅在这里缓存,还会在这里共享。如果有1 000个会话都在执行同样的代码,那么只会加载这个代码的一个副本,并由所有会话共享。Oracle把系统参数存储在共享池中。数据字典缓存(关于数据库对象的已缓存信息)也存储在这里。简单地讲,就像是厨房的水池一样,什么东西都往共享池里放。我的理解是:这是个共用的东西,大家都可以用。比如一个用户进行一次查询,在解析之前,查看共享池,这个sql语句是否已经缓存在这里了。如果在,他就没有必要再去进行解析了,因为已经解析好了,直接拿来用就可以了!这也是绑定变量为什么可以改善oracle性能的原因!

5、large pool 大池

    大池(large pool)并不是因为它是一个“大”结构才这样取名(不过,它可能确实很大)。之所以称之为大池,是因为它用于大块内存的分配,共享池不会处理这么大的内存块。
在Oracle 8.0引入大池之前,所有内存分配都在共享池中进行。如果你使用的特性要利用“大块的”内存分配(如共享服务器UGA内存分配),倘若都在共享池中分配就不太好。另外,与共享池管理内存的方式相比,处理(需要大量内存分配)会以不同的方式使用内存,所以这个问题变得更加复杂。共享池根据LRU来管理内存,这对于缓存和重用数据很合适。不过,大块内存分配则是得到一块内存后加以使用,然后就到此为止,没有必要缓存这个内存。我的理解是:其实是把原来属于共享池里面的一些特殊的内存拿出来进行不同的处理。因为这些内存用完之后就可以立即释放,而共享池的内存不存在释放问题,因为是大家共享的。

     大池专门用于以下情况:
共享服务器连接,用于在SGA中分配UGA区,因为一个用户断开之后,UGA就可以立即释放!
语句的并行执行,允许分配进程间的消息缓冲区,这些缓冲区用于协调并行查询服务器。一旦发送了缓冲消息就可以立即释放!
备份,在某些情况下用于RMAN磁盘I/O 缓冲区。因为写入磁盘之后,这些缓存可以立即释放!

6、Java pool Java池

    在数据库中运行Java代码时用到这部分内存。例如:编写Java存储过程在服务器内运行。需要注意的是,该内存与常见的Java编写的B/S系统并没关系。用JAVA语言代替PL/SQL语言在数据库中写存储过程才会用到这部分内存。

7、Stream pool 流池

    9iR2以上增加了“流”技术,10g以上在SGA中增加了流池。流是用来共享和复制数据的工具。

SGA设置

    没有通用的设置,所有设置都要根据系统的负载、业务需求和硬件环境来进行调整。这里只是总结出大体的设定,避免因SGA设置不当引起的问题。

1、自动SGA内存管理
        在Oracle 10g中引入了自动SGA内存管理特性,DBA可以设定SGA_TARGET告诉Oracle可用的SGA内存为多大,由Oracle根据系统负载来动态调整各组件大小,相应的数定会保存在控制文件中,使数据库重启后也记得各组件大小。
       需要注意一下几点:
   要使用自动SGA内存管理,STATISTICS_LEVEL参数必须设为TYPICAL或ALL,系统自动收集相应的信息用来动态调整SGA设定。
   可以设定某个组件的值,Oracle使用此值为该组件的最小大小。

       可动态调整的参数:
       DB_CACHE_SIZE,SHARED_POOL_SIZE,LARGE_POOL_SIZE,JAVA_POOL_SIZE。
       需手动设置的参数:
       LOG_BUFFER,STREAMS_POOL,DB_NK_CACHE_SIZE,DB_KEEP_CACHE_SIZE,DB_RECYCLE_CACHE_SIZE。

2、手动SGA内存管理
1)  32bit和64bit限制
在32位的操作系统中,Oracle最大可用内存为1.75g,也就是说SGA+PGA<=1.75g,超过这一限制的内存将不会被Oracle用到。
32位的Oracle可以装到64位的操作系统上,64位的Oracle不可以装到32位的操作系统上。

2)  查看Oracle版本:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production

TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

3)  各组件设置:
JAVA_POOL_SIZE:如果没用到数据库端java的系统,30MB足够。

LOG_BUFFER:默认为MAX(512KB,128KB*CPU个数)。一般系统1MB足够,运行大型事务的系统可以设为2MB,让1/3满写入日志文件时可以继续写入缓冲,再大也没有意义。

SHARED_POOL_SIZE:过大过小都会严重影响系统性能,1GB内存可以设为100MB,2GB内存可设为150MB,4GB内存可设为300MB。共享池命中过低首先要调整的是应用程序而不是扩大共享池。使用绑定变量可以减少共享池需求、提高命中率,减少共享池管理负担和LATCH竞争。

LARGE_POOL_SIZE:使用专用服务模式可设为30MB,除非必要,不然不建议使用共享服务器模式。

DB_CACHE_SIZE:除去上述内存外其他可用内存都分配给该区域。

总结
32位Oracle:
1G内存:SHARED_POOL_SIZE=100MB,DB_CACHE_SIZE=0.5GB;
2G内存:SHARED_POOL_SIZE=150MB,DB_CACHE_SIZE=1.25GB;

64位Oracle
4G内存:SHARED_POOL_SIZE=200MB,DB_CACHE_SIZE=2.5GB;
8G内存:SHARED_POOL_SIZE=400MB,DB_CACHE_SIZE=5GB;
12G内存:SHARED_POOL_SIZE=500MB,DB_CACHE_SIZE=8GB

再次强调,以上只是避免因SGA设置不当引起问题的大体设置,需要根据具体的系统负载和业务逻辑结合Stackpack等工具细调。

阅读(17856) | 评论(0) | 转发(4) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册