当前位置: 首页 > Oracle, oracle 11g > 正文

SGA_TARGET大于SGA_MAX_SIZE的真实案例

今天在给库户数据库健康检查的时候,发现个很奇怪的问题,SGA_TARGET参数的值竟然大于SGA_MAX_SIZE参数的值。

NAME                                 TYPE        VALUE
------------------------------------ ----------- -----
sga_max_size                         big integer 1984M
sga_target                           big integer 2000M

大家应该都知道SGA_MAX_SIZE是ORACLE可用的最大SGA,SGA_TARGET是ORACLE自动管理的SGA,SGA_TARGET可以小于等于SGA_MAX_TARGET,但不能大于SGA_MAX_SIZE,即使可以大于SGA_MAX_SIZE,也是没有意义的,所以这个现象应该是不会出现的才对,我做了些实验,也没有模拟出来。

SQL> show parameter sga_

NAME                   TYPE                 VALUE
---------------------- -------------------- ----------
sga_max_size           big integer          300M
sga_target             big integer          300M

我的数据库现在SGA_MAX_SIZE和SGA_TARGET参数的值都是300M,现在将SGA_TARGET的值改为350M,如果直接修改肯定会报错。

SQL> alter system set sga_target=350M;
alter system set sga_target=350M
*
第 1 行出现错误:
ORA-02097: 无法修改参数, 因为指定的值无效
ORA-00823: 指定的 sga_target 的值大于 sga_max_size

如果指定SCOPE=SPFILE,重启数据库后,如果是10g的数据库,SGA_MAX_TARGET参数的值也会被更改为350M,如果是11g的数据库,会报ORA-00823错误,下面是10g的数据库修改SGA_TARGET参数情况。

SQL> show parameter sga_
NAME                                 TYPE        VALUE
------------------------------------ ----------- --------
sga_max_size                         big integer 300M
sga_target                           big integer 300M
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
SQL> alter system set sga_target=350M scope=spfile;
System altered.
SQL> startup force
ORACLE instance started.
Total System Global Area  368263168 bytes
Fixed Size                  1374668 bytes
Variable Size             239076916 bytes
Database Buffers          121634816 bytes
Redo Buffers                6176768 bytes
Database mounted.
Database opened.
SQL> show parameter sga_
NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------
sga_max_size                         big integer 350M
sga_target                           big integer 350M

下面是11g数据库修改SGA_TARGET参数情况。

SQL> select * from v$version;
BANNER
-----------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for 32-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL> alter system set sga_target=350M scope=spfile;
系统已更改。
SQL> startup force;
ORA-00823: Specified value of sga_target greater than sga_max_size

可是客户的数据库为什么SGA_TARGET的值会大于SGA_MAX_SIZE呢?这应该是和ORACLE的granule(粒度)有关系,granule是ORACLE内存中的一片连续区域,是连续虚拟内存分配的单位,粒度是9i新引入的参数,其大小取决于SGA_MAX_SIZE参数所定义的SGA总的大小,9i的数据库,linux环境下,SGA_MAX_SIZE<128MB的时候,一个granule是4M,SGA_MAX_SIZE>128MB的时候,一个granule是16M,32位的Windows环境下,SGA_MAX_SIZE<128MB的时候,一个granule是4M,SGA_MAX_SIZE>128MB的时候,一个granule是8M。10g的数据库,linux环境下,SGA_MAX_SIZE<1g的时候,一个granule是4M,SGA_MAX_SIZE>1g的时候,一个granule是16M,32位的Windows环境,SGA_MAX_SIZE<1g的时候,一个granule是4M,SGA_MAX_SIZE>1g的时候,一个granule是16M,granule受隐含参数“_ksmg_granule_size控制,建议不要修改,ORACLE在分配内存的时候,是以granule为单位比如,即使手工设置的shared pool大小不是granule的整数倍,ORACLE会自动设置为granule的整数倍,例如:

SQL> select name,bytes from v$sgainfo where name in('Shared Pool Size',
'GranuleSize');
NAME                                  BYTES
-------------------------------- ----------
Shared Pool Size                  192937984
Granule Size                        4194304

我的数据库granule大小为4M,shared pool为184M,设置shared pool 为
185M,ORACLE将自动将shared pool 设置为188M。

SQL> alter system set shared_pool_size=185M;
系统已更改。
SQL> show parameter shared_pool_size
NAME TYPE VALUE
------------------------ -------------------- ----------
shared_pool_size big integer 188M

我们的这个客户是64位的linux,ORACLE10gR2数据库,SGA大于1984M,granule是16M。

SQL> show parameter sga_
NAME                                 TYPE        VALUE
------------------------------------ ----------- -----
sga_max_size                         big integer 1984M
sga_target                           big integer 2000M
SQL> select name,bytes/1024/1024 from v$sgainfo where name=’ Granule Size';
NAME                                  BYTES
-------------------------------- ----------
Granule Size                               16

SGA_MAX_SIZE也是16M的整数倍,为什么SGA_TARGET会比SGA_MAX_SIZE大一个granule呢? 查看客户的参数文件,里面只有SGA_TARGET=2097152000,并没有SGA_MAX_SIZE参数的设置,按理说SGA_MAX_SIZE参数的值应该会自动设置和SGA_TARGET一样才对。而且AWR显示虽然SGA_TARGET比SGA_MAX_SIZE大了一个granule,但这是没有意义的,数据库真实用到的SGA并你没有超过SGA_MAX_SIZE的限制。

至于为什么客户的这个数据库SGA_TARGET回比SGA_MAX_SIZE的值大,我想可能是和ORACLE的内部算法有关系,或者,ORACLE算错数了!!!!

本文固定链接: http://www.dbdream.com.cn/2011/12/sga_target%e5%a4%a7%e4%ba%8esga_max_size%e7%9a%84%e7%9c%9f%e6%98%af%e6%a1%88%e4%be%8b/ | 信春哥,系统稳,闭眼上线不回滚!

该日志由 dbdream 于2011年12月15日发表在 Oracle, oracle 11g 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: SGA_TARGET大于SGA_MAX_SIZE的真实案例 | 信春哥,系统稳,闭眼上线不回滚!
关键字:

SGA_TARGET大于SGA_MAX_SIZE的真实案例:目前有2 条留言

  1. 沙发
    北在南方:

    哥们儿,你的博客很棒,不过标题有个错别字 “真是”—>“真实”~~

    2011-12-16 02:44 [回复]
    • streamsong:

      谢谢,平时不太注意,多谢指点。

      2012-01-05 01:35 [回复]

发表评论

快捷键:Ctrl+Enter