深刻解析Oracle 10g中SGA_MAX_SIZE和SGA_TARGET參數的區別和做用


SGA_MAX_SIZE是從9i以來就有的做爲設置SGA大小的一個參數,而SGA_TARGET則是從10g纔有的一個新參數,做爲配合10g自動管理SGA而出現的,下面以實驗的方式,深刻解析這2個參數的區別和做用

[oracle@bak ~]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on Mon Oct 13 01:59:11 2014

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 272M
sga_target                           big integer 272M
SQL> desc v$sgainfo
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME                                               VARCHAR2(32)
 BYTES                                              NUMBER
 RESIZEABLE                                         VARCHAR2(3)

SQL> set pages 100
SQL> select name,bytes/1024/1024 "size(MB)",resizeable from v$sgainfo;

NAME                               size(MB) RES
-------------------------------- ---------- ---
Fixed SGA Size                   1.16254425 No
Redo Buffers                      2.8359375 No
Buffer Cache Size                       172 Yes
Shared Pool Size                         80 Yes
Large Pool Size                           4 Yes
Java Pool Size                            4 Yes
Streams Pool Size                         8 Yes
Granule Size                              4 No
Maximum SGA Size                        272 No    --SGA_MAX_SIZE對應的值
Startup overhead in Shared Pool          36 No
Free SGA Memory Available                 0

11 rows selected.

注意,resizeable值爲NO的,都是不可動態調整的值,而且因爲SGA_TARGET和SGA_MAX_SIZE的大小一致,所以Free SGA Memory Available=0,而全部可動態調整的幾個內存組件再加上一個4M Granule Size,則正好等於SGA_TARGET的值

SQL> select (172 + 80 + 4 + 4 + 8 + 4) "sga_target(MB)" from dual;

sga_target(MB)
--------------
           272

咱們也能夠從v$sga_dynamic_components這個視圖瞭解各內存組件的內存分配狀況,和v$sgainfo內容基本是一致的,除了沒有展現Gradual Size這一項

SQL> select component,current_size/1024/1024 "size(MB)" from v$sga_dynamic_components;

COMPONENT                                                          size(MB)
---------------------------------------------------------------- ----------
shared pool                                                              80
large pool                                                                4
java pool                                                                 4
streams pool                                                              8
DEFAULT buffer cache                                                    172
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.

SGA = shared pool + large pool + java pool + streams pool + DEFAULT buffer cache = 80 +4 + 4 + 8 + 172 =268M
這個算出來的SGA值比SGA_TARGET的值少了4M,其實就是那個Gradual Size的值

SQL> col name for a35
SQL> select name,issys_modifiable from v$parameter where name like '%sga%';

NAME                                ISSYS_MOD
----------------------------------- ---------
sga_max_size                        FALSE
pre_page_sga                        FALSE
lock_sga                            FALSE
sga_target                          IMMEDIATE

ISSYS_MODIFIABLE列的值爲FALSE的,就是不能動態修改的參數,需重啓生效,爲IMMEDIATE的,便可以動態修改

SQL> alter system set sga_target=350m;
alter system set sga_target=350m
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00823: Specified value of sga_target greater than sga_max_size

若是不帶scope參數,默認爲both,但要在內存中生效,必須知足SGA_TARGET<SGA_MAX_SIZE的條件,所以必須指定scope=spfile,所以雖然是動態參數,可是依舊要重啓後生效

SQL> alter system set sga_target=350m scope=spfile;

System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  369098752 bytes
Fixed Size                  1219472 bytes
Variable Size             100664432 bytes
Database Buffers          264241152 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 352M
sga_target                           big integer 352M

能夠看到,當調整了SGA_TARGET參數後,儘管沒有去手動調整SGA_MAX_SIZE的值,但如今它自動和修改後的SGA_TARGET的值匹配了,從272M調整爲352M,這裏還有個比較有意思的地方,就是指定了350M,爲什麼會變爲352M,這多出來的2M又是什麼呢?

SQL> select 350/4 "Granual Count" from dual;

Granual Count
-------------
         87.5

SQL> select 88*4 "SGA_SIZE(MB)" from dual;

SGA_SIZE(MB)
------------
         352

其實很容易理解,剛纔說了Granual Size的大小爲4M,因爲Granual必須完整地分配,所以會分配給SGA共88個Granual,即88*4=352M,也就是多給了2M

再來看一下剛纔那些內存組件的內存分配狀況

SQL> select name,bytes/1024/1024 "size(MB)",resizeable from v$sgainfo;

NAME                                  size(MB) RES
----------------------------------- ---------- ---
Fixed SGA Size                      1.16297913 No
Redo Buffers                         2.8359375 No
Buffer Cache Size                          252 Yes
Shared Pool Size                            80 Yes
Large Pool Size                              4 Yes
Java Pool Size                               4 Yes
Streams Pool Size                            8 Yes
Granule Size                                 4 No
Maximum SGA Size                           352 No
Startup overhead in Shared Pool             36 No
Free SGA Memory Available                    0

