这一篇主要讨论oracle的3个主要的内存结构:
[b]1.系统全局区[/b](system global area, SGA):这是一个很大的[color=red]共享内存段[/color],几乎所有oarcle进程都要访问这个区中的某一点。
[b]2.进程全局区[/b](process global area, PGA):这是一个[color=red]进程或线程专用的内存[/color],其他进程/线程不能访问。
[b]3.用户全局区[/b](user global area, UGA):这个内存区与特定的[color=red]会话相关联[/color]。他可能在SGA中分配,也可能在PGA中分配,这取决于是用共享服务器还是用专用服务器来连接数据库。
[b]3.1 进程全局区和用户全局区[/b]
PGA是特定于进程的一段内存。PGA[color=red]绝对不会[/color]在oracle的SGA中分配,而总是由进程或线程在本地分配。
实际上,对你来说,UGA就是你的会话的状态。会话总能访问这部分内存。UGA的位置完全取决于你如何连接oracle。
PGA的内存管理分为手动管理和自动管理,手动管理要DBA设置各参数的值,这不太容易,一般倾向于自动管理。具体的管理策略这里不展开了。
[b]3.2 系统全局区[/b]
每个oracle实例都有一个很大的内存结构,称为系统全局区(system global area, SGA)。 这是一个庞大的共享内存结构。
SGA分为不同的池(pool):
[b](1)Java池[/b](java pool):java池是为数据库中运行的jvm分配的一段固定大小的内存。在oracle 10中,java池可以在数据库启动并运行时在线调整大小。
[b](2)大池[/b](large pool):共享服务器连接使用大池作为会话内存,并行执行特性使用大池作为消息缓存区,另外RMAN备份可能使用大池作为磁盘IO缓冲区。大池可以在线调整大小。
[b](3)共享池[/b](shared pool):共享池包含共享游标,存储过程,状态对象,字典缓存和诸如此类的大量其他数据。在oracle10和9中,共享池都可以在线调整大小。
[b](4)流池[/b](stream pool):这是oracle流专用的一个内存池,oracle流是数据库中地一个数据共享工具,是oracle10中新增的,可以在线调整大小。
[b](5)空池[/b](NULL pool):这个池其实没有名字。这是块缓冲区,重做日志缓冲区和固定SGA区专用的内存。
[b]3.2.1 共享池[/b]
共享池是SGA中最重要的内存段之一,特别是对于性能和可扩展性来说。共享池如果太小,会严重影响性能,甚至导致系统看上去像终止了一样。如果共享池太大,也会有同样的效果。共享池使用不当会导致灾难性的后果。
共享池就是oracle缓存一些“程序”数据的地方。[color=red]在解析一个查询时[/color],解析得到的表示(representation)就缓存在那里。在完成解析整个查询的任务之前,oracle会搜索共享池,看看这个工作是否已经完成。你运行的pl/sql代码不仅在这里缓存,还会在这里共享。如果有1000个会话都在执行同样的代码,那么只会加载这个代码的一个副本,并由所有会话共享。Oracle把系统参数存储在共享池中。数据字典缓存(关于数据库对象的已缓存信息)也存储在这里。
共享池的特点就是有大量小的内存块,一般为4KB或更小。我们的目标是使用小块的内存来避免碎片问题,共享池的内存根据LRU的原则来管理。
[color=red][b]如果真的想破坏oracle的共享池,最容易的办法是不使用绑定变量。[/b][/color]如果不使用绑定变量,可能会让系统陷于瘫痪,有两个原因:
(1) 系统要花大量cpu时间解析查询。
(2) 系统使用大量资源来管理共享池中的对象,因为从来不重用查询。
如果提交到oracle的每个查询都是具有硬编码值的唯一查询,则共享池的概念就一点用都没有。设计共享池是为了反复使用查询计划。[color=red]如果每个查询都是全新的,那么缓存只会增加开销。共享池反而会损害性能。[/color]对于这个问题,[color=blue]真正的解决方案只有一个,就是使用共享sql,也就是重用查询。[/color]
与管理PGA内存一样,从oracle10开始,管理SGA内存也有两种方法:手动管理和自动管理。手动管理需要设置所有必要的池和缓存参数,自动管理只需设置少数几个内存参数和一个SGA_TARGET参数。通过设置SGA_TARGET参数,实例就能设置各个SGA组件的大小以及调整他们的大小。
从oracle 11g 开始,oracle数据库还提供了自动内存管理,相当于可以一站式完成所有内存设置。在oracle 11g中,DBA现在只需设置一个内存参数,memory_target,这个参数表示SGA和PGA分配能达到的总内存量。
[b]1.系统全局区[/b](system global area, SGA):这是一个很大的[color=red]共享内存段[/color],几乎所有oarcle进程都要访问这个区中的某一点。
[b]2.进程全局区[/b](process global area, PGA):这是一个[color=red]进程或线程专用的内存[/color],其他进程/线程不能访问。
[b]3.用户全局区[/b](user global area, UGA):这个内存区与特定的[color=red]会话相关联[/color]。他可能在SGA中分配,也可能在PGA中分配,这取决于是用共享服务器还是用专用服务器来连接数据库。
[b]3.1 进程全局区和用户全局区[/b]
PGA是特定于进程的一段内存。PGA[color=red]绝对不会[/color]在oracle的SGA中分配,而总是由进程或线程在本地分配。
实际上,对你来说,UGA就是你的会话的状态。会话总能访问这部分内存。UGA的位置完全取决于你如何连接oracle。
PGA的内存管理分为手动管理和自动管理,手动管理要DBA设置各参数的值,这不太容易,一般倾向于自动管理。具体的管理策略这里不展开了。
[b]3.2 系统全局区[/b]
每个oracle实例都有一个很大的内存结构,称为系统全局区(system global area, SGA)。 这是一个庞大的共享内存结构。
SGA分为不同的池(pool):
[b](1)Java池[/b](java pool):java池是为数据库中运行的jvm分配的一段固定大小的内存。在oracle 10中,java池可以在数据库启动并运行时在线调整大小。
[b](2)大池[/b](large pool):共享服务器连接使用大池作为会话内存,并行执行特性使用大池作为消息缓存区,另外RMAN备份可能使用大池作为磁盘IO缓冲区。大池可以在线调整大小。
[b](3)共享池[/b](shared pool):共享池包含共享游标,存储过程,状态对象,字典缓存和诸如此类的大量其他数据。在oracle10和9中,共享池都可以在线调整大小。
[b](4)流池[/b](stream pool):这是oracle流专用的一个内存池,oracle流是数据库中地一个数据共享工具,是oracle10中新增的,可以在线调整大小。
[b](5)空池[/b](NULL pool):这个池其实没有名字。这是块缓冲区,重做日志缓冲区和固定SGA区专用的内存。
[b]3.2.1 共享池[/b]
共享池是SGA中最重要的内存段之一,特别是对于性能和可扩展性来说。共享池如果太小,会严重影响性能,甚至导致系统看上去像终止了一样。如果共享池太大,也会有同样的效果。共享池使用不当会导致灾难性的后果。
共享池就是oracle缓存一些“程序”数据的地方。[color=red]在解析一个查询时[/color],解析得到的表示(representation)就缓存在那里。在完成解析整个查询的任务之前,oracle会搜索共享池,看看这个工作是否已经完成。你运行的pl/sql代码不仅在这里缓存,还会在这里共享。如果有1000个会话都在执行同样的代码,那么只会加载这个代码的一个副本,并由所有会话共享。Oracle把系统参数存储在共享池中。数据字典缓存(关于数据库对象的已缓存信息)也存储在这里。
共享池的特点就是有大量小的内存块,一般为4KB或更小。我们的目标是使用小块的内存来避免碎片问题,共享池的内存根据LRU的原则来管理。
[color=red][b]如果真的想破坏oracle的共享池,最容易的办法是不使用绑定变量。[/b][/color]如果不使用绑定变量,可能会让系统陷于瘫痪,有两个原因:
(1) 系统要花大量cpu时间解析查询。
(2) 系统使用大量资源来管理共享池中的对象,因为从来不重用查询。
如果提交到oracle的每个查询都是具有硬编码值的唯一查询,则共享池的概念就一点用都没有。设计共享池是为了反复使用查询计划。[color=red]如果每个查询都是全新的,那么缓存只会增加开销。共享池反而会损害性能。[/color]对于这个问题,[color=blue]真正的解决方案只有一个,就是使用共享sql,也就是重用查询。[/color]
与管理PGA内存一样,从oracle10开始,管理SGA内存也有两种方法:手动管理和自动管理。手动管理需要设置所有必要的池和缓存参数,自动管理只需设置少数几个内存参数和一个SGA_TARGET参数。通过设置SGA_TARGET参数,实例就能设置各个SGA组件的大小以及调整他们的大小。
从oracle 11g 开始,oracle数据库还提供了自动内存管理,相当于可以一站式完成所有内存设置。在oracle 11g中,DBA现在只需设置一个内存参数,memory_target,这个参数表示SGA和PGA分配能达到的总内存量。