是不是很难准确地分配 配到最需要的地方去成为可
|
不同的池所需的内存数?自动共 能。
|
享内存管理特性使得自动将内存分
|
无论您是一个刚入门的 的错误:
|
DBA 还是一个经验丰富的 DBA
|
,您肯定至少看到过一次类似以下
|
ORA-04031:unable to
|
allocate 2216 bytes of share
|
d memory ("shared pool"... ...
|
ORA-04031:unable to allocate XXX
|
X bytes of shared memory
|
("large pool","unknown object","
|
session heap","frame")
|
ORA-04031:unable to
|
allocate bytes of shared mem
|
ory ("shared pool",
|
"unknown object","joxlod:init h"
|
, "JOX:ioc_allocate_pal")
|
第一种错误的原因很明 原因可能不是池本身的大小 的一个主题;但目前让我们 池的空间不足。
|
显:分配给共享池的内存不足以 ,而是未使用绑定变量导致的过 把重点放在手头的问题上。)其
|
满足用户请求。(在某些情况下, 多分析造成的碎片,这是我很喜欢 它的错误分别来自大型池和 Java
|
您需要解决这些错误情 问题是如何在 Oracle 例程
|
况,而不作任何与应用程序相关 所需的所有池之间划分可用的内
|
的修改。那么有哪些方案可选呢? 存。
|
正如您所了解的,一个 冲高速缓存、共享池、Java 占据了固定的内存数;它们
|
Oracle 例程的系统全局区域 ( 池、大型池和重做日志缓冲) 的大小由 DBA 在初始化参数文
|
SGA) 包含几个内存区域(包括缓 。这些池在操作系统的内存空间中 件中指定。
|
这四个池(数据库块缓冲高速缓存、 的空间。(与其它区域相比,重做日志缓 )作为 DBA,您必须确保它们各自的内存
|
共享池、Java 池和大型池)几乎占据了 SGA 中所有 冲没有占据多少空间,对我们这里的讨论无关紧要。 分配是充足的。
|
假定您决定了这些池的值分别是 2GB 数据库例程规定池的大小。
|
、1GB、1GB 和 1GB。您将设置以下初始化参数来为
|
| 现在,仔细看一下这些参数。坦白讲,这些值是否准确? |
我相信您一定会有疑虑 赖于数据库内部的处理,而
|
。在实际中,没有人能够为这些 处理的特性随时在变化。
|
池指定确切的内存数 — 它们太依
|
下面是一个示例场景。 速缓存分配的专用内存比为 用户放开了一些非常大的全 线修改内存分配的功能,但 些内存:
|
假定您有一个典型的、大部分属 纯 OLTP 数据库(现在已经很少 表扫描,以创建当天的结束报表 由于提供的总物理内存有限,您
|
于 OLTP 的数据库,并且为缓冲高 见了)分配的要少。有一天,您的 。Oracle9i 数据库为您提供了在 决定从大型池和 Java 池中取出一
|
alter system set db_cache_size =
|
3g scope=memory;
|
alter system set lar
|
ge_pool_size = 512m scope=me
|
mory;
|
alter system set jav
|
a_pool_size = 512m scope=mem
|
ory;
|
这个解决方案能够很好地工作一段时 开始了,大型池将立即出现内存不足。同 池,以挽救这种局面。
|
间,但是接着夜间的 RMAN 作业(它们使用大型池) 样,您从数据库高速缓存中取出一些内存来补充大型
|
RMAN 作业完成,然后 池相关的错误。因此,您( 求:
|
启动一个广泛使用 Java 的批处 再次)重新分配池,以满足 Jav
|
理程序,接着您开始看到与 Java a 池和数据库高速缓存上的内存需
|
alter system set db_cache_size =
|
2G scope=memory;
|
alter system set lar
|
ge_pool_size = 512M scope=me
|
mory;
|
alter system set jav
|
a_pool_size = 1.5G scope=mem
|
ory;
|
| 第二天早上,OLTP 作业恢复在线,这个循环又完全重复! |
解决这种恶性循环的一种替代方法是 分配的总的 SGA 可能超出可用的内存 — 和分页的风险。人工重新分配的方法(虽
|
永久设置每个池的最大需求。不过,这么做的话,您 从而在为每个池分配的内存数不足时,将增加交换 然不实际)目前看起来很不错。
|
另一种替代方法是将值 性能将受到影响。
|
设为可接受的最小值。不过,当
|
需求增长且内存不能完全满足时,
|
注意在所有这些示例中,分配给 SGA 的需求进行修改。如果 RDBMS 将自动探 是很好吗?
|
的总内存保持不变,而池之间的内存分配根据即时 测来自用户的需求并相应地重新分布内存分配,那不
|
Oracle 数据库 10g 中的自动共享内 SGA 的总大小,然后设置一个名称为 SGA SGA 内部的各个池将根据工作负载动态地 参数的一个非零值。
|
存管理特性正好能够实现这一目的。您可以决定 _TARGET 的参数,这个参数决定 SGA 的总大小。 进行配置。实现自动内存分配仅仅需要 SGA_TARGET
|
让我们看看该特性是如 了多少内存来估计这个值。
|
何工作的。首先,确定 SGA 的
|
总大小。您可以通过确定现在分配
|
| SQL> select sum(value)/1024/1024 from v$sga; |
此时 SGA 的当前总大 执行语句:
|
小近似为 500MB,并且这个值将
|
变为 SGA_TARGET 的值。接下来,
|
alter system set sga_target = 50
|
0M scope=both;
|
这种方法不需要为各个池设置不同值 部删除它们。
|
;因而,您将需要在参数文件中使它们的值为零或全
|
这个人工过程还可以通 "Administration" 选项卡 显示标记为 "Enable" 的按 共享内存管理特性。企业管
|
过 EntERPrise Manager 10g 实 ,然后选择 "Memory Parameter 钮,以及所有人工配置的池的值 理器将完成剩下的工作。
|
施。从数据库主页中,选择 s"。对于人工配置的内存参数,将 。单击 "Enable" 按钮,启用自动
|
| 在配置了自动内存分配之后,您可以利用以下命令检查它们的大小: |
| SQL> select current_size from v$buffer_pool; |
| SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool; |
正如您所看到的,所有 缓冲高速缓存大小是 340MB 总的大小为 (340+4+4+148=
|
的池都从 500MB 的总目标大小 ,Java 池是 4MB,大型池是 4M ) 496MB,近似与 500MB 的目标
|
中自动进行分配。(参见图 1。) B,共享池是 148MB。它们合起来 SGA 的大小相同。
|
现在假定提供给 Oracl SGA 的大小。我们可以通过
|
e 的主机内存从 500MB 减少为 减小目标 SGA 大小来反映这种
|
300MB,这意味着我们必须减少总 变化。
|
alter system set sga
|
_target = 300M scope=both;
|
| SQL> select current_size from v$buffer_pool; |
| SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool; |
占用的总大小是 240+4 SGA_TARGET 改变时,如何
|
+4+44 = 296MB,接近于目标的 自动重新分配池。
|
300MB。注意如图 2 所示,当
|
|
图 2:在将 SGA 大小减少到 300MB 之后重新分配池 |
这些池的大小是动态的。池将根据工 个池的扩展。这种扩展或缩小自动发生, 们暂时返回到那个场景,假定在初始分配 大型池将从 4MB 扩展到 40MB,以容纳需 库块缓冲将缩小,如图 3 所示。
|
作负载扩展,以容纳需求的增长,或缩小以容纳另一 无需 DBA 的干预,这与本文开头的示例不同。让我 后,RMAN 作业启动,指示需要一个更大的大型池, 求。这个额外的 36MB 将从数据库缓冲中划出,数据
|
池的大小变化基于系统 根据需求的增长自动调整。 此不存在使内存需求的增长 SGA_TARGET 增加至绝对最
|
上的工作负载,因此不需要为最 此外,SGA 的总大小始终在由 S 比例失调(这将导致分页和交换 大值,这个绝对最大值是通过调
|
坏的情况调整池的大小 — 它们将 GA_TARGET 指定的最大值之内,因 )的风险。您可以动态地将 整参数 SGA_MAX_SIZE 指定的。
|
SGA 中的一些池不受动 非标准块大小的缓冲池,以 个块大小为 8K,而您想要 。它们的大小将保持不变; KEEP 池和 RECYCLE 池时, 管工作负载如何,在参数 l 定义一种新的池:流池 (st 受自动内存调整的影响。)
|
态大小调整的影响,但是必须显 及 KEEP 池或 RECYCLE 池的非 配置 2K、4K、16K 和 32K 块大 它们将不会根据负载缩小或扩展 您应当考虑这个因素。此外,日 og_buffer 中设定的值是不变的 ream pool),它用参数 streams
|
式指定这些池。其中值得注意的是 默认块大小。如果您的数据库有一 小的池,那么您必须手动设置它们 。当使用多种大小的缓冲池、 志缓冲不受内存调整的影响 — 不 。( 在 10g 中,还可以在 SGA 中 _pool_size 进行设置。该池也不
|
这就产生了一个有趣的问题。如果您 池,那么该怎么办?
|
需要一个非默认块大小的池,而且想自动管理其它的
|
如果您指定了这些非自 的总大小将从 SGA_TARGET 变。例如,假设值看起来像
|
动调整的参数中的任意一个(如 值中减去,以计算自动调整的参 这样:
|
db_2k_cache_size),那么它们 数值,以使 SGA 的总大小保持不
|
其余的池参数未设置。50MB 的 2KB (db_cache_size)、共享池、Java 池和大 自动调整的参数(如 2KB 块大小池)— 调整的部分将重新调整。例如,将 db_2k 动调整的参数剩余 400MB。因此,如图 4 默认缓冲池)自动缩小,以将它们的总大
|
缓冲池为自动调整的池(如默认块大小缓冲池 型池)保留了 450MB。当以一种方法动态地调整不可 —这种方法将影响到可自动调整部分的大小,可自动 _cache_size 的值从 50MB 提高到 100MB 只为可自 所示,可调整的池(如共享池、大型池、Java 池和 小从 450MB 减少到 400MB。
|
但如果您有足够的可用 的话,您可以通过不指定参 过使用 ALTER SYSTEM 动态 0 时,池的当前值被自动设
|
内存,或者上述风险可能不是那 数文件中的参数 SGA_TARGET、 地将其修改为 0 来关闭自动大 为它们的参数。
|
么明显,那应该怎么办?如果这样 通过在文件中将其设为 0,或者通 小调整。当 SGA_TARGET 被设为
|
您还可以使用 Enterpr "Memory Parameters",这
|
ise Manager 10g 来处理这些参 将显示一个类似于图 5 中的屏
|
数。从数据库主页中单击超链接 幕。
|
|
图 5:在 Enterprise Manager 中调整自动共享内存管理 |
注意红圈中的项目:数据库在 Autom 小为 564MB — 与在参数 SGA_TARGET 中 Apply 按钮接受这些值;可调整的参数将
|
atic Shared Memory Management 模式下运行,总大 指定的值相同。您可以在此修改它,然后单击 自动调整。
|
| 假定您将 SGA_TARGET 设为 600MB,并且各个池已自动分配: |
看看上述值,您可能推 需要增加。因此,您可能想 16MB。您可以通过在参数文 目的(如下所示)。
|
断 4MB 的 Java 池和大型池可 确保这些池至少在最初时具有更 件中显式地指定这些池的值或动
|
能有点不足;这个值在运行时无疑 高的值,比如说,分别为 8MB 和 态使用 ALTER SYSTEM 来实现这一
|
| alter system set large_pool_size = 16M; |
| alter system set java_pool_size = 8M; |
| SQL> select pool, sum(bytes)/1024/1024 Mbytes from v$sgastat group by pool; |
| SQL> select current_size from v$buffer_pool; |
注意 Java 池和大型池是如何分别被 SGA 保持在 600MB 以下,缓冲池已从 40 存管理控制 — 它们的大小将根据需求缩 限;它们将永远不会缩小到低于这个界限
|
重新配置为 8MB 和 16MB,并且注意为了使总的 4MB 减少为 388MB。当然,这些池仍然由自动共享内 小或扩展。您显式指定的值为池的大小设定了一个下 。
|
Oracle SGA 中的各种池的内存需求 。Oracle 数据库 10g 中的自动共享内存 地方同时施加一个指定的最大值以防止分 更有效的内存管理还带来了更少的内存需
|
不是静态的 — 相反,它们根据系统上的需求而变化 管理特性通过动态地将资源重新分配到最需要它们的 页和交换,使得 DBA 能够更有效地管理系统内存。 求,这使得更精简的硬件更加可行。
| |