暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

Oracle 内存分配

原创 唯唯 2020-10-20
4473

一、Oracle预估内存:

一般情况下,在系统稳定之前,是不知道SGA和PGA该调整为多少。在这里根据经验,在调整系统的时候有个规则。SGA 通常情况下不能大于memory的50%, 另外oracle推荐得有一个分配规则,oracle推荐分配给oracle实例的内存为物理内存的80%。比如8GB的物理内存,按照Oracle的推荐,分配给Oracle实例的内存大约为6.4G(880%),对于OLAP应用来说,分配给SGA的值即sga_max_size的值大约为5.12G(880%80%),PGA的值即pga_aggregate_target的值大约为1.28G(880%*20%);对于DSS来说,分配给SGA和PGA的值各位实例内存的50%即3.2G。当然上面都是针对新的数据库来说的初始值,需要在使用过程中进行调整。
下面简单用公式表示(oracle建议):

对OLTP而言(新数据的初始参数)
SGA=memory*80%80%
PGA=memory
80%20%
对DSS而言(新数据的初始参数)
SGA=memory
80%50%
PGA=memory
80%*50%

那么在使用过程中如何确定SGA的大小呢,我们如下展开讨论:

首先来看SGA是有哪些部分组成
SQL> show user
User is “sn_qudao”

SQL> select component,current_size/1024/1024 as current_size from v$sga_dynamic_components;
COMPONENT                                                        CURRENT_SIZE


shared pool                                                               912
large pool                                                                  16
java pool                                                                    16
streams pool                                                              0
DEFAULT buffer cache                                           576
KEEP buffer cache                                                     0
RECYCLE buffer cache                                             0
DEFAULT 2K buffer cache                                        0
DEFAULT 4K buffer cache                                        0
DEFAULT 8K buffer cache                                        0
DEFAULT 16K buffer cache                                      0
DEFAULT 32K buffer cache                                      0
ASM Buffer Cache                                                       0
13 rows selected

SQL> show parameters shared_pool;
NAME                                 TYPE        VALUE


shared_pool_reserved_size            big integer 17616076
shared_pool_size                     big integer 0
SGA实际大小 = DB_CACHE_SIZE + DB_KEEP_CACHE_SIZE + DB_RECYCLE_CACHE_SIZE + DB_nk_CACHE_SIZE + SHARED_POOL_SIZE + LARGE_POOL_SIZE + JAVA_POOL_SIZE + STREAMS_POOL_SIZE(10g中的新内存池) + LOG_BUFFERS+11K(Redo Log Buffer的保护页) + 1MB + 16M(SGA内部内存消耗,适合于9i及之前版本)

在上面公式中,对于SGA来说有两个非常重要的指标DB_CACHE_SIZE和SHARED_POOL_SIZE 下面我们分别来讨论如何取得这两个的值。

一般来说设置1GB以上的shared pool不会给性能带来明显的提高,相反,这将给Oracle管理shared pool以及监控shared pool的过程中带来较多的麻烦。而从目前的系统来说,我们没有单独分配shared_pool内存,而是通过内存自动管理来分配的,当前shared_pool_size为912M。如果我们硬性的要求设置shared_pool的值的话,建议在系统上线之时设置为SGA的10%,但是不要超过1G,然后通过顾问来判断设置是否合理,当然必须将初始化参数statistics_level设置为typical或者all,这样才能产生顾问。

SQL> SELECT T.SHARED_POOL_SIZE_FOR_ESTIMATE “SP”,
  2         T.ESTD_LC_SIZE                  “EL”,
  3         T.ESTD_LC_MEMORY_OBJECTS        “ELM”,
  4         T.ESTD_LC_TIME_SAVED            “ELT”,
  5         T.ESTD_LC_TIME_SAVED_FACTOR     “ELTS %”,
  6         T.ESTD_LC_MEMORY_OBJECT_HITS    “ELMO”
  7  FROM   V$SHARED_POOL_ADVICE T
  8  /
        SP         EL        ELM        ELT     ELTS %       ELMO


