在
32
位的操作系统上,
Oracle
系统理论上可以使用的内存上限是
4G
,即
2^32
字节,任何多出的部分,
Oracle
均不会使用;在
64
位的操作系统上,
Oracle
系统可以使用的内存理论上是
2^64
字节,在可以预见的未来的应用,这几乎和没有上限限制是一样的。因此在购买小型机服务器硬件设备时(一般都会自带操作系统)要考虑到使用的是多少位的操作系统,否则即使内存配得再多,也不会给性能带来提高。在使用
32
位的操作系统时,如果该服务器设备专门用作数据库服务器(即不在其上安装其它诸如应用服务器等软件)时,配置
6G
的内存应该是比较恰当的,除
4G
被
Oracle
使用外,
2G
内存用来运行操作系统本身的进程。
注意
1
:如果是
UNIX
或
Linux32
位操作系统,还要设置操作系统级的参数
shmmax
。
SGA
的空间可以大于
shmmax
,具体情况请参考
Oracle
安装手册以及操作系统手册
;
注意
2:
本小节(下面)中所列的操作可能需要一定的权限,在实际工作中,如果发现相关权限的问题,请及时给相关用户授权或以一个权限更大的用户的身份进行操作。
Oracle
总体内存结构如下图所示:
从上图中,
Oracle
的内存结构主要有
SGA
和
PGA
组成,其中
UGA
的一部分为
SGA
所管理,而另一部分则为
PGA
所管理,
CGA
则不关
UGA
被
SGA
管理还是被
PGA
所管理,它总是处于
UGA
之内。
或许由于
SGA
太重要了,以致大家忽略了
PGA
、
UGA
和
CGA
的存在。比如很多人都搞不清楚
PGA
和
UGA
两者之间的区别,实际上两者之间的区别跟一个进程和一个会话之间的区别是类似的。尽管说进程和会话之间一般都是一对一的关系,但实际上比这个更复杂。一个很明显的情况是
MTS
配置,会话往往会比进程多得多。在这种配置下,每一个进程会有一个
PGA
,每一个会话会有一个
UGA
。
PGA
所包含的信息跟会话是无任何关联的,而
UGA
包含的信息是以特定的会话为基础的。现在我们对
PGA
、
UGA
和
CGA
做以下介绍:
进程全局区
(PGA)
即可以理解为
Process Global Area
,也可以理解为
Program Global Area
。它的内存段是在进程私有区
(Process Private Memory)
而不是在共享区
(Shared Memory)
。它是个全局区意味着它包含了所有代码有可能进入的全局变量和数据结构,但是它是不被所有进程共享的。每个
Oracle
的服务器进程都包含有属于自己的
PGA
,它只包含了本进程的相关特定信息。
PGA
中的结构不需要由
latches
来保护,因为其它的进程是不能进入到这里面来访问的。
PGA
包含的是有关进程正在使用的操作系统资源信息以及进程的状态信息,而其它的进程所使用的
Oracle
的共享资源是在
SGA
中。
PGA
是私有的而不是共享的,这个机制是有必要的,因为当进程死掉后可以把这些资源清除和释放掉。
PGA
包含两个主要区域:
Fixed PGA
和
Variable PGA
或称为
PGA Heap
。
Fixed PGA
的作用跟
Fixed SGA
是类似的,都包含原子变量
(
不可分的
)
,小的数据结构和指向
Variable PGA
的指针。
Variable PGA
是一个堆。它的
Chunks
可以从
Fixed Table X$KSMPP
查看得到,这个表的结构跟前面有提到的
X$KSMSP
是相同的。
PGA HEAP
包含了一些有关
Fixed Table
的永久性内存,它跟某些参数的设置有依赖关系。这些参数包含
DB_FILES
,
LOG_FILES
,
CONTROL_FILES
。
UGA(User Global Area)
包含的是特定会话的信息,有如下一些
:
-
所打开游标的持续和运行时间内的区域
-
包的状态信息,特定的变量
-
Java
会话状态
-
可以用的
ROLES
-
被
ENABLE
的跟踪事件
-
起作用的
NLS
参数设置
-
打开的
DBLINK
-
会话的入口控制
跟
PGA
一样,
UGA
也由两区组成:
Fixed UGA
和
Variable UGA
,也称为
UGA HEAP
。
Fixed UGA
包含了大约
70
个原子变量,小的数据结构和指向
Variable UGA
的指针。
UGA HEAP
中的
Chunks
可以从它们自己的会话中通过查看表
X$KSMUP
获得相关信息,这个表的结构跟
X$KSMSP
是一样的。
UGA HEAP
包含了一些有关
fixed tables
的永久性内存段,跟一些参数的设置有依赖关系。这些参数有
OPEN_CURSORS
,
OPEN_LINKS
和
MAX_ENABLE_ROLES
。
调用全局区
(CGA)
跟其它的全局区不同,
Call Global Area
是短暂性存在的。它只有在调用数据期间存在,一般是在对实例的最低级别的调用时才需要
CGA
,如下:
-
分析一个
SQL
语句
-
执行一个
SQL
语句
-
取出一个
SELECT
语句的输出
一个单独的
CGA
在递归调用时是需要的。在
SQL
语句的分析过程中,对数据字典信息的递归调用是需要的,因为要对
SQL
语句进行语法分析,还有在语句的优化期间要计算执行计划。执行
PL/SQL
块时在处理
SQL
语句的执行时也是需要递归调用的,在
DML
语句的执行时要处理触发器执行也是需要递归调用的。不管
UGA
是放在
PGA
中还是在
SGA
中,
CGA
都是
PGA
的一个子堆
(Subheap)
。这个事实的一个重要推论是在一个调用的期间会话必须是一个进程。对于在一个
MTS
的
Oracle
数据库进程应用开发时关于这一点的理解是很重要的。如果相应的调用较多,就得增加
processes
的数量以适应调用的增加。没有
CGA
中的数据结构,
CALLS
是没法工作的。而实际上跟一次
CALL
相关的数据结构一般都是放在
UGA
中,如
SQL AREA
,
PL/SQL AREA
和
SORT AREA
它们都必须在
UGA
中,因为它们要在各
CALLS
之间要一直存在并且可用。而
CGA
中所包含的数据结构是要在一次
CALL
结束后能够释放的。例如
CGA
包含了关于递归调用的信息,直接
I/O BUFFER
等还有其它的一些临时性的数据结构。
Java Call Memory
也是在
CGA
中。这一段内存比
Oracle
的其它内存段管理得更密集。它分成三个
Space
:
Stack Space
,
New Space
,
Old Space
。在
New Space
和
Old Space
中不再被参考使用的
Chunks
,根据它们在使用期间的长度及
SIZE
的不同,在调用的执行过程中将被当成不用的
Chunks
收集起来。
New Space Chunks
很多次的不用的
Chunks
的反复收集过程中没有被收集的
Chunks
将会被放到
Old Space Chunks
中。这是在
Oracle
内存管理中唯一的一个废物收集
(garbage collection)
,其它的
Oracle
内存段都是释放
Dead Chunks
。
正象前面提到的,
Oracle
数据库系统和信能相关最主要的就是
SGA
(
System Global Area
)了,它由
SHARED POOL
、
DATABASE BUFFER CACHE
和
Redo LOG BUFFER
三部分组成,
其中又以
SHARED POOL
、
DATABASE BUFFER CACHE
对于日常碰到的系统性能调整最为重要。现在我们假定
Oracle
运行在
32
位的操作系统上,并且系统有足够多的内存可以分配,那么我们可以修改
sga_max_size
,使其等于
4G
的
60%
(因为
PGA
也需要使用内存,并且它并未包含在
SGA
中),即:
sga_max_size=2458M
①
调整
SHARED POOL
。在
SHARED POOL
中,又包含两个
CACHE
,即
Library Cache
和
Data Dictionary Cache
。
Library Cache
用于存放共享
SQL
语句和
PL/SQL
语句,采用
LRU
(
Least Recently Used
)算法进行管理,
Oracle
可以用已经
cache
在其中的
SQL
语句,而不需要
re-parsing
,我们可以通过下面的
SQL
语句来查询
Library Cache
的命中率(
Hit Ratio
):
SQL> select GETHITRATIO
from v$librarycache
where NAMESAPCE
=
'SQL AREA';
如果得到的结果小于
90%
,那么说明命中率不高,需要增大
Library Cache
了。如果想要将某个
package
放于
Library Cache
中,请使用以下命令:
SQL> execute dbms_shared_pool.keep('package_name');
要将某个
package
从
Library Cache
移出,请使用以下命令:
SQL> execute dbms_shared_pool.unkeep('package_name');
Data Dictionary Cache
主要用来保持字典对象的相关信息。可以查看视图
v$rowcache
,该视图由以下各列组成:
列名 | 说明 |
PARAMETERS | 数据字典项的分类 |
GETS | 对于此类字典项的信息获取次数 |
GETMISSES | 对于此类字典项的信息获取失败次数 |
如果
GETMISSES/ GETS * 100% > 15%
,那么就要考虑增大
Data Dictionary Cache
了。
很重要地,
Library Cache
和
Data Dictionary Cache
不能单独进行调整,要对它们进行调整,只能通过调整
SHARED_POOL_SIZE
来进行(
Oracle
会自动去分配
Library Cache
和
Data Dictionary Cache
的大小,如何分配这个过程不被人控制)。比如,如果想增加
Library Cache
,那么请增加
SHARED_POOL_SIZE
。下面是分配
SHARED POOL
大小的经验公式:
SHARED_POOL_SIZE = sga_max_size * 40%
在前面我们已经得出
sga_max_size
=
2458M
了,那么按照上面这个公式,
SHARED_POOL_SIZE = 2458 * 40%
=
983M
②
调整
DATABASE BUFFER CACHE
。
BUFFER CACHE
也是
SGA
的一部分,它主要保存可以被所有用户共享的数据块。用下面的
SQL
语句来检查
BUFFER CACHE
的命中率:
SQL> select 1 – (phys.value/(cur.value + con.value)) "CACHE HIT RATIO"
from v$sysstat cur, v$sysstat con, v$sysstat phys
where cur.name = 'db block gets' and
con.name = 'consistent gets' and
phys.name = 'physical reads';
如果上面的命令的数据结果小于
80%
,那么就需要考虑增大
DATABASE BUFFER CACHE
了。在
Oracle9i
以前的版本,需要在
init<SID>.ora
中增加
DB_BLOCK_BUFFERS
的数值(因为数据库系统安装完成后
DB_BLOCK_SIZE
就固定了),
DATABASE BUFFER CACHE
的容量=
DB_BLOCK_BUFFERS * DB_BLOCK_SIZE
;在
Oracle9i
及其以后版本,则需要修改该
DB_CACHE_SIZE
。
DATABASE BUFFER CACHE
的大小计算的经验公式:
DATABASE BUFFER CACHE
的大小
= sga_max_size * 40%
在前面我们已经得出
sga_max_size
=
2458M
了,那么按照上面这个公式,
DATABASE BUFFER CACHE
的大小
= 2458 * 40%
=
983M
③
调整
PGA
大小。调整
PGA
的大小是通过设置
pga_aggregate_target
这个参数来实现的。设置此参数时,
要将
SGA
从可用于
Oracle
例程的系统内存总量中减去。然后可将剩余内存量分配给
pga_aggregate_target
。如果继续我们前面说到的情况,那么,
pga_aggregate_target
=
4G
-
2458M
=
1638M
PGA
影响到的最主要是
sort_area_size
和
hash_area_size
这两个参数,它们分别根据排序操作的多少
/
大小,
hash_join
的多少
/
大小来决定的。在江钻现有的系统中,我们发现排序操作和
jion
的操作都有很多
(
感觉上
join
操作比排序操作更多也更复杂
)
,可以考虑以下的公式:
sort_area_size = pga_aggregate_target * 30%
;
hash_area_size
=
pga_aggregate_target * 40%
;
④
其它参数调整。
db_file_multiblock_read_count
表明在涉及一个完全连续扫描的一次
I/O
操作过程中读取的块的最大数量,默认值是
8
。增加该值可以提高查询的速度,但取值到底是多大,要根据操作系统的情况来定,一般而言最好不要超过
32
(可在实际工作中反复试试,一遍确定一个最合理的值)。
java_pool_size
以字节为单位,
指定
Java
存储池的大小,
它用于存储
Java
的方法和类定义在共享内存中的表示法,
以及在调用结束时移植到
Java
会话空间的
Java
对象。如果没有使用
Oralce HTTP
之类的服务,令
java_pool_size = 64M
即可
large_pool_size
指定大型池的分配堆的大小,它可被共享服务器用作会话内存,用作并行执行的消息缓冲区以及用作
RMAN
备份和恢复的磁盘
I/O
缓冲区。一般可令
large_pool_size
=
pga_aggregate_target * 10%
。
最后,我们必须要认识到系统参数调优的过程是一个比较复杂的过程,而且根据不同应用目的的系统各种参数的给定有非常大的差别,比如有些系统数据变化不是很频繁,主要用于查询,而另外一些系统主要用来插入数据,因此放之四海而皆准的方法或者经验公式是不存在的。尽管如此,一些经过许多人积累下来的方法或者经验公式还是提供了一个很好的出发点,在此基础上,通过反复试验,应该可以得到一组相对优化的参数取值。
转载于:https://blog.51cto.com/gaoshan/282599