11 rows selected.

SQL> select component,current_size/1024/1024 "size(MB)" from v$sga_dynamic_components;

COMPONENT                                                          size(MB)
---------------------------------------------------------------- ----------
shared pool                                                              80
large pool                                                                4
java pool                                                                 4
streams pool                                                              8
DEFAULT buffer cache                                                    252
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> 

當咱們把SGA_TARGET從272M調整爲350M時,因爲Gruanual的存在,Oracle實際給SGA分配了352M的內存,而這352M內存中,其餘內存組件的大小都沒有發生變化,僅僅只是db buffer cache的值由以前的172M調整到了252M

之因此db buffer cache size隨着SGA_TARGET的值自動調整,是由於這時10g的新特性,只要SGA_TARGET爲非零值,那麼內存組件就是採用動態分配原則,由Oracle自動調整各內存組件的大小。不過有個地方挺奇怪的,雖然從啓動實例時分配地內存也好,從v$sgainfo以及v$sga_dynamic_components中也好,看到的值都是252M,而從參數看db_cache_size的值,仍然是172M,不知何故,難道是bug?

SQL> show parameter db_cache

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_cache_advice                      string      ON
db_cache_size                        big integer 172M

剛纔是直接修改SGA_TARGET而不修改SGA_MAX_SIZE的狀況,咱們再來看一下反過來的狀況,先把SGA_TARGET調整回272M

SQL> alter system set sga_target=270m scope=spfile;

System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  285212672 bytes
Fixed Size                  1219016 bytes
Variable Size             100664888 bytes
Database Buffers          180355072 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 272M
sga_target                           big integer 272M

注意,一旦SGA_TARGET動了,重啓數據庫後,SGA_MAX_SIZE會跟着調整,也一塊兒回到了272M的狀態,但與增大SGA_TARGET時的狀況不一樣,也能夠選擇不重啓數據庫,那麼SGA_MAX_SIZE的值就不會作調整,而內存組件的值依然會跟着SGA_TARGET走(體現動態調整)

SQL> alter system set sga_target=270m;

System altered.

SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 352M
sga_target                           big integer 272M

因爲是減少SGA_TARGET的值,所以不受必須比TARGET_MAX_SIZE小的這個條件限制,所以數據庫無需重啓

SQL> select name,bytes/1024/1024 "size(MB)",resizeable from v$sgainfo;

NAME                                  size(MB) RES
----------------------------------- ---------- ---
Fixed SGA Size                      1.16297913 No
Redo Buffers                         2.8359375 No
Buffer Cache Size                          172 Yes    --僅僅調整了db buffer cache,由252M變爲172M
Shared Pool Size                            80 Yes
Large Pool Size                              4 Yes
Java Pool Size                               4 Yes
Streams Pool Size                            8 Yes
Granule Size                                 4 No
Maximum SGA Size                           352 No
Startup overhead in Shared Pool             36 No
Free SGA Memory Available                   80

11 rows selected.

剛纔是直接調整SGA_TARGET,咱們再來看一下只調整SGA_MAX_SIZE的狀況,先重啓數據庫,使SGA_MAX_SIZE的值回到272M

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  285212672 bytes
Fixed Size                  1219016 bytes
Variable Size             100664888 bytes
Database Buffers          180355072 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 272M
sga_target                           big integer 272M
SQL> alter system set sga_max_size=350m scope=spfile;

System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  369098752 bytes
Fixed Size                  1219496 bytes
Variable Size             184550488 bytes
Database Buffers          180355072 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 352M
sga_target                           big integer 272M
SQL> select name,bytes/1024/1024 "size(MB)",resizeable from v$sgainfo;

NAME                                  size(MB) RES
----------------------------------- ---------- ---
Fixed SGA Size                      1.16300201 No
Redo Buffers                         2.8359375 No
Buffer Cache Size                          172 Yes
Shared Pool Size                            80 Yes
Large Pool Size                              4 Yes
Java Pool Size                               4 Yes
Streams Pool Size                            8 Yes
Granule Size                                 4 No
Maximum SGA Size                           352 No
Startup overhead in Shared Pool             36 No
Free SGA Memory Available                   80

11 rows selected.

注意,僅僅調整SGA_MAX_SIZE後,SGA_TARGET並不會跟着調整,所以各內存組件的值也不會調整,而這時咱們發現Free SGA Memory Available的值爲80M,而再也不是以前的0了,調整SGA_MAX_SIZE爲SGA_TARGET增長了80M的上限,這80就是352-272獲得的,至關於作了個預留,告訴SGA,你能夠如今只用172M,但若是想增長,能夠再多用80M,達到352M。而這個時候只要SGA_TARGET從新設置的值沒有超過SGA_MAX_SIZE的值,就能夠在不停庫的狀況下增長SGA大小,這樣作是有好處的