432         98       4203     739431      0.979  175769954
       528        191       7149     744591     0.9858  176184285
       624        286      10082     750144     0.9932  176413511
       720        381      16457     753856     0.9981  176552951
       816        476      17949     754790     0.9993  176657863
       912        571      20518     755308          1  176731921
      1008        666      27638     755544     1.0003  176765699
      1104        761      39851     755725     1.0006  176794037
      1200        856      43813     755927     1.0008  176817793
      1296        951      47191     756054      1.001  176837933
      1392       1046      55562     756240     1.0012  176854191
      1488       1141      60339     756317     1.0013  176866602
      1584       1236      63715     756401     1.0014  176878638
      1680       1330      64144     756455     1.0015  176889564
      1776       1425      64660     756503     1.0016  176899694
      1872       1520      64746     756561     1.0017  176910238 
16 rows selected

ESTD_LC_SIZE:估计库高速缓存的使用数量(以兆字节为单位)
ESTD_LC_MEMORY_OBJECTS: 估算共享池中库缓存的内存对象数
ESTD_LC_TIME_SAVED: 估算将可以节省的解析时间
ESTD_LC_TIME_SAVED_FACTOR: 估算的节省的解析时间与当前节省解析时间的比
ESTD_LC_MEMORY_OBJECT_HITS: 估算可以直接从共享池中命中库缓存的内存对象的命中次数

我们主要关注estd_lc_time_saved_factor列的值,当该列的值为1时表示再增加shared pool的大小对性能的提高没有意义,对于上面例子来说,当shared pool为912MB时达到最佳。

如何设置buffer cache的大小,在oracle9i之后开始通过设置参数db_cache_advice来启动顾问,oracle会监控各种类型的buffer cache的使用,oracle会根据当前所监控到的物理读得速率,从而估算在不同大小尺寸下的buffer cache产生的可能的物理读的数量,将这些信息放入到v$db_cache_advice。

SQL> show parameters db_cache_advice;
NAME                                 TYPE        VALUE


db_cache_advice                      string      ON

当然这个参数设置为on之后,CPU的usage会有所增加,因为会存在额外的记录,在文档中提到
When the advisory is enabled,there is a small increase in CPU usage, because additional bookkeeping is required.

SQL>
SQL> SELECT SIZE_FOR_ESTIMATE         “target M”,
  2         BUFFERS_FOR_ESTIMATE,
  3         ESTD_PHYSICAL_READ_FACTOR “physical_read %”,
  4         ESTD_PHYSICAL_READS
  5  FROM   VDB_CACHE_ADVICE   6  WHERE  NAME = 'DEFAULT' AND   7         BLOCK_SIZE =   8         (SELECT VALUE FROM VPARAMETER WHERE NAME = ‘db_block_size’) AND
  9         ADVICE_STATUS = ‘ON’;
  target M BUFFERS_FOR_ESTIMATE physical_read % ESTD_PHYSICAL_READS


48                 5937         14.2714           146488649
        96                11874          7.9979            82094677
       144                17811          6.4177            65874181
       192                23748          5.6685            58183947
       240                29685          5.0403            51735717
       288                35622          4.3047            44185592
       336                41559          3.4006            34905795
       384                47496          2.4827            25483716
       432                53433          1.8562            19052864
       480                59370          1.5658            16071812
       528                65307          1.2588            12921439
       576                71244               1            10264507
       624                77181          0.8152             8367972
       672                83118          0.6549             6721931
       720                89055          0.5826             5980169
       768                94992          0.5423             5566815
       816               100929           0.511             5245267
       864               106866          0.4892             5021126
       912               112803          0.4687             4811105
       960               118740          0.4317             4431650
20 rows selected

