学习《Oracle 9i10g编程艺术》的笔记 (八) 内存结构

来源:互联网 发布:淘宝首饰店推荐 编辑:程序博客网 时间:2024/05/17 09:24

 Oracle  3 个主要的内存结构:
系统全局区(System Global Area,SGA):这是一个很大的共享内存段,几乎所有Oracle
进程都要访问这个区中的某一点。
进程全局区(Process Global Area,PGA):这是一个进程或线程专用的内存,其他进程/
线程不能访问。
用户全局区(User Global Area,UGA):这个内存区与特定的会话相关联。它可能在SGA
中分配,也可能在PGA 中分配,这取决于是用共享服务器还是用专用服务器来连接数据库。如
果使用共享服务器,UGA 就在SGA 中分配;如果使用专用服务器,UGA 就会在PGA(即进程内存
区)中。

 

 

每个Oracle 实例都有一个很大的内存结构,称为系统全局区(System Global Area,SGA)。这是一
个庞大的共享内存结构,每个Oracle 进程都会访问其中的某一点。SGA 的大小不一,在小的测试系统上只
有几MB,在中到大型系统上可能有几百MB,对于非常大的系统,甚至多达几GB。

 

在Oracle 自身内,则完全可以看到SGA,而不论平台是什么。为此,只需使用另一个神奇的V$视图,
名为V$SGASTAT。它可能如下所示(注意,这个代码并非来自前面的系统;而是来自一个已经适当地配置
了相应特性的系统,从而可以查看所有可用的池):

ops$tkyte@ORA10G> compute sum of bytes on pool
ops$tkyte@ORA10G> break on pool skip 1
ops$tkyte@ORA10G> select pool, name, bytes
2 from v$sgastat
3 order by pool, name;

 

SGA 分为不同的池(pool):
Java 池(Java pool): Java 池是为数据库中运行的JVM 分配的一段固定大小的内存。在
Oracle10g 中,Java 池可以在数据库启动并运行时在线调整大小。
大池(Large pool):共享服务器连接使用大池作为会话内存,并行执行特性使用大池作为
消息缓冲区,另外RMAN 备份可能使用大池作为磁盘I/O 缓冲区。在Oracle 10g 和9i Release 2
中,大池都可以在线调整大小。
共享池(Shared pool):共享池包含共享游标( cursor)、存储过程、状态对象、字典缓存
和诸如此类的大量其他数据。在Oracle 10g 和9i 中,共享池都可以在线调整大小。
流池(Stream pool):这是Oracle 流(Stream)专用的一个内存池,Oracle 流是数据库中
的一个数据共享工具。这个工具是Oracle 10g 中新增的,可以在线调整大小。如果未配置流池,
但是使用了流功能,Oracle 会使用共享池中至多10%的空间作为流内存。
“空”池(“Null”pool):这个池其实没有名字。这是块缓冲区(缓存的数据库块)、重做
日志缓冲区和“固定SGA”区专用的内存。

对SGA 整体大小影响最大的参数如下:
JAVA_POOL_SIZE:控制Java 池的大小。
SHARED_POOL_SIZE:在某种程度上控制共享池的大小。
LARGE_POOL_SIZE:控制大池的大小。
DB_*_CACHE_SIZE:共有8 个CACHE_SIZE 参数,控制各个可用的缓冲区缓存的大小。
LOG_BUFFER:在某种程度上控制重做缓冲区的大小。
SGA_TARGET:Oracle 10g 及以上版本中用于自动SGA 内存管理。
SGA_MAX_SIZE:用于控制数据库启动并运行时SGA 可以达到的最大大小。

 

不论是使用自动内存管理还是手动内存管理,都会发现各个池的内存以一种称为颗粒(granule,也
称区组)的单位来分配。
一个颗粒是大小为4 MB、8 MB 或16 MB 的内存区。颗粒是最小的分配单位,所以
如果想要一个5 MB 的Java 池,而且颗粒大小为4 MB,Oracle 实际上会为这个Java 池分配8 MB(在4 的
倍数中,8 是大于或等于5 的最小的数)。颗粒的大小由SGA 的大小确定(听上去好像又转回来了,因为SGA
的大小取决于颗粒的大小)。通过查询V$SGA_DYNAMIC_ COMPONENTS,可以查看各个池所用的颗粒大小。实
际上,还可以使用这个视图来查看SGA 的总大小如何影响颗粒的大小:
sys@ORA10G> show parameter sga_target
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
在这个例子中,我使用了自动SGA 内存管理,并通过一个参数(SGA_TARGET)来控制SGA 的大小。SGA
小于1 GB 时,颗粒为4 MB。当SGA 大小增加到超过阈值1 GB 时(对于不同的操作系统,甚至对于不同的
版本,这个阈值可能稍有变化),可以看到颗粒大小有所增加:
sga_target big integer 576M
sys@ORA10G> select component, granule_size from v$sga_dynamic_components;
COMPONENT GRANULE_SIZE
------------------------- ------------
shared pool 4194304
large pool 4194304
java pool 4194304
streams pool 4194304
DEFAULT buffer cache 4194304
KEEP buffer cache 4194304
RECYCLE buffer cache 4194304
DEFAULT 2K buffer cache 4194304
DEFAULT 4K buffer cache 4194304
DEFAULT 8K buffer cache 4194304
DEFAULT 16K buffer cache 4194304
DEFAULT 32K buffer cache 4194304
OSM Buffer Cache 4194304
13 rows selected.
sys@ORA10G> alter system set sga_target = 1512m scope=spfile;
System altered.
sys@ORA10G> startup force
ORACLE instance started.
Total System Global Area 1593835520 bytes
Fixed Size 779316 bytes
Variable Size 401611724 bytes
Database Buffers 1191182336 bytes
Redo Buffers 262144 bytes
Database mounted.
Database opened.
sys@ORA10G> select component, granule_size from v$sga_dynamic_components;
COMPONENT GRANULE_SIZE
------------------------- ------------
shared pool 16777216
large pool 16777216
java pool 16777216
streams pool 16777216
DEFAULT buffer cache 16777216
KEEP buffer cache 16777216
RECYCLE buffer cache 16777216
DEFAULT 2K buffer cache 16777216
DEFAULT 4K buffer cache 16777216
DEFAULT 8K buffer cache 16777216
DEFAULT 16K buffer cache 16777216
DEFAULT 32K buffer cache 16777216
OSM Buffer Cache 16777216
13 rows selected.
可以看到,SGA 为1.5 GB 时,会以16 MB 的颗粒为池分配空间,所以池大小都将是16 MB 的某个倍
数。