内存结构

这一篇主要讨论oracle的3个主要的内存结构:
1.系统全局区(system global area, SGA):这是一个很大的 共享内存段,几乎所有oarcle进程都要访问这个区中的某一点。
2.进程全局区(process global area, PGA):这是一个 进程或线程专用的内存,其他进程/线程不能访问。
3.用户全局区(user global area, UGA):这个内存区与特定的 会话相关联。他可能在SGA中分配,也可能在PGA中分配,这取决于是用共享服务器还是用专用服务器来连接数据库。

3.1 进程全局区和用户全局区
PGA是特定于进程的一段内存。PGA 绝对不会在oracle的SGA中分配,而总是由进程或线程在本地分配。
实际上,对你来说,UGA就是你的会话的状态。会话总能访问这部分内存。UGA的位置完全取决于你如何连接oracle。
PGA的内存管理分为手动管理和自动管理,手动管理要DBA设置各参数的值,这不太容易,一般倾向于自动管理。具体的管理策略这里不展开了。

3.2 系统全局区
每个oracle实例都有一个很大的内存结构,称为系统全局区(system global area, SGA)。 这是一个庞大的共享内存结构。

SGA分为不同的池(pool):
(1)Java池(java pool):java池是为数据库中运行的jvm分配的一段固定大小的内存。在oracle 10中,java池可以在数据库启动并运行时在线调整大小。
(2)大池(large pool):共享服务器连接使用大池作为会话内存,并行执行特性使用大池作为消息缓存区,另外RMAN备份可能使用大池作为磁盘IO缓冲区。大池可以在线调整大小。
(3)共享池(shared pool):共享池包含共享游标,存储过程,状态对象,字典缓存和诸如此类的大量其他数据。在oracle10和9中,共享池都可以在线调整大小。
(4)流池(stream pool):这是oracle流专用的一个内存池,oracle流是数据库中地一个数据共享工具,是oracle10中新增的,可以在线调整大小。
(5)空池(NULL pool):这个池其实没有名字。这是块缓冲区,重做日志缓冲区和固定SGA区专用的内存。

3.2.1 共享池
共享池是SGA中最重要的内存段之一,特别是对于性能和可扩展性来说。共享池如果太小,会严重影响性能,甚至导致系统看上去像终止了一样。如果共享池太大,也会有同样的效果。共享池使用不当会导致灾难性的后果。

共享池就是oracle缓存一些“程序”数据的地方。 在解析一个查询时,解析得到的表示(representation)就缓存在那里。在完成解析整个查询的任务之前,oracle会搜索共享池,看看这个工作是否已经完成。你运行的pl/sql代码不仅在这里缓存,还会在这里共享。如果有1000个会话都在执行同样的代码,那么只会加载这个代码的一个副本,并由所有会话共享。Oracle把系统参数存储在共享池中。数据字典缓存(关于数据库对象的已缓存信息)也存储在这里。
共享池的特点就是有大量小的内存块,一般为4KB或更小。我们的目标是使用小块的内存来避免碎片问题,共享池的内存根据LRU的原则来管理。

如果真的想破坏oracle的共享池,最容易的办法是不使用绑定变量。如果不使用绑定变量,可能会让系统陷于瘫痪,有两个原因:
(1) 系统要花大量cpu时间解析查询。
(2) 系统使用大量资源来管理共享池中的对象,因为从来不重用查询。

如果提交到oracle的每个查询都是具有硬编码值的唯一查询,则共享池的概念就一点用都没有。设计共享池是为了反复使用查询计划。 如果每个查询都是全新的,那么缓存只会增加开销。共享池反而会损害性能。对于这个问题, 真正的解决方案只有一个,就是使用共享sql,也就是重用查询。

与管理PGA内存一样,从oracle10开始,管理SGA内存也有两种方法:手动管理和自动管理。手动管理需要设置所有必要的池和缓存参数,自动管理只需设置少数几个内存参数和一个SGA_TARGET参数。通过设置SGA_TARGET参数,实例就能设置各个SGA组件的大小以及调整他们的大小。
从oracle 11g 开始,oracle数据库还提供了自动内存管理,相当于可以一站式完成所有内存设置。在oracle 11g中,DBA现在只需设置一个内存参数,memory_target,这个参数表示SGA和PGA分配能达到的总内存量。

你可能感兴趣的:(绑定变量,PGA,UGA,SGA)