size_for_estimate : 预测buffer cache的尺寸
buffers_for_estimate: 预测buffer Cache大小(缓冲块数)
estd_physical_read_factor: 这一缓冲大小时,物理读因子,它是如果缓冲大小为SIZE_FOR_ESTIMATE时,建议器预测物理读数与当前实际物理读数的比率值。如果当前物理读数为0,这个值为空。
estd_physical_reads: 如果缓冲大小为SIZE_FOR_ESTIMATE时,建议器预测物理读数。
上面输出中ESTD_PHYSICAL_READ_FACTOR为1时,表示当前cache的大小为576M(如下查询),如果将cache大小设置为480M,那么建立的物理读因子会增加56.58%(1.5658-1),如果将cache大小设置为672,那么那么建立的物理读因子会减少34.51%(1-0.6549),如果在系统级和SGA_MAX_SIZE允许增加的话,建议将buffer cache增加到672。当然Physical I/O 和 Buffer Cache Size并不是一个直线关系,会存在一个瓶颈,当buffer cache增大到一定值之后,Physical I/O不在减少或者减少得非常少 ,这个时候我们就没有必要在增加的必要,所以在增加cache大小的时候需要结合另外一个参数命中率(cache hit ratio)一起使用。

SQL> select name,value/1024/1024 value from v$sga;
NAME                      VALUE


Fixed Size           1.99950408
Variable Size        944.000495
Database Buffers            576
Redo Buffers                 14

SQL> SELECT NAME,
  2         VALUE
  3  FROM   V$SYSSTAT
  4  WHERE  NAME IN (‘db block gets from cache’,
  5                  ‘consistent gets from cache’,
  6                  ‘physical reads cache’);
NAME                                                                  VALUE


