oracle数据库:内存结构_笔记10
2.多个块大小
从Oracle Database 9i开始,同一个数据库中可以有多个不同的数据库块大小。此前,一个数据库中的所有块大小都相同,要想使用一个不同的块大小,必须重新建立整个数据库。现在就不同了,你可以有一个“默认的”块大小(最初创建数据库时使用的块大小,即SYSTEM和所有TEMPORARY表空间的块大小),以及最多4个其他的块大小。每个不同的块大小都必须有其自己的缓冲区缓存。默认池、保持池和回收池只缓存具有默认大小的块。为了在数据库中使用非默认的块大小,需要配置一个缓冲区池来保存这些块。
默认块大小是8KB。想创建一个块大小为16KB的表空间:
sys@ORCL>create tablespace ts_16k
2 datafile '/tmp/ts_16k.dbf'
3 size 5m
4 blocksize 16k;
create tablespace ts_16k
*
ERROR at line 1:
ORA-29339: tablespace block size 16384 does not match configured block sizes
sys@ORCL>show parameter 16k
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
db_16k_cache_size big integer
0
现在,由于还没有配置一个16KB的缓存,所以无法创建这样一个表空间。要解决这个问题,可以在以下方法中选择一种。可以设置DB_16K_CACHE_SIZE参数,并重启数据库。也可以缩小另外的某个SGA组件,从而在现有的SGA中腾出空间来建立一个16KB的缓存。或者,如果SGA_MAX_SIZE参数大于当前的SGA大小,还可以直接分配一个16KB的缓存。
注意:从Oracle Database 9i开始,即使数据库已经启动并且正在运行,也能重新设置各个SGA组件的大小。如果想拥有这个能力,能够“扩大”SGA的大小(超过初始分配的大小),就必须把SGA_MAX_SIZE参数设置为大于已分配SGA的某个值。例如,如果启动之后,你的SGA大小为128MB,你想再为缓冲区缓存增加另外的64MB,就必须把SGA_MAX_SIZE设置为192MB或更大,以便扩展。
sys@ORCL>alter system set sga_target=256m scope=spfile;
System altered.
sys@ORCL>alter system set db_16k_cache_size=16m scope=spfile;
System altered.
sys@ORCL>connect / as sysdba
Connected.
sys@ORCL>startup force
ORACLE instance started.
Total System Global Area 267227136 bytes
Fixed Size 2227504 bytes
Variable Size 104858320 bytes
Database Buffers 155189248 bytes
Redo Buffers 4952064 bytes
Database mounted.
Database opened.
sys@ORCL>show parameter 16k
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
db_16k_cache_size big integer
16M
一般来讲,默认池、保持池和回收池对于块缓冲区缓存精细调优来说应该已经足够了,多个块大小主要用于从一个数据库向另一个数据库传输数据,可能在混合的报告/事务系统中也会用到这种机制。
4.2.4共享池
共享池是SGA中最重要的内存段之一,特别是对于性能和可扩展性来说。共享池如果太小,会严重影响性能,甚至导致系统看上去好像中止了一样。如果共享池太大,也会有同样的效果。
那么,到底什么是共享池?共享池就是Oracle缓存一些"程序"数据的地方。在解析一个查询时,解析得到的表示就缓存在那里。在完成解析整个查询的任务之前,Oracle会搜索共享池,看看这个工作是否已经完成。你运行的PL/SQL代码就在共享池中缓存,所以下一次运行时,Oracle不会再次从磁盘重新读取。PL/SQL代码不仅在这里缓存,还会在这里共享。如果有1000个会话都在执行同样的代码,那么只会加载这个代码的一个副本,并由所有会话共享。Oracle把系统参数存储在共享池中。数据字典缓存也存储在这里。
共享池的特点是有大量小的内存块,一般为4KB或更小。要记住,4KB并不是一个硬性限制,可能有的内存分配会超过这个大小,但是一般来讲,我们的目标是使用小块的内存来避免碎片问题。如果分配的内存块大小显著不同,就可能出现碎片问题。共享池中的内存根据LRU的原则来管理。在这方面,它类似于缓冲区缓存,如果你不用某个对象,它就会丢掉。为此提供了一个包,名叫DBMS_SHARED_POOL,这个包可用于改变这种行为,强制性地“钉住”共享池中的对象。可以使用这个过程在数据库启动时加载频繁使用的过程和包,并使它们不至于老化。不过,通常如果过一段时间共享池中的一段内存没有得到重用,它就会老化。甚至PL/SQL代码(可能相当大)也以一种分页机制来管理,这样当你执行一个非常大的包中的代码时,只有所需的代码会加载到共享池的小块中。如果你很长时间都没有用它,而且共享池已经填满,需要为其他对象留出空间,它就会老化。
如果真的想破坏Oracle的共享池,最容易的办法是不使用绑定变量。如果不使用绑定变量,可能会让系统陷于瘫痪,这有两个原因。
.系统要花大量CPU时间解析查询
.系统使用大量资源来管理共享池中的对象,因为从来不重用查询。
关于共享池和参数SHARED_POOL_SIZE还有一点要说明。在Oracle Database 9i及以前的版本中,查询结果与SHARED_POOL_SIZE参数之间没有直接的关系,只能说SUM(BYTES) FROM V$SGASTAT总是大于SHARED_POOL_SIZE。
不过,在Oracle Database 10g及以上版本中,应该能看到二者之间存在一对一的对应关系。
4.2.5大池
大池(large pool)并不是因为它是一个"大"结构才这样取名。之所以称之为大池,是因为它用于大块内存的分配,共享池不会处理这么大的内存块。
大块内存分配是得到一块内存后加以使用,然后就到此为止,没有必要缓存这个内存。
Oracle需要的应该是像为块缓冲区缓存实现的回收和保持缓冲区池之类的组件。这正是现在的大池和共享池。大池就是一个回收型的内存空间,共享池则更像是保持缓冲区池。如果对象可能会被频繁地使用,就将其缓存起来。
大池中分配的内存在堆上管理,这是C语言通过malloc()和free()管理内存很相似。一旦“释放”了一块内存,它就能由其他进程使用。在共享池中,实际上没有释放内存块的概念。你只是分配内存,然后使用,再停止使用而已。过一段时间,如果需要重用那个内存,Oracle会让你的内存块老化。如果只使用共享池,问题在于:一种大小不一定全局适用。
大池专门用于以下情况:
.共享服务器连接。用于在SGA中分配UGA区
.语句的并行执行。允许分配进程间的消息缓冲区,这些缓冲区用于协调并行查询服务器。
.备份。在某些情况下用于RMAN磁盘I/O缓冲区。
4.2.6Java池
Java池(Java pool)是Oracle 8.1.5版本中增加的,目的是支持在数据库中运行Java。如果用Java编写一个存储过程,Oracle会在处理代码时使用Java池的内存。参数JAVA_POOL_SIZE用于确定为会话特有的所有Java代码和数据分配多大的Java池内存量。
Java池有多种用法,这取决于Oracle服务器运行的模式。如果采用专用服务器模式,Java池包括每个Java类的共享部分,由每个会话使用。这些实际上是只读部分(执行向量、方法等),每个类的共享部分大约4-8KB。
因此,采用专用服务器模式时,Java池所需的总内存相当少,可以根据要用的Java类的个数来确定。应该知道,如果采用专用服务器模式,每个会话的状态不会存储在SGA中,因为这个信息要存储在UGA中。使用共享服务器连接来连接Oracle时,Java池包括以下部分。
.每个Java类的共享部分
.UGA中用于各会话状态的部分,这是从SGA中的JAVA_POOL分配的。UGA中余下的部分会正常地在共享池中分配,或者如果配置了大池,就会在大池中分配。
Oracle Database 9i及以前版中Java池的总大小是固定的。在Oracle Database 10g及以上版本中,这个参数可以修改,Java池可以随着时间的推移而扩大和收缩,而无需重启数据库。
http://www.52ij.com/jishu/5170.htmloracle数据库:内存结构_笔记9
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5171.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