最後,咱們還能夠把SGA_TARGET設置爲0,即表示禁用10g的新特性——自動分配內存,這樣咱們能夠對各個內存組件的值進行單獨設置,對於特殊的應用場景,有時候也是須要的,由於自動管理只是oracle提供的一種便利行,但並不意味着自動調整就必定萬事皆OK,11g的自動內存管理就一度被詬病,這裏不討論

SQL> alter system set sga_target=0;

System altered.

SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 352M
sga_target                           big integer 0
SQL> select name,bytes/1024/1024 "size(MB)",resizeable from v$sgainfo;

NAME                                  size(MB) RES
----------------------------------- ---------- ---
Fixed SGA Size                      1.16300201 No
Redo Buffers                         2.8359375 No
Buffer Cache Size                          172 Yes
Shared Pool Size                            80 Yes
Large Pool Size                              4 Yes
Java Pool Size                               4 Yes
Streams Pool Size                            8 Yes
Granule Size                                 4 No
Maximum SGA Size                           352 No
Startup overhead in Shared Pool             36 No
Free SGA Memory Available                   80

設置SGA_TARGET=0之後,已經分配的內存組件的值不會變化,若是不設置新值,那麼依舊保持原來的值,除非單獨設置,即便從起數據庫實例也同樣,SGA_MAX_TARGET依然不會再根據SGA_TARGET調整,由於SGA_MAX_TARGET咱們是給過它肯定的值的

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  369098752 bytes
Fixed Size                  1219496 bytes
Variable Size             184550488 bytes
Database Buffers          180355072 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> show parameter sge
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 352M    --重啓後依然是352M,並不會變爲0
sga_target                           big integer 0
SQL> select name,bytes/1024/1024 "size(MB)",resizeable from v$sgainfo;

NAME                                  size(MB) RES
----------------------------------- ---------- ---
Fixed SGA Size                      1.16300201 No
Redo Buffers                         2.8359375 No
Buffer Cache Size                          172 Yes
Shared Pool Size                            80 Yes
Large Pool Size                              4 Yes
Java Pool Size                               4 Yes
Streams Pool Size                            8 Yes
Granule Size                                 4 No
Maximum SGA Size                           352 No
Startup overhead in Shared Pool             36 No
Free SGA Memory Available                   80

11 rows selected.

SQL> alter system set sga_target=270m;

System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  369098752 bytes
Fixed Size                  1219496 bytes
Variable Size             184550488 bytes
Database Buffers          180355072 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 352M
sga_target                           big integer 272M

重啓數據庫實例後,SGA_MAX_SIZE的值沒有跟着SGA_TARGET作調整,除非再次增大SGA_TARGET的大小並超過SGA_MAX_SIZE的上限,那麼下次重啓後,SGA_MAX_SIZE又會再一次跟着SGA_TARGET調整

SQL> alter system set sga_target=380m scope=spfile;

System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  398458880 bytes
Fixed Size                  1219640 bytes
Variable Size             100664264 bytes
Database Buffers          293601280 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 380M
sga_target                           big integer 380M

SGA_MAX_SIZE又再一次和SGA_TARGET的值一致了,而且380正好能夠除盡4,共分配95個Granual,所以不會有多2M的問題

總結:

1.SGA_MAX_SIZE是靜態參數,而SGA_TARGET能夠動態修改,當要改的SGA_TARGET值超過SGA_MAX_SIZE的值時,由於不容許在內存中直接生效,即scope=both或memory都不行,所以必須指定scope=spfile,重啓後才能修改爲功。若是此時沒有設置過SGA_MAX_SIZE得值,那麼不管是改大仍是改小,重啓數據庫後,SGA_MAX_SIZE都回跟着SGA_TARGET作調整。

2.當先給SGA_MAX_SIZE設置了一個較大的值,重啓數據庫後,SGA_TARGET能夠依然保持原有大小,至關於給SGA_TARGET先預留了一些內存,預先設置好可SGA可分配內存,等到數據庫出現壓力致使SGA內存不足,能夠直接經過SGA_TARGET動態修改到這一上限而無需停庫。

3.當給SGA_TARGET設置非零值時,表示採用內存組件內存由oracle動態調整,如shared pool,db buffer cache等,這些內存組件只會跟着SGA的大小動態進行調整(增大或減少),與其餘值無關。

4.當SGA_TARGET設置爲零時,表示禁用內存組件由SGA自動管理,若是未作單獨設置,那麼保持原有值。此時能夠根據具體場景需求,單獨
爲某個內存組件配置合理的內存大小。

5.若是是先設置了SGA_MAX_SIZE的值,再設置了SGA_TARGET,那麼只有當SGA_TARGET設置的值超過SGA_MAX_SIZE的值時,SGA_MAX_SIZE纔會在重啓生效後,調整到與SGA_TARGET的值一致,反之則不會改變。
相關文章
相關標籤/搜索