db block gets from cache                                          126050238
consistent gets from cache                                       4628694596
physical reads cache                                               10264507
SQL> select 1-10264507/(126050238+4628694596) from dual;
1-10264507/(126050238+46286945

0.997841207602435

此处说明一下三个参数的解释:

consistent gets from cache:Number of times a consistent read was requested for a block from the buffer cache.
db block gets from cache:Number of times a CURRENT block was requested from the buffercache
physical reads: cache Total number of data blocks read from disk into buffer cache.

SQL> show parameters log_buffer
NAME                                 TYPE        VALUE


log_buffer                           integer     14234624

SQL> show parameters DB_KEEP_CACHE_SIZE
NAME                                 TYPE        VALUE


db_keep_cache_size                   big integer 0

SQL> show parameters DB_RECYCLE_CACHE_SIZE
NAME                                 TYPE        VALUE


db_recycle_cache_size                big integer 0

上面整段可以用一条语句生成

SQL> SELECT ‘SGA-EXP-BUFFER_CACHE-SHARED_POOL’,
  2         SUM(VALUE) VALUE
  3  FROM   (SELECT SUM(VALUE) VALUE
  4          FROM   VPARAMETER   5          WHERE  NAME IN ('db_keep_cache_size',   6                          'db_recycle_cache_size',   7                          'large_pool_size',   8                          'java_pool_size',   9                          'streams_pool_size')  10          UNION ALL  11          SELECT SUM(VALUE) VALUE  12          FROM   VPARAMETER
 13          WHERE  NAME LIKE ‘db_%k_cache_size’
 14          UNION ALL
 15          SELECT (VALUE / 1024 + 11) / 1024 + 1
 16          FROM   V$PARAMETER
 17          WHERE  NAME = (‘log_buffer’));
'SGA-EXP-BUFFER_CACHE-SHARED_P        VALUE


SGA-EXP-BUFFER_CACHE-SHARED_POOL 14.5859375

最后的SGA就是上面之和

SGA=576+912+(0+0+0+0+0+0+13.5751953125+1)+16=1518.5751953125M

所以该系统上的SGA大概为1560M。

SQL> show parameters sga_max_size
NAME                                 TYPE        VALUE


sga_max_size                         big integer 1536M

二、对内存的几个参数的详细描述、ORACLE11G内存管理参数

1、首先,在ORACLE11G的INIT.ORA里,有“__”开头的参数,也就是以两个下划线开头的参数,这种参数应该是系统自动调整的结果,第一次启动系统后,系统对这些参数进行了调整,然后,把调整后的结果记录在了参数文件里,我想可能在SPFILE里也有的。而以一个下划线开头的参数,我们大家都知道,是隐含参数,就是在ORACLE的公开的文档里没说明的,也就是ORACLE不主张用户自己调整的参数。
2、现在开始讨论一下ORACLE11G里的内存参数:MEMORY_MAX_TARGET,MEMORY_TARGET,SGA_MAX_SIZE,SGA_TARGET,PGA_AGGREGATE_TARGET,WORK_SIZE_POLICY,DB_BLOCK_BUFFERS,DB_CACHE_SIZE等。
(1)MEMORY_MAX_TARGER:确定DBA能确定的MEMORY_TARGET的最大值,K|M|G;
(2)MEMORY_TARGET:确定ORACLE系统范围可用的内存大小,数据库系统调整SGA和PGA的大小来适应MEMORY_TARGET,在初始化参数里,如果你确定了MEMORY_TARGET的大小,而没确定MEMORY_MAX_TARGET,那么系统自动确定MEMORY_MAX_TARGET为MEMORY_TARGET的大小,反之,系统确定MEMORY_TARGET为0,系统启动后再动态调整MEMORY_TARGET的大小,但不会超过MEMORY_MAX_TARGET,K|M|G。
(3)SGA_MAX_SIZE:确定SGA在整个实例生命期的最大值,K|M|G。
(4)SGA_TARGET:确定SGA各组件的总大小,如果SGA_TARGET被确定,那么下面各SGA组件ORACLE自动调整:DB_CACHE_SIZE,SHARED_POOL_SIZE,LARGE_POOL_SIZE,JAVA_POOL_SIZE,STREAMS_POOL_SIZE;当你设置这些POOL为非零值时,那么,ORACLE的自动共享内存管理会把这些值当做这些POOL的最低值。而下面这些POOL需要手工调整,不受SGA_TARGET的影响:
Log buffer;Other buffer caches, such as KEEP, RECYCLE, and other block sizes;Fixed SGA and other internal allocations
(5)PGA_AGGREGATE_TARGET:确定属于ORACLE实例的所有服务器进程的、可用的、总的PGA的目标大小,确定这个参数的值为非零,会自动设置WORK_SIZE_POLICY为AUTO,这样,系统会自动调整每个SQL工作区大小,来适应该PGA_AGGREGATE_TARGET大小,如果你没确定它的值,那么系统缺省该值为SGA的20%和10M中最大的值;当你设置这个值为0时,系统自动设置WORK_SIZE_POLICY为MANUAL,这时,系统会启用系统的*_AREA_SIZE,K|M|G。
(6)WORK_SIZE_POLICY:确定WORK AREA调整模式:AUTO,MANUAL。
(7)DB_BLOCK_BUFFERS:该参数和DB_CACHE_SIZE不能一起使用的,同时,也不能和SGA_TARGET参数一起使用,因为该参数是9i以前配置DATA BUFFERS的参数,留着它可能是为了向后兼容,一般不使用它了,使用它时,不能使用DB_CACHE_SIZE和SGA_TARGET参数,该参数不能设置大小,只能设置成块数,而不能设置成K|M|G。
(8)DB_CACHE_SIZE:设置数据库缓冲的大小,当SGA_TARGET设置为非零值时,那么该参数设置数据缓冲的最小值;
(9)11g新特性,从内存参数生成SPFILE文件:
以前只能:CREATE SPFILE FROM PFILE;
现在可以:CREATE SPFILE FROM MEMORY;

三、设置大小(具体看实际的环境情况)

Oracle官方文档推荐:
MEMORY_TARGET=物理内存 x 80%
MEMORY_MAX_SIZE=物理内存 x 80%

对于OLTP系统:
SGA_TARGET=(物理内存 x 80%) x 80%
SGA_MAX_SIZE=(物理内存 x 80%) x 80%
PGA_AGGREGATE_TARGET=(物理内存 x 80%) x 20%

对于DSS系统:
SGA_TARGET=(物理内存 x 80%) x 50%
SGA_MAX_SIZE=(物理内存 x 80%) x 50%
PGA_AGGREGATE_TARGET=(物理内存 x 80%) x 50%
若有不妥之处,还请多多指点

最后修改时间:2020-12-13 15:09:04
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论