Oracle|SGA (System Global Area)详解

2天前 6.8k 0

Oracle|SGA (System Global Area)详解-1

顾名思义

    Oracle SGA (System Global Area)  Oracle 系统全局区,包含实例的数据和控制信息,由所有服务进程和后台进程共享。

Oracle|SGA (System Global Area)详解-2

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

Oracle|SGA (System Global Area)详解-1

内存结构

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)

  • 按惯例,访问很随机的大段可以放在这个候选的缓冲区池中,这些块会导致过量的缓冲区刷新输出,而且不会带来任何好处,因为等你想要再用这个块时,它可能已经老化退出了缓存。要把这些段与默认池和保持池中的段分开,这样就不会导致默认池和保持池中的块老化而退出缓存。

Oracle|SGA (System Global Area)详解-3

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中增加了流池。流是用来共享和复制数据的工具。

 

Oracle|SGA (System Global Area)详解-1

内存设置

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内存管理

  • 32bit和64bit限制

  • 在32位的操作系统中,Oracle最大可用内存为1.75g,也就是说SGA+PGA

相关文章

MySQL 9.0.0 新鲜出炉!支持向量类型
OCP 4.x 特性解读:可观测性、高可用和易用性全面升级
第 55 期:MySQL 频繁 Crash 怎么办?
openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存
Oracle 19C PDB迁移报错 ORA-17628: error 65338 returned by remote Oracle server
【ORACLE】Oracle数据库并发控制、多版本控制、数据库独立性与应用性能优化

发布评论