Oracle ASMM和AMM

Oracle ASMM和AMM


ASMM(Automatic Shared Memory Management,自動共享內存管理)是Oracle 10g引入的概念。經過使用ASMM,就不須要手工設置相關內存組件的大小,而只爲SGA設置一個總的大小,
Oracle的MMAN進程(Memory Manager Process,內存管理進程)會隨着時間推移,根據系統負載的變化和內存須要,自動調整SGA中各個組件的內存大小。
ASMM的SGA中包含的組件及對應參數以下表所示:


在Oracle 10g中,必須將STATISTICS_LEVEL參數設置爲TYPICAL(默認值)或者ALL才能啓用ASMM功能,若是將其值設置爲BASIC,那麼會禁用不少新特性,好比像AWR、ASMM等。
若是使用SQL*Plus來設置ASMM,那麼必須先把SGA中包含的組件的值設置爲0。經過設置SGA_TARGET參數爲非零值來啓用ASMM功能。java

能夠經過如下SQL來計算SGA_TARGET的值:數據庫

SELECT ((SELECT SUM(VALUE) FROM V$SGA) - (SELECT CURRENT_SIZE FROM V$SGA_DYNAMIC_FREE_MEMORY)) "SGA_TARGET"  FROM DUAL;緩存

設置SGA_TARGET的值,能夠直接修改初始化參數文件後重啓數據庫,或者經過下面SQL命令進行修改:服務器

ALTER SYSTEM SET SGA_TARGET=value [SCOPE={SPFILE|MEMORY|BOTH}];數據結構

示例以下所示:oracle

ALTER SYSTEM SET SGA_TARGET = 992M;app

ALTER SYSTEM SET SHARED_POOL_SIZE = 0;框架

ALTER SYSTEM SET LARGE_POOL_SIZE = 0;less

ALTER SYSTEM SET JAVA_POOL_SIZE = 0;ide

ALTER SYSTEM SET STREAMS_POOL_SIZE = 0;

ALTER SYSTEM SET DB_CACHE_SIZE = 0;

在啓用ASMM後,Oracle會自動調整SGA內部組件大小。若再手動指定某一組件值,則該值爲該組件的最小值。例如,手動設置SGA_TARGET=8G,SHARED_POOL_SIZE=1G,
則ASMM在自動調整SGA內部組件大小時,保證Shared Pool不會低於1G。當設置了SGA_TARGET參數後,Oracle將會收集SGA相關的統計數據,並經過V$SGA_TARGET_ADVICE呈現出來,
所以,能夠根據這些指導SGA_TARGET作相關的調整,以達到最佳狀況。

Oracle 10g的ASMM實現了自動共享內存管理,可是具備必定的侷限性。因此,在Oracle 11g中,Oracle引入了AMM(Automatic Memory Management,自動內存管理)的概念,
實現了所有內存的自動管理。DBA能夠僅僅經過設置一個目標內存大小的初始化參數(MEMORY_TARGET)和可選最大內存大小初始化參數(MEMORY_MAX_TARGET)就能夠在大多數平臺上實現AMM。
AMM可使實例總內存保持相對穩定的狀態,Oracle基於MEMORY_TARGET的值來自動調整SGA和PGA的大小。MEMORY_TARGET是動態初始化參數,能夠隨時修改該參數的值而不用重啓數據庫。
MEMORY_MAX_TARGET做爲一個內存上限值,是一個靜態參數,它是MEMORY_TARGET能夠被配置的最大值。

若是內存發生變化,實例會自動在SGA和PGA之間作調整。若啓用了AMM功能,而SGA_TARGET和PGA_AGGREGATE_TARGET沒有顯式的被設置,
則默認SGA_TARGET爲MEMORY_TARGET的60%,PGA_AGGREGATE_TARGET爲MEMORY_TARGET的40%。
若是MEMORY_MAX_TARGET設置爲1400M,而MEMORY_TARGET設置爲1000M,那麼對於數據庫實例而言,只有1000M可使用,剩下的400M會被保留下來,
但會被Oracle的MMAN進程鎖定。可是,由於MEMORY_MAX_TARGET是顯式設置的,因此,能夠在不重啓數據庫的狀況下動態調整MEMORY_TARGET。
若是隻設置了MEMORY_TARGET的值,而MEMORY_MAX_TARGET沒有顯式設置,那麼MEMORY_MAX_TARGET的值默認是MEMORY_TARGET的大小。

當LOCK_SGA初始化參數的值設置爲TRUE時,不能啓用AMM,該參數的值默認爲FALSE。

只要是設置了MEMORY_MAX_TARGET或MEMORY_TARGET,那麼就說明啓用了AMM。可使用視圖V$MEMORY_DYNAMIC_COMPONENTS動態查閱內存各組件的當前實時大小。

若是在建立數據庫的時候未啓用AMM,那麼能夠在建庫後啓用它,啓用AMM須要重啓數據庫,具體步驟以下所示:

一、查詢SGA_TARGET和PGA_AGGREGATE_TARGET的值,從而肯定MEMORY_TARGET的最小值

SYS@lhrdb> SHOW PARAMETER TARGET

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

pga_aggregate_target                 big integer 409M

sga_target                           big integer 1648M

二、肯定自系統啓動以來PGA的最大值,單位爲bytes

SYS@lhrdb> select value from v$pgastat where name='maximum PGA allocated';

     VALUE

----------

 248586240

三、經過如下方法來計算出SGA_TARGET的最大值

memory_target = sga_target + max(pga_aggregate_target, maximum PGA allocated)

例如:在這裏,SGA_TARGET的值爲1648M,PGA_AGGREGATE_TARGET的值爲409M,PGA的最大值爲248586240/1024/1024=237M,因此,MEMORY_TARGET的值至少爲1648+409=2057M。

四、設置系統參數啓用AMM

ALTER SYSTEM SET MEMORY_MAX_TARGET = 2100M  SCOPE=SPFILE;

--重啓數據庫

ALTER SYSTEM SET MEMORY_TARGET = 2057M;

ALTER SYSTEM SET SGA_TARGET = 0;

ALTER SYSTEM SET PGA_AGGREGATE_TARGET = 0;

另外須要說明的一點是,使用AMM常常出現的一個錯誤是「ORA-00845: MEMORY_TARGET not supported on this system」。

[ZFZHLHRDB1:oracle]:/oracle>oerr ora 845

00845, 00000, "MEMORY_TARGET not supported on this system"

// *Cause: The MEMORY_TARGET parameter was not supported on this operating system or /dev/shm was not sized correctly on Linux.

// *Action: Refer to documentation for a list of supported operating systems. Or, size /dev/shm to be at least the SGA_MAX_SIZE on each Oracle instance running on the system.

這個錯誤緣由是操做系統不支持MEMORY_TARGET參數或/dev/shm的大小設置不正確。解決方法就是將/dev/shm的值增大,至少須要大於數據庫參數MEMORY_MAX_TARGET的值。修改步驟以下:

[root@LHRDB ~]# cat /etc/fstab | grep tmpfs    #查看/dev/shm大小

tmpfs                   /dev/shm                tmpfs   defaults,size=1G 0 0

[root@LHRDB ~]# mount -o remount,size=4G /dev/shm     #臨時修改/dev/shm大小

[root@LHRDB ~]# vi /etc/fstab  #永久修改/dev/shm大小, tmpfs /dev/shm tmpfs defaults,size=4G 0 0

[root@LHRDB ~]# df -h | grep shm

tmpfs                 4.0G     0  4.0G   0% /dev/shm

[root@LHRDB ~]# df -h /dev/shm/

Filesystem      Size  Used Avail Use% Mounted on

tmpfs            4.0G    0    4.0G  0%   /dev/shm

[root@LHRDB ~]# cat /etc/fstab | grep tmpfs

tmpfs                   /dev/shm                tmpfs   defaults,size=4G        0 0

再次啓動數據庫就能夠正常啓動了。

因爲AMM不支持HugePage,而ASMM支持HugePage,因此,在生產庫上強烈推薦使用ASMM。有關ASMM和AMM的區別以下表所示:

表 3-10 ASMM和AMM的區別



MOS 文檔「     SGA and PGA Management in 11g's Automatic Memory Management (AMM) (     文檔     ID 1392549.1)     」對     AMM     和     ASMM     有很是詳細的說明。









 Oracle 11g AMM與ASMM切換 

如今的Oracle正在往智能化方向發展。若是咱們如今找一些8i/9i時代的Oracle書籍,怎麼樣配置合適的數據庫各內存池大小是很是重要的話題。可是進入10g以後,自動內存池調節成爲一個重要Oracle特性。

 

在10g時,Oracle推出了ASMM(Automatic Shared Memory Management),實現了Oracle SGA和PGA內部結構的自調節。進入11g以後,AMM(Automatic Memory Management)實現了參數MEMORY_TARGET,將SGA和PGA的規劃所有統籌起來對待。

 

默認狀況下,Oracle 11g是使用AMM的。咱們在安裝過程當中,指定Oracle使用內存的百分比,這個取值就做爲MEMORY_TARGET和MEMORY_MAX_TARGET的初始取值使用。若是這兩個參數設置爲非零取值,那麼Oracle就是採用AMM管理策略的。

 

同時,若是咱們設置這兩個參數爲0,則AMM自動關閉。對應的SGA_TARGET、PGA_AGGREGATE_TARGET參數取值非零以後,Oracle自動退化使用ASMM特性。

 

本篇簡單介紹一下AMM和ASMM的相互切換。

 

一、實驗環境介紹

 

咱們選擇11.2.0.3進行試驗,當前狀態爲ASMM。

 

 

SQL> select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production

PL/SQL Release 11.2.0.3.0 - Production

CORE        11.2.0.3.0         Production

 

 

當前MEMORY_TARGET設置爲零,AMM沒有啓用。

 

 

SQL> show parameter target

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

archive_lag_target                   integer     0

db_flashback_retention_target        integer     1440

fast_start_io_target                 integer     0

fast_start_mttr_target               integer     0

memory_max_target                    big integer 0

memory_target                        big integer 0

parallel_servers_target              integer     16

pga_aggregate_target                 big integer 108M

sga_target                           big integer 252M

 

 

二、從ASMM到AMM

 

在11g中,若是使用ASMM,對應的內存共享段是真實的共享段。

 

 

[oracle@SimpleLinux ~]$ ipcs -m

 

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status     

0x00000000 32768      oracle    640        4194304    32                     

0x00000000 65537      oracle    640        260046848  32                     

0x01606d30 98306      oracle    640        4194304    32  

 

 

下面進行參數的調整,這裏筆者有一個建議,不少時候啓動umount階段故障都是因爲不當的參數修改形成的。在進行參數修改以前,可使用create pfile進行一下參數備份,能夠加快故障出現時候的系統修復速度。

 

 

SQL> show parameter spfile

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

spfile                               string      /u01/app/oracle/dbs/spfileora11g.ora

 

SQL> create pfile from spfile;

Done

 

 

修改系統參數,將sga和pga的target值設置爲0,memory的target設置非0。注意,這個過程不少參數是靜態的參數,能夠都在spfile可見性中進行修改,以後重啓服務器生效。

 

 

SQL> alter system set memory_max_target=360m scope=spfile;

System altered

 

SQL> alter system set memory_target=360m scope=spfile;

System altered

 

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

System altered

 

SQL> alter system set sga_max_size=0 scope=spfile;

System altered

 

SQL> alter system set pga_aggregate_target=0 scope=spfile;

System altered

 

 

從新啓動數據庫服務器,查看參數配置。

 

 

SQL> conn / as sysdba

Connected.

SQL> startup force

ORACLE instance started.

 

Total System Global Area  263651328 bytes

Fixed Size                  1344284 bytes

Variable Size             176164068 bytes

Database Buffers           83886080 bytes

Redo Buffers                2256896 bytes

Database mounted.

Database opened.

 

SQL> show parameter target

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

archive_lag_target                   integer     0

db_flashback_retention_target        integer     1440

fast_start_io_target                 integer     0

fast_start_mttr_target               integer     0

memory_max_target                    big integer 360M

memory_target                        big integer 360M

parallel_servers_target              integer     16

pga_aggregate_target                 big integer 0

sga_target                           big integer 0

 

 

AMM啓動以後,系統共享段變爲「虛擬」共享段。

 

[oracle@SimpleLinux dbs]$ ipcs -m

 

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status     

0x00000000 163840     oracle    640        4096       0                      

0x00000000 196609     oracle    640        4096       0                      

0x01606d30 229378     oracle    640        4096       0  

 

 

三、從AMM到ASMM

 

下面是如何從AMM到ASMM。要徹底關閉AMM,必定將MEMORY_TARGET和MEMORY_MAX_TARGET都設置爲0才行。

 

 

SQL> alter system set memory_max_target=0 scope=spfile;

System altered

 

SQL> alter system set memory_target=0 scope=spfile;

System altered

 

SQL> alter system set pga_aggregate_target=100m scope=spfile;

System altered

 

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

System altered

 

SQL> alter system set sga_max_size=260m scope=spfile;

System altered

 

 

注意,此時若是從新啓動系統,會報錯。

 

 

SQL> startup force

ORA-00843: Parameter not taking MEMORY_MAX_TARGET into account

ORA-00849: SGA_TARGET 272629760 cannot be set to more than MEMORY_MAX_TARGET 0.

SQL>

 

 

這個問題的緣由是Oracle啓動過程當中對於參數的內部檢查。由於MEMORY_MAX_TARGET被「顯示」的賦值,與SGA_TARGET賦值相沖突。

 

解決的方法就是使用參數默認值。建立出pfile以後,將顯示賦值爲0的MEMORY_TARGET和MEMORY_MAX_TARGET記錄行刪除掉。再利用pfile啓動數據庫,重建spfile。

 

 

SQL> create pfile from spfile

  2  ;

 

File created.

 

--修改前

*.db_recovery_file_dest='/u01/app/fast_recovery_area'

*.db_recovery_file_dest_size=10737418240

*.diagnostic_dest='/u01/app'

*.dispatchers='(PROTOCOL=TCP) (SERVICE=ora11gXDB)'

*.log_checkpoints_to_alert=TRUE

*.memory_max_target=0

*.memory_target=0

*.open_cursors=300

*.pga_aggregate_target=104857600

*.processes=150

 

--修改後

*.db_recovery_file_dest='/u01/app/fast_recovery_area'

*.db_recovery_file_dest_size=10737418240

*.diagnostic_dest='/u01/app'

*.dispatchers='(PROTOCOL=TCP) (SERVICE=ora11gXDB)'

*.log_checkpoints_to_alert=TRUE

*.open_cursors=300

*.pga_aggregate_target=104857600

*.processes=150

*.remote_login_passwordfile='EXCLUSIVE'

 

 

使用pfile啓動數據庫,重建spfile。

 

 

SQL> conn / as sysdba

Connected to an idle instance.

SQL> startup pfile=/u01/app/oracle/dbs/initora11g.ora

ORACLE instance started.

 

Total System Global Area  272011264 bytes

Fixed Size                  1344372 bytes

Variable Size             176163980 bytes

Database Buffers           88080384 bytes

Redo Buffers                6422528 bytes

Database mounted.

Database opened.

SQL> show parameter target

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

archive_lag_target                   integer     0

db_flashback_retention_target        integer     1440

fast_start_io_target                 integer     0

fast_start_mttr_target               integer     0

memory_max_target                    big integer 0

memory_target                        big integer 0

parallel_servers_target              integer     16

pga_aggregate_target                 big integer 100M

sga_target                           big integer 260M

 

SQL> create spfile from pfile

  2  ;

 

File created.

 

 

從新啓動以後,ASMM切換完成。

 

 

SQL> startup force

ORACLE instance started.

 

Total System Global Area  272011264 bytes

Fixed Size                  1344372 bytes

Variable Size             176163980 bytes

Database Buffers           88080384 bytes

Redo Buffers                6422528 bytes

Database mounted.

Database opened.

 

--真實的共享內存段結構

[oracle@SimpleLinux dbs]$ ipcs -m

 

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status     

0x00000000 425984     oracle    640        8388608    25                     

0x00000000 458753     oracle    640        264241152  25                     

0x01606d30 491522     oracle    640        4194304    25 

 

--HugePage使用狀況

[oracle@SimpleLinux dbs]$ grep Huge /proc/meminfo

HugePages_Total:    67

HugePages_Free:      1

HugePages_Rsvd:      0

Hugepagesize:     4096 kB

[oracle@SimpleLinux dbs]$

 

 

四、結論

 

AMM和ASMM是咱們管理數據庫很是重要的工具,藉助自我調節的機制,咱們能夠作到數據庫自我管理。11g的AMM應該說是很方便的,可是在一些狀況下,如HugePage,咱們可能須要切換回ASMM。權當記錄,留須要的朋友待查。




每個Oracle的初學者在入門階段都會接觸到SGA/PGA的知識,若是是從10g開始學習那麼會多或少會對ASMM有所瞭解,從使用的角度來講ASMM的出現極大地簡化了Oracle內存初始化參數的設置,在ASMM的使用上高級DBA和初學者不會有太大的差異;不少人所以而認爲ASMM極大程度地減小了數據庫對於專業DBA的依賴:若是咱們有一個足夠智能的DB,那麼爲何還要花費金錢僱傭DBA呢?這彷佛是時下一種十分流行的想法。固然這種想法我我的是不能苟同的,ASMM必定程度上帶來了便利,更大程度上它是一個黑盒,黑盒裏面藏了不少祕密,這些祕密帶來比手動管理更多的不肯定性;在10g release 1和10.2的早期版本中ASMM扮演的角色有點像一個闖禍精,另外一個讓用戶對ASMM很不待見的緣由是ASMM直接拖慢了startup的速度。一個我的觀點是ASMM也好AMM也罷,都要求產品數據庫DBA掌握更多SGA/PGA相關的知識才能成功」駕馭」這些」有智力」的傢伙,有點誇張的說這個時候的DBA很像一個chemist(須要和一大堆以1個或2個下劃線開頭的奇怪參數打交道)。

爲了避免辱使命咱們真的有必要了解一下ASMM的基本知識,顯然這並非一件容易的事情……

Oracle的SGA基本內存組件從9i開始並無很是大的變化,他們包括:

  • Buffer Cache 咱們常說的數據庫高速緩存,雖然我一直不明白要冠以高速之名
    • Default Pool                  默認的緩衝池,大小由DB_CACHE_SIZE決定
    • Keep Pool                     持久的緩衝池,大小由DB_KEEP_CACHE_SIZE決定
    • Non standard pool         非標準塊標準池,大小由DB_nK_cache_size決定
    • Recycle pool                 回收池,大小由db_recycle_cache_size決定
  • Shared Pool 共享池,大小由shared_pool_size決定
    • Library cache   俗稱的庫緩存
    • Row cache      行緩存,也叫字典緩存
  • Java Pool         java池,大小由Java_pool_size決定
  • Large Pool       大池,大小由Large_pool_size決定
  • Fixed SGA       固定的SGA區域,包含了Oracle內部的數據結構,通常被存放在第一個granule中

在9i中還沒有引入ASMM,惟一的選擇是手動管理的SGA,有時候也叫作MSMM。在9i中除去buffer cache的大小能夠手動修改外,其他組件都沒法動態修改。由於缺少一種動態管理的機制,因此在9i中若是有某個內存區域有急用,也沒法從其餘有空閒內存的組件中捐獻一些來解燃眉之急。

手動管理SGA的缺點在於:

  • 個別組件如shared pool、default buffer pool的大小存在最優值,但組件之間沒法交換內存
  • 在9i中就提供了多種內存建議(advisor),但都要求人工手動干預
  • 沒法適應工做負載存在變化的環境
  • 每每會致使內存浪費,沒有用到實處
  • 若設置不當,引起著名的ORA-04031錯誤的可能性大大提升

ASMM的優點在於:

  • 全自動的共享內存管理
  • 無需再配置每個內存組件大小參數
  • 僅使用一個參數sga_target驅動
  • 有效利用全部可用的內存,極大程度上減小內存浪費
  • 對比MSMM其內存管理模式:
    • 更加動態
    • 更加靈活
    • 並具有適應性
  • 易於使用
  • 必定程度上加強了性能,由於內存分配更爲合理了
  • 當某個組件急需更多內存時能夠有效提供,所以能夠必定程度避免ORA-04031的發生

ASMM主要能夠囊括爲三個部分:
1.由一個新參數sga_target驅動的管理模式
2.內存交換的模型,包括了:內存組件(memory component),內存代理(memory broker)和內存交換機制(memory mechanism)
3.內存建議(memory advisor)

ASMM下一部分參數是自動設置的(Automatically set),這些參數包括:shared_pool_size、db_cache_size、java_pool_size、large_pool _size和streams_pool_size;而另一些是須要手動設置的靜態參數,包括了:db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size、log_buffer以及固定SGA內存結構等,若是以上沒有手動設置這些參數的話,除去log_buffer和fixed sga其餘內存組件通常默認大小爲零。

經過ASMM用戶僅須要設置一個sga_target參數,其餘參數都將由ASMM自行內部控制。但若是用戶依舊設置瞭如db_cache_size、java_pool_size等參數,那麼這些參數被認爲是相關內存組件的最小限制,同時每一個內存組件的大小也存在一個最大上限(內部的)。在實例啓動階段,Oracle會將必要的內存顆粒(granule,當SGA<1GB時granule大小爲4M,當SGA>1GB時granule大小爲16M)分配給內存組件,多餘沒有分配出去的全都分配給buffer cache,以後隨着系統的不斷活躍更多的內存顆粒(granule)將被分配給急需內存的組件。咱們能夠動態地修改sga_target參數,前提是所在的系統平臺支持動態地共享內存(dism,主流平臺都支持)。使用ASMM的一個必要條件是初始化參數statistics_level必須設置爲typical或ALL,若是設置爲BASIC那麼MMON後臺進程(Memory Monitor is a background process that gathers memory statistics (snapshots) stores this information in the AWR (automatic workload repository). MMON is also responsible for issuing alerts for metrics that exceed their thresholds)將沒法有效分析內存的使用的統計信息從而驅動ASMM的自動調優,實際上咱們不能同時設置sga_target爲非零值和statistics_level爲BASIC:

SQL> show parameter sga

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

SQL> show parameter sga_target

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

SQL> alter system set statistics_level=BASIC;
alter system set statistics_level=BASIC
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00830: cannot set statistics_level to BASIC with auto-tune SGA enabled

若是使用了server parameter file即spfile的話,ASMM會在實例shutdown以前將當前實際的內存組件大小(Oracle認爲這是最優的,但實際上可能不是)保存到spfile中,若是你使用strings命令打印過spfile的內容的能夠發現一些以雙下劃線開頭的參數,如:

G10R2.__db_cache_size=973078528
G10R2.__java_pool_size=16777216
G10R2.__large_pool_size=16777216
G10R2.__shared_pool_size=1006632960
G10R2.__streams_pool_size=67108864

這些在spfile保存的組件大小會在下次啓動時被沿用,以達到將已經實踐得出的」最佳值」記住的目的,這樣下次就不用從頭再」學習」了。

在ASMM的內存交換模型中存在三類組件

  1. 可調優組件(tunable):可調優組件是那些大小能夠隨之變化且若太小僅損害少許性能。buffer cache就是一個經典的例子,cache太小的狀況下應用程序仍能正常運行,但帶來的代價是更多的 IO。注意可調優組件同時存在一個下限。舉例來講共享池由庫緩存Library cache和其餘一些 subheap子堆組成,那麼共享池就存在一個下限要保證至少能放下某個一個時刻並行打開的遊標(open cursors)以及負擔其餘共享池client的運行時內存分配需求。相似的buffer cache也存在一個下限,該下限至少要大於並行被pin住的buffer的總和(雖然這部分很小)
  2. 不可調組件(Un-tunable):不可調組件是那些存在最小下限的內存組件,這個最小下限足夠讓應用程序正常運行,超過這個上限並不會帶來額外的性能收益。在這類組件中large pool是一個典型。
  3. 固定大小組件(Fixed Size):自動調優框架以外的組件,通常爲固定大小。這些組件的大小僅在手動調整時改變。例如非標準塊大小的高速緩衝池


內存交換模型中內存大小調整的申請(memory resize request)存在三種不一樣的模式,它們分別是:

當即內存申請(Immediate Request):這種申請模式通常出如今ASMM管理的某個自動調優組件在沒法分配到連續可用內存塊(chunk)時,爲了不出現OUT-OF-MEMORY(ORA-04031)的錯誤,系統嘗試從其餘候選組件中轉移一個內存顆粒(granule)過來。須要注意的是當前可能沒有可用的全空granule,這時就會出現不完整的轉移,在此情形下系統會開始從候選組件中清理內存顆粒以知足內存申請,並將一個granule不完整地轉移給急需內存的組件。

延遲內存申請(Deferred Request):這種申請通常出如今系統認爲存在一種更爲合理的內存分配時,考慮在組件之間轉移一個或多個granule。用以斷定最佳內存分配的依據是MMON進程所提供的統計信息delta.

手動內存申請(Manual Request):這種申請僅發生在用戶使用alter system命令手動調整內存組件的大小時。在這種模式下僅容許使用空的內存顆粒參與大小調整。若是當時沒有足夠的空granule,那麼針對組件grow操做會返回ORA-4033錯誤,而針對組件shrink操做會返回ORA-4034錯誤。

當ASMM被啓用後,內存代理(Memory Broker)按期執行上圖所示的活動。以上操做都處於延遲內存申請模式下(Deferred)。其目的是經過自動化的做業來調優自動調優組件(auto-tunable component)的大小以適應不斷改變的工做負載,將內存分配到最須要它們的地方。MMON輔助進程會在後臺不斷將統計信息和內存建議按期地捕獲到循環使用的內存中,並計算不一樣時期緩存信息之間的差值;MMON還會基於Memory Broker的策略分析這些差值並估算出長期和短時間內的趨勢。最後MMON基於以上分析生成一些內存組件的大小調整決議並將相應的申請發送到一個系統申請隊列中(resize request system queue)。MMAN後臺進程(Memory Manager is a background process that manages the dynamic resizing of SGA memory areas as the workload increases or decreases)會按期掃描系統申請隊列並執行內存轉移。

在10gR1中Shared Pool的shrink收縮操做存在一些缺陷,形成缺陷的緣由是在該版本中Buffer Cache尚未能力共享使用一個granule,這是由於Buffer Cache的granule的尾部由granule header和Metadata(多是buffer header或者RAC中的Lock Elements)拼接組成,在其尾部不允許存在空洞。另外一個緣由是當時的shared pool容許不一樣生命週期duration(之後會介紹)的chunk存放在同一個granule中,這形成共享池沒法徹底釋放granule。到10gR2中經過對Buffer Cache Granule結構的修改容許在granule header和buffer及Metadata(buffer header或LE)存在縫隙,同時shared pool中不一樣duration的chunk將不在共享同一個granule,經過以上改進buffer cache與shared pool間的內存交換變得可行。此外在10gr2中streams pool也開始支持內存交換(實際根據不一樣的streams pool duration存在限制)

當某個組件扮演捐獻者(Donor,下面的trace中會看到)角色時,它可能將一個不完整granule轉移給buffer cache,那麼在該granule被使用前須要完成如下步驟:

  1. 首先在該granule的尾部生成新的granule header
  2. 針對剩下的chunk斷定在該granule中是否還有未使用的buffer header
  3. 若是有,那麼將chunk中的內存轉換爲一個數據塊。不然將之轉換爲一個metadata塊
  4. 重複以2-4步驟,直到該granule被轉換完

接着咱們來了解一下內存轉移的基本原理,當將buffer cache中的granule轉移給shared pool時,將按照如下步驟:

  1. MMAN後臺進程找到一塊屬於buffer cache的合適granule
  2. MMAN將看中的granule置入quiesce列表中(Moving 1 granule from inuse to quiesce list of DEFAULT buffer cache for an immediate req)
  3. DBWR將負責寫出置入quiesced列表中granule裏面的髒buffer(dirty buffer)
  4. MMAN將爲shared pool調用消費回調函數(consume callback),granule中free的chunk都會被shared pool消費(consume)掉,並對共享池新的內存分配可用。從這裏開始該granule變成一個shared granule共享內存顆粒,注意不要認爲這個時候該granule的空間所有屬於共享池了,實際上有部分pin住的buffer及其Metadata(上述的buffer header和LE)的空間仍被buffer cache佔用着
  5. 最終該granule將完整的轉移給shared pool,這時此granule再也不是一個shared共享的

實際使用中ASMM受到衆多隱藏參數的影響,其中比較主要的參數有:

  1. _enabled_shared_pool_duration:該參數控制是否啓用10g中特有的shared pool duration特性,當咱們設置sga_target爲0時該參數爲false;同時在10.2.0.5前若cursor_space_for_time設置爲true時該參數也爲false,不過在10.2.0.5之後cursor_space_for_time參數被廢棄
  2. _memory_broker_shrink_heaps:若該參數設置爲0那麼Oracle不會去收縮shared pool或java pool,當該參數大於0,會在shrink request失敗後等待該參數指定秒數時間後再次申請
  3. _memory_management_tracing: 該參數控制針對MMON和MMAN後臺進程包括內存建議(advisor)和內存代理(Memory Broker)決議的相關trace的級別;針對ORA-04031的診斷能夠設置爲36,設置爲8啓用針對啓動期間組件大小的trace,設置爲23啓動針對Memory Broker decision的跟蹤,設置爲32將轉儲cache resize的細節;該參數的具體級別以下:
Level Contents
0x01 Enables statistics tracing
0x02 Enables policy tracing
0x04 Enables transfer of granules tracing
0x08 Enables startup tracing
0x10 Enables tuning tracing
0x20 Enables cache tracing


接下來咱們經過設置_memory_management_tracing隱藏參數和DUMP_TRANSFER_OPS轉儲來實地瞭解一次完整的內存轉移,和不完整的內存轉移。如下演示的完整trace文件能夠從這裏下載mman_trace、transfer_ops_dump。

SQL> alter system set "_memory_management_tracing"=63;
System altered Operation make shared pool grow and buffer cache shrink!!!..............

如下爲一個完整granule轉移的過程,包括了對default buffer pool的resize操做:

AUTO SGA: Request 0xdc9c2628 after pre-processing, ret=0

/* 這裏的0xdc9c2628是前臺進程的addr */

AUTO SGA: IMMEDIATE, FG request 0xdc9c2628

/* 這裏能夠看到前臺進程的Immediate當即申請  */

AUTO SGA: Receiver of memory is shared pool, size=16, state=3, flg=0

/* 這次申請的收益人是shared pool,共享池,其大小爲16個granule,處於grow狀態 */

AUTO SGA: Donor of memory is DEFAULT buffer cache, size=106, state=4, flg=0

/* 此處的捐獻者是Default buffer cache,高速緩存,其大小爲106個granule,處於shrink狀態 */

AUTO SGA: Memory requested=3896, remaining=3896

/* 這裏immeidate request所要求的空間是3896 bytes */

AUTO SGA: Memory received=0, minreq=3896, gransz=16777216

/* 這裏沒有free的granule,因此received爲0,gransz爲granule的大小 */

AUTO SGA: Request 0xdc9c2628 status is INACTIVE

/* 由於沒有空的內存顆粒,先將申請置於inactive狀態 */

AUTO SGA: Init bef rsz for request 0xdc9c2628

/* 爲相關申請初始化before-process大小調整  */

AUTO SGA: Set rq dc9c2628 status to PENDING

/* 將request置於pending狀態 */

AUTO SGA: 0xca000000 rem=3896, rcvd=16777216, 105, 16777216, 17

/* 返回起始地址爲0xca000000的16M大小granule */

AUTO SGA: Returning 4 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 4, 1, a
AUTO SGA: Resize done for pool DEFAULT, 8192

/* 完成對default pool的resize */

AUTO SGA: Init aft rsz for request 0xdc9c2628
AUTO SGA: Request 0xdc9c2628 after processing
AUTO SGA: IMMEDIATE, FG request 0x7fff917964a0
AUTO SGA: Receiver of memory is shared pool, size=17, state=0, flg=0
AUTO SGA: Donor of memory is DEFAULT buffer cache, size=105, state=0, flg=0
AUTO SGA: Memory requested=3896, remaining=0
AUTO SGA: Memory received=16777216, minreq=3896, gransz=16777216
AUTO SGA: Request 0x7fff917964a0 status is COMPLETE

/* shared pool成功收到16M的granule */

AUTO SGA: activated granule 0xca000000 of shared pool

如下爲一個partial granule不徹底內存顆粒的轉移過程trace:

AUTO SGA: Request 0xdc9c2628 after pre-processing, ret=0
AUTO SGA: IMMEDIATE, FG request 0xdc9c2628

AUTO SGA: Receiver of memory is shared pool, size=82, state=3, flg=1
AUTO SGA: Donor of memory is DEFAULT buffer cache, size=36, state=4, flg=1

/* 此處的受益者仍爲shared pool,而捐獻者是default buffer cache */

AUTO SGA: Memory requested=4120, remaining=4120
AUTO SGA: Memory received=0, minreq=4120, gransz=16777216
AUTO SGA: Request 0xdc9c2628 status is INACTIVE
AUTO SGA: Init bef rsz for request 0xdc9c2628
AUTO SGA: Set rq dc9c2628 status to PENDING
AUTO SGA: Moving granule 0x93000000 of DEFAULT buffer cache to activate list
AUTO SGA: Moving 1 granule 0x8c000000 from inuse to quiesce list of DEFAULT buffer cache for an immediate req

/* 以上將buffer cache中起始地址爲0x8c000000的granule從使用中列表inuse list,
    移動到靜默列表quiesce list中 */

AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: activated granule 0x93000000 of DEFAULT buffer cache
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000

/ * 等待dbwr寫出0x8c000000 granule中全部的dirty buffer */

AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
......................................... AUTO SGA: Rcv shared pool consuming 8192 from 0x8c000000 in granule 0x8c000000; owner is DEFAULT buffer cache AUTO SGA: Rcv shared pool consuming 90112 from 0x8c002000 in granule 0x8c000000; owner is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 24576 from 0x8c01a000 in granule 0x8c000000; owner is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 65536 from 0x8c022000 in granule 0x8c000000; owner is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 131072 from 0x8c034000 in granule 0x8c000000; owner is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 286720 from 0x8c056000 in granule 0x8c000000; owner is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 98304 from 0x8c09e000 in granule 0x8c000000; owner is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 106496 from 0x8c0b8000 in granule 0x8c000000; owner is DEFAULT buffer cache
.....................

/* 以上shared pool開始消費0x8c000000 granule中的chunk,
    但此granule的owner暫時仍爲default buffer cache */

AUTO SGA: Imm xfer 0x8c000000 from quiesce list of DEFAULT buffer cache to partial inuse list of shared pool

/* 以上將0x8c000000 granule從default buffer cache的靜默列表轉移到shared pool的不完整inuse list */

AUTO SGA: Returning 4 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 4, 1, 20a
AUTO SGA: Init aft rsz for request 0xdc9c2628
AUTO SGA: Request 0xdc9c2628 after processing
AUTO SGA: IMMEDIATE, FG request 0x7fffe9bcd0e0
AUTO SGA: Receiver of memory is shared pool, size=83, state=0, flg=1
AUTO SGA: Donor of memory is DEFAULT buffer cache, size=35, state=0, flg=1
AUTO SGA: Memory requested=4120, remaining=0
AUTO SGA: Memory received=14934016, minreq=4120, gransz=16777216
AUTO SGA: Request 0x7fffe9bcd0e0 status is COMPLETE

/* 以上一個partial transfer完成 */

對應於以上partial transfer咱們能夠經過DUMP_TRANSFER_OPS來了解該0x8c000000 partial granule的實際使用狀況,如:

SQL> oradebug setmypid;
Statement processed.

SQL> oradebug dump DUMP_TRANSFER_OPS 1;
Statement processed.

SQL> oradebug tracefile_name;
/s01/admin/G10R2/udump/g10r2_ora_21482.trc

=======================trace content==============================

GRANULE SIZE is 16777216
COMPONENT NAME : shared pool
Number of granules in partially inuse list (listid 4) is 23
Granule addr is 0x8c000000 Granule owner is DEFAULT buffer cache

/* 該0x8c000000 granule在shared pool的partially inuse list,
    但這裏它的owner仍爲default buffer cache */

Granule 0x8c000000 dump from owner perspective
gptr = 0x8c000000, num buf hdrs = 1989, num buffers = 156, ghdr = 0x8cffe000

/ * 能夠看到該granule的granule header地址位於0x8cffe000,
     其中共有156個buffer block,1989個buffer header */

/* 如下granule中具體的內容,實際既包含了buffer cache也有shared pool chunk */

BH:0x8cf76018 BA:(nil) st:11 flg:20000
BH:0x8cf76128 BA:(nil) st:11 flg:20000
BH:0x8cf76238 BA:(nil) st:11 flg:20000
BH:0x8cf76348 BA:(nil) st:11 flg:20000
BH:0x8cf76458 BA:(nil) st:11 flg:20000
BH:0x8cf76568 BA:(nil) st:11 flg:20000
BH:0x8cf76678 BA:(nil) st:11 flg:20000
BH:0x8cf76788 BA:(nil) st:11 flg:20000
BH:0x8cf76898 BA:(nil) st:11 flg:20000
BH:0x8cf769a8 BA:(nil) st:11 flg:20000
BH:0x8cf76ab8 BA:(nil) st:11 flg:20000
BH:0x8cf76bc8 BA:(nil) st:11 flg:20000
BH:0x8cf76cd8 BA:0x8c018000 st:1 flg:622202
...............

Address 0x8cf30000 to 0x8cf74000 not in cache
Address 0x8cf74000 to 0x8d000000 in cache
Granule 0x8c000000 dump from receivers perspective
Dumping layout

Address 0x8c000000 to 0x8c018000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c018000 to 0x8c01a000 not in this pool
Address 0x8c01a000 to 0x8c020000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c020000 to 0x8c022000 not in this pool
Address 0x8c022000 to 0x8c032000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c032000 to 0x8c034000 not in this pool
Address 0x8c034000 to 0x8c054000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c054000 to 0x8c056000 not in this pool
Address 0x8c056000 to 0x8c09c000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c09c000 to 0x8c09e000 not in this pool
Address 0x8c09e000 to 0x8c0b6000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c0b6000 to 0x8c0b8000 not in this pool
Address 0x8c0b8000 to 0x8c0d2000 in sga heap(1,3) (idx=1, dur=4)

以上能夠看到該granule真的是一個shared granule共享內存顆粒,其中不只包含了部分buffer block,還包含了1號shared subpool共享池子池的durtaion爲4的chunk,duration=4即execution duration;這類duration的chunk通常有着較短的生命週期,當其extent被置於quiesce list靜默列表時將頗有可能變得足夠free。execution duration是共享池中惟一能可靠轉移的,所以惟有該類duration所在的extent(通常來講一個extent佔用一個granule)能夠用來收縮。

如下咱們列出一些有助於診斷ASMM問題的動態性能視圖,僅供參考:

V$SGAINFO
Displays summary information about the system global area (SGA).

V$SGA
Displays size information about the SGA, including the sizes of different SGA components, the granule size, and free memory.

V$SGASTAT
Displays detailed information about the SGA.

V$SGA_DYNAMIC_COMPONENTS
Displays information about the dynamic SGA components. This view summarizes information based on all completed SGA resize operations since instance startup.

V$SGA_DYNAMIC_FREE_MEMORY
Displays information about the amount of SGA memory available for future dynamic SGA resize operations.

V$SGA_RESIZE_OPS
Displays information about the last 400 completed SGA resize operations.

V$SGA_CURRENT_RESIZE_OPS
Displays information about SGA resize operations that are currently in progress. A resize operation is an enlargement or reduction of a dynamic SGA component.

V$SGA_TARGET_ADVICE
Displays information that helps you tune SGA_TARGET.

近期內會寫一篇介紹shared pool duration的文章,做爲對這篇的補充。






SGA and PGA Management in 11g's Automatic Memory Management (AMM) (文檔 ID 1392549.1)

In this Document


Purpose

Scope

Details
  Mandatory parameters for AMM
  Optional parameters for AMM
  How to control the memory under MEMORY_TARGET?
  Give MMAN complete control
  Take control of memory yourself
  AMM details
  CASE 1: Only MEMORY_TARGET is set
  CASE 2: MEMORY_TARGET, SGA_TARGET and PGA_AGGREGATE_TARGET are set
  CASE 3: MEMORY_TARGET, SGA_MAX_SIZE, SGA_TARGET and PGA_AGGREGATE_TARGET are set
  Summary of case studies
  ORA-4030 and ORA-4031


APPLIES TO:

Oracle Database - Enterprise Edition - Version 11.1.0.6 and later
Information in this document applies to any platform.
***Checked for relevance on 01-Apr-2016***

PURPOSE

The purpose of this document is to demonstrate how Automatic Memory Management (AMM) manages memory in the SGA and PGA.

SCOPE

The intended audience of this document is experienced Database Administrators and Oracle Support engineers interested in Automatic Memory Management.

DETAILS

Automatic Memory Management (hereafter called AMM) is introduced in Oracle 11g to automatically manage both the SGA and PGA for a database instance. It is an extension of Automatic Shared Memory Management (ASMM) which was introduced in Oracle 10g, which manages the SGA only.

The significant instance parameters used by AMM are:

  • MEMORY_MAX_TARGET
  • MEMORY_TARGET
  • SGA_MAX_SIZE
  • SGA_TARGET
  • PGA_AGGREGATE_TARGET

AMM functionality is implemented by the Memory Manager process (hereafter called MMAN).

   

Mandatory parameters for AMM

AMM is enabled by the use of EITHER of these parameters:

  • MEMORY_TARGET - defines the outer limits to which the sum of the SGA and PGA can grow.
  • MEMORY_MAX_TARGET - defines the outer limit to which the MEMORY_TARGET can be manually, dynamically, extended (i.e. without a database restart).


Example:      

If MEMORY_MAX_TARGET is set to 1400M, and MEMORY_TARGET is set to 1000M, only the 1000M is available to the instance. The remaining 400M is held in reserve, but locked by Oracle (MMAN). However, because MEMORY_MAX_TARGET is explicitly set, it now becomes possible to dynamically resize MEMORY_TARGET without a database restart.      
                
     

SQL> alter system set memory_target = 1400M;      

          
If MEMORY_MAX_TARGET is the same as MEMORY_TARGET, or if it is not explicitly set, this dynamic increase would not be possible and a instance restart would be required.


Regardless of the Operating System used, when the instance starts up, an amount of memory equal to MEMORY_MAX_TARGET will be locked by MMAN.

MEMORY_MAX_TARGET will always be set, either explicitly in the parameter file, or implicitly by the MMAN background process and will always define the memory locked by the database instance. If MEMORY_MAX_TARGET is not set in the parameter file, it defaults to MEMORY_TARGET.

   

Optional parameters for AMM

All SGA memory parameters can be set in an AMM environment. If no SGA memory parameters are set, MMAN defaults in the following ratio:

60% to SGA_TARGET      
40% to PGA_AGGREGATE_TARGET


Let's look at the following parameters:

  • SGA_MAX_SIZE: this parameter sets the upper limits of the SGA within MEMORY_TARGET
  • SGA_TARGET: this parameter sets the lower limits for the SGA within MEMORY_TARGET
  • PGA_AGGREGATE_TARGET: this parameter is just a target for the total private memory the instance will allow for all processes. In AMM, this is a movable target and will slide up ad down as free space in MEMORY_TARGET is available and as the processing needs change.


The sum of SGA and 'used' PGA cannot exceed MEMORY_TARGET. The exception is PL/SQL collections (such as VARRAYs and other collection types) which will not honor the PGA_AGGREGATE_TARGET, but will continue to consume memory as long as more memory is requested by the procedure, and more memory is available on the server. This is memory in excess of MEMORY_MAX_TARGET.

If SGA_TARGET is explicitly set in the parameter file, it becomes the lower limit (minimum size) for the SGA. The PGA_AGGREGATE_TARGET will always get an amount of memory equal to MEMORY_TARGET - SGA_TARGET.

   

How to control the memory under MEMORY_TARGET?

There are some options available to the Database Administrator to determine how memory is allocated to the various memory components.

   

Give MMAN complete control

You can consider MEMORY_TARGET as one big area of memory for MMAN to use. When you set no other parameters than MEMORY_TARGET, you give MMAN complete control of the area. MMAN divides this area in a ratio or 60% to SGA and 40% to PGA. But these are only initial settings, and MMAN will freely move memory between the two areas depending on memory pressures. Within the 60%, MMAN will resize the SGA components as it did under ASMM, but the difference is MMAN will now increase SGA_TARGET if the SGA is in need of more memory. Under ASMM, SGA_TARGET, once breached, would give a ORA-4031.

   

Take control of memory yourself

Recall that MEMORY_TARGET manages both SGA and PGA memory - and without limitations, MMAN will freely move memory back and forth between the two. If you wish to constrain aggressive PGA growth, set SGA_TARGET in the parameter file, and this now becomes a minimum size for the SGA. In this case PGA growth cannot shrink the SGA beyond this size.

If you want to constrain aggressive SGA growth, set SGA_MAX_SIZE in the parameter file, and this becomes the ceiling for the SGA. An amount of memory equal to SGA_MAX_SIZE is carved out of MEMORY_TARGET, and the SGA must fit within it. This limits the amount SGA can grow to.

Any of the SGA components can be set if you wish to make sure you have a certain minimum amount of memory for that component. The significant SGA components are:

  • the shared pool (managed by the SHARED_POOL_SIZE instance parameter)
  • the buffer cache (managed by the DB_CACHE_SIZE instance parameter)
  • the Streams pool (managed by the STREAMS_POOL_SIZE instance parameter)
  • the Java pool (managed by the JAVA_POOL_SIZE instance parameter)
  • the large pool (managed by the LARGE_POOL_SIZE instance parameter)

If you wish to make any component larger (e.g. the buffer cache in order to maximize transaction throughput and minimize I/O), set the corresponding component parameter (DB_CACHE_SIZE for the example given) to the value you require. But remember, the new component size has to fit within the SGA_TARGET along with all other pools. So either MMAN will adjust SGA_TARGET to a larger value in case you did not set SGA_TARGET explicitly, or, you will have to reset SGA_TARGET manually to a larger value to accommodate for the component enlargement.

   

AMM details

One of the most significant changes of AMM, is that memory that was originally shared (SGA), can be released, and used by the Operating system for private memory (PGA). The reverse is also true: memory that was private to a process, can be released and used as shared memory. This movement of memory is contained within MEMORY_TARGET and managed by MMAN.

There are some important consequences of this. On a system with many large SQL statements, for example parallel executions, processes often do large sorts and table joins. These operations are memory intensive, and can consume a lot of the free memory under MEMORY_TARGET. As more of these processes start up, and need more private memory, MMAN will turn to the SGA in an attempt to reallocate shared memory as private memory.

Under the covers, if the PGA needs more memory, MMAN will run through the SGA free lists looking for memory chunks that are not currently in use. MMAN coalesces these free chunks, until it creates one contiguous chunk that is the size of a granule. The granule is then unlocked from the SGA, and put back in circulation for the OS to use as private memory for the PGA. Various Operating System functions are invoked to unlock the shared memory and return it to the O/S. These memory lock and unlock routines may differ by hardware platform. Running truss (or any similar utility) may show the O/S routines being used:

On UNIX, freeing memory from the SGA shows like the following in a truss output:      
...
18039: munlock(0xc0000009c0000000, 16777216)                  <== this is the granule size (16M)
18039: madvise(0xc0000009c0000000, 0x1000000, MADV_DONTNEED)  <== this is the command to free the granule
18039: munlock(0xc0000009c1000000, 16777216)
18039: madvise(0xc0000009c1000000, 0x1000000, MADV_DONTNEED)
18039: munlock(0xc0000009c2000000, 16777216)
18039: madvise(0xc0000009c2000000, 0x1000000, MADV_DONTNEED)
...  

The number of the freed granules will directly correspond to the amount of memory being freed. For example, if the SGA_TARGET=4G and the granule size is 16M, and you reduce SGA_TARGET to 2G, you can use this command:      

SQL> alter system set SGA_TARGET=2G;      

The number of granules freed will be 2048M/16M = 128. So the truss report will show 128 calls to the OS routines munlock() and madvise(MADV_DONT_NEED). When the memory is freed (unmapped) it is now free for the O/S to reallocate.      

The same process occurs during a resize operation that was initiated by MMAN, instead of the manual resize shown above.


If you consider that the memory eligible for PGA is approximately MEMORY_TARGET minus the SGA_TARGET, it becomes desirable to put a lower limit on SGA_TARGET. This prevents the PGA from taking too much memory from the SGA. The lower limit is set when the parameter file contains a value for SGA_TARGET. Without this setting, MMAN will continue to try to take any available memory from the SGA, as long as that memory is not currently in use (pinned).

On Linux the behavior of AMM can be demonstrated easily; when AMM is in use on Linux, the entire amount of MEMORY_TARGET creates /dev/shm segments when the instance starts up. This is visible if you run the following command:

$ ls -l /dev/shm | grep $ORACLE_SID


Note: these /dev/shm segments disappear if MEMORY_TARGET is not set, and MMAN reverts to using only the normal shared segments (visible by the ipcs -ma command).


For the SGA portion of MEMORY_TARGET, there is an equivalent amount of /dev/shm segments created. This appears as /dev/shm segments each the size of 1 granule. The PGA (or free memory) portion of memory_target appears as /dev/shm segments of 0 length.

For example, if MEMORY_MAX_TARGET=1G, the granule size is 4M, and there would be 256 /dev/shm segments created (256 * 4M = 1G). If there are no other memory parameters set, the initial SGA size will be 612M (60% of MEMORY_TARGET) and the initial PGA will be 412M (40% of MEMORY_TARGET). So there would be 153 /dev/shm segments with size of 4M (153 * 4M = 612M). The remaining /dev/shm segments will be zero length and represent free memory. These allocation can be seen if you query the V$SGAINFO fixed table. See the case studies that follow:

Example:      
If the database name is testdb, the command would be:      
$ ls -l /dev/shm | grep -i testdb  

which results in:      
-rw-r----- 1 oracle oracle 4194304 Aug 25 09:19 ora_testdb_327688_0    <== these are shared memory segments used by SGA (each = 1 granule = 4M)
-rw-r----- 1 oracle oracle 4194304 Aug 25 09:19 ora_testdb_327688_1
-rw-r----- 1 oracle oracle 4194304 Aug 25 09:19 ora_testdb_327688_10
-rw-r----- 1 oracle oracle 4194304 Aug 25 09:19 ora_testdb_327688_100
-rw-r----- 1 oracle oracle 4194304 Aug 25 09:19 ora_testdb_327688_101
-rw-r----- 1 oracle oracle 4194304 Aug 25 09:19 ora_testdb_327688_102
...
-rw-r----- 1 oracle oracle 0 Aug 25 09:19 ora_testdb_327688_95    <== These segments with 0 length are free segments which can be (re)used by the O/S
-rw-r----- 1 oracle oracle 0 Aug 25 09:19 ora_testdb_327688_96
-rw-r----- 1 oracle oracle 0 Aug 25 09:19 ora_testdb_327688_97
-rw-r----- 1 oracle oracle 0 Aug 25 09:19 ora_testdb_327688_98
-rw-r----- 1 oracle oracle 0 Aug 25 09:19 ora_testdb_327688_99    


If you dynamically resize the SGA (using an ALTER SYSTEM SET SGA_TARGET command), you will not see an immediate change in the number of /dev/shm segments, nor in V$SGAINFO. The changes will only occur when memory pressures dictate that the SGA or PGA needs to give up memory.

As the database instance matures and workloads differ, these values will all change. If SGA grows, the number of /dev/shm segments of size 1 granule will increase with a corresponding decrease in the number of /dev/shm segments of 0 length.

For other platforms, the O/S mechanism for moving shared memory between SGA and PGA is different, and will not be discussed here.

Perhaps the best way to show the memory management is by means of examples, and this document will show a few cases below.

   

CASE 1: Only MEMORY_TARGET is set

The following instance parameters are set:

  • MEMORY_TARGET=1G

In this case MEMORY_MAX_TARGET is not set, so it defaults to MEMORY_TARGET.

The following SQL statements highlight what is happening:

SQL> select * from v$sgainfo where name like 'Maximum SGA%' or name like 'Free SGA%';

NAME                                  BYTES RES
-------------------------------- ---------- ---
Maximum SGA Size                 1068937216 No
Free SGA Memory Available         432013312

SQL> select component,current_size from v$memory_dynamic_components where component like '%Target%';

COMPONENT                           CURRENT_SIZE
----------------------------------- ------------
SGA Target                             641728512
PGA Target                             432013312    


Summary:

  1. Initially all memory (1GB) is assigned to shared memory. Here V$SGAINFO shows that 'Maximum SGA size' is 1GB. This is because SGA_MAX_SIZE is unset, and therefore defaults to MEMORY_TARGET.
  2. V$SGAINFO also shows that 412M is free memory. This free memory can be used either for the PGA, or for resizing the SGA.
  3. The initial ratio of memory allocation is 60% to SGA, 40% to PGA. This is the default if neither SGA_TARGET nor PGA_AGGREGATE_TARGET is set. This means, of the 1GB of MEMORY_TARGET, SGA got 60% (612M) and free memory was 40% (412M).
  4. The V$MEMORY_DYNAMIC_COMPONENTS output shows SGA_TARGET was set to 612M and PGA_AGGREGATE_TARGET was set to 412M. The PGA_AGGREGATE_TARGET value of 412M does not mean there is already 412M of PGA, only that there is enough free memory for it to grow to 412M. If it needs to grow beyond 412M, MMAN will request memory from the SGA.
Component Value in the parameter file MMAN assigned value
MEMORY_TARGET 1024M 1024M
SGA_MAX_SIZE not set 1024M
SGA_TARGET not set 612M (60% of MEMORY_TARGET)
PGA_AGGREGATE_TARGET not set 412M (40% of MEMORY_TARGET)


   

CASE 2: MEMORY_TARGET, SGA_TARGET and PGA_AGGREGATE_TARGET are set

The following instance parameters are set:

  • MEMORY_TARGET=1G
  • SGA_TARGET=300M
  • PGA_AGGREGATE_TARGET=100M

In this case MEMORY_MAX_TARGET is not set, so it defaults to MEMORY_TARGET.

The following SQL statements highlight what is happening:

SQL> select * from v$sgainfo where name like 'Maximum SGA%' or name like 'Free SGA%';      

NAME                                  BYTES RES      
-------------------------------- ---------- ---      
Maximum SGA Size                 1068937216 No      
Free SGA Memory Available         759169024      

SQL> select component,current_size from v$memory_dynamic_components where component like '%Target%';      

COMPONENT                           CURRENT_SIZE      
----------------------------------- ------------      
SGA Target                             314572800      
PGA Target                             759169024


Summary:

  1. Initially all memory (1GB) is assigned as shared memory. Here V$SGAINFO shows 'Maximum SGA size' is 1G. This is because SGA_MAX_SIZE is unset, so it defaults to MEMORY_TARGET.
  2. V$SGAINFO also shows that 724M is free memory. This amount is the difference between the MEMORY_TARGET and the SGA_TARGET. This free memory can be used either for the PGA, or for resizing the SGA.
  3. The V$MEMORY_DYNAMIC_COMPONENTS fixed table shows SGA_TARGET was set to 300M as requested, but PGA_AGGREGATE_TARGET was set to 724M, which is the remainder of the MEMORY_TARGET allocation. The PGA_AGGREGATE_TARGET value of 724M does not mean there is already 724M of PGA, only that there is enough free memory to grow to 724M.
  4. Because SGA_MAX_SIZE was defaulted to 1G, in theory, this is also the maximum size of the SGA (if there was no PGA).
Component value is parameter file MMAN assigned value
MEMORY_TARGET 1024M 1024M
SGA_MAX_SIZE not set 1024M
SGA_TARGET 300M 300M
PGA_AGGREGATE_TARGET 100M 724M


   

CASE 3: MEMORY_TARGET, SGA_MAX_SIZE, SGA_TARGET and PGA_AGGREGATE_TARGET are set

The following instance parameters are set:

  • MEMORY_TARGET=1G
  • SGA_MAX_SIZE=500M
  • SGA_TARGET=300M
  • PGA_AGGREGATE_TARGET=100M

In this case MEMORY_MAX_TARGET is not set, so it defaults to MEMORY_TARGET.

The following SQL statements highlight what is happening:

SQL> select * from v$sgainfo where name like 'Maximum SGA%' or name like 'Free SGA%';      

NAME                                  BYTES RES      
-------------------------------- ---------- ---      
Maximum SGA Size                  521936896 No      
Free SGA Memory Available         209715200      

SQL> select component,current_size from v$memory_dynamic_components where component like '%Target%';      

COMPONENT                           CURRENT_SIZE      
----------------------------------- ------------      
SGA Target                             314572800      
PGA Target                             759169024


Summary:

  1. Now that SGA_MAX_SIZE is set to 500M, the memory assigned as shared memory, shows up in V$SGAINFO as 500M under 'Maximum SGA Size'.
  2. The 'Free SGA Memory Available' in V$SGAINFO is the difference between the SGA_MAX_SIZE and SGA_TARGET (500M-300M = 200M).
  3. The memory above SGA_MAX_SIZE (500M) is unavailable to the SGA so never shows up in V$SGAINFO.
  4. The V$MEMORY_DYNAMIC_COMPONENTS fixed table shows the SGA_TARGET is 300M as set in the parameter file, but the PGA_AGGREGATE_TARGET is 724M, which is the difference between MEMORY_TARGET and SGA_TARGET.

    So the PGA has access to the memory above SGA_MAX_SIZE (500M) plus any free memory in the SGA (200M).
Component Value in the parameter file MMAN assigned value
MEMORY_TARGET 1024M 1024M
SGA_MAX_SIZE 500M 500M
SGA_TARGET 300M 300M
PGA_AGGREGATE_TARGET 100M 724M


   

Summary of case studies

The above examples show that:

  • In AMM, shared memory is available for use by both the SGA and PGA.
  • MMAN will lock, unlock, and transfer memory freely between the SGA and the PGA as necessary.
  • The exceptions are:
    • When SGA_MAX_SIZE is set in the parameter file, MMAN will not transfer memory into the SGA that would cause it to exceed this size.
    • When SGA_TARGET is set in the parameter file, MMAN will not transfer any memory out of the sga that will cause it to go below this size.

Note: if MEMORY_MAX_TARGET would have been manually set to a value higher than MEMORY_TARGET the following situation would occur:

  • The 'Maximum SGA Size' value in V$SGAINFO would show the MEMORY_MAX_TARGET value.
  • The 'Free SGA Memory Available' in V$SGAINFO is the difference between the SGA_MAX_SIZE (which defaults to MEMORY_MAX_TARGET)and SGA_TARGET.
  • All other parameters would act the same as described in the cases, as calculations for the initial memory sizes are based on MEMORY_TARGET and not MEMORY_MAX_TARGET.


   

ORA-4030 and ORA-4031

How can the database run out of memory, if it can freely move memory around between SGA and PGA?

Recall that ORA-4030 occurs when there is no more memory for the PGA, and ORA-4031 occurs when there is no more memory for the SGA.

If the SGA allocation is totally consumed, and the PGA (free memory) is totally consumed, then you have run out of memory and either ORA-4030 or ORA-4031 is imminent. This means the MEMORY_TARGET is undersized.

Some things that can initiate memory shortages are limits set on the SGA:

  • If SGA_MAX_SIZE is set, this is an upper limit. If the processing load requires more memory than this, you can get ORA-4031.
  • If SGA_TARGET is set, this is a minimum size for the SGA. If the processing load requires a lot of private memory (PGA), and that memory requirement exceeds MEMORY_TARGET - SGA_TARGET, you can get a ORA-4030. But if the process needing the memory is PL/SQL, it can take additional free memory from the server. However, it is still a good idea to set SGA_TARGET so there is always some memory available for the SGA.

For ORA-4030, there are also O/S limits that come into play. Notably, the 4G limits on 32-bit platforms, and the ulimit soft settings for UNIX type systems which limit the maximum memory a process can access.







"ipcs -m" Displays Incorrect Shared Memory Segment Sizes in Oracle 11G (文檔 ID 731658.1)

In this Document


Symptoms

Cause

Solution


APPLIES TO:

Oracle Database - Enterprise Edition - Version 11.1.0.6 and later
Generic Linux



SYMPTOMS

The "ipcs -m" indicates allocated shared memory segments. In Oracle 11G all of the segments are between 808 and 4096 bytes, where as the instance has a 4GB SGA .Output of ipcs -m:

------ Shared Memory Segments -------- 
key shmid owner perms bytes nattch status 
0x00000000 65536 oracle 660 4096 0 
0xd649823c 98305 oracle 660 4096 0 
0x7905c133 131074 oracle 666 808 0 
0xc90e3f3c 196611 oracle 660 4096 0

CAUSE

When Oracle on Linux is configured to use Auto Memory Management (AMM), it utilizes the POSIX implementation of SHM on Linux. The small shared memory segment just contains some metadata for new processes to find the /dev/shm/* files used for the SGA. POSIX shared memory is not reflected by the ipcs utility. 

When AMM is disabled, Oracle falls back to using the System V SHM implementation as seen in earlier versions of Oracle for Linux.

SOLUTION

1. Use PMAP command. PMAP output shows that Oracle 11g uses /dev/shm for shared memory implementation instead. There are many 4MB files mapped to Oracle server processes address space. The total size shows the MEMORY_TARGET size. If MEMORY_TARGET is set to 0 then the shared memory segments will be displayed by the ipcs command.

 

E.g.:

$pmap 6124 

.. .
20001000 4092K rw-s- /dev/shm/ora_ora11g_19693577_0 
20400000 4096K rw-s- /dev/shm/ora_ora11g_19693577_1 
20800000 4096K rw-s- /dev/shm/ora_ora11g_19693577_2 
20c00000 4096K rw-s- /dev/shm/ora_ora11g_19693577_3 
21000000 4096K rw-s- /dev/shm/ora_ora11g_19693577_4 
...

 

2. /dev/shm also shows the shared memory segments in use for this instance.

 

$ ls -l /dev/shm/ |grep ora11g -rw-r----- 1 oracle oinstall 4194304 Jul 31 10:40 ora_ora11g_19693577_0  -rw-r----- 1 oracle oinstall 4194304 Jul 31 10:40 ora_ora11g_19693577_1  -rw-r----- 1 oracle oinstall 4194304 Jul 31 10:40 ora_ora11g_19693577_177  -rw-r----- 1 oracle oinstall 4194304 Jul 31 10:40 ora_ora11g_19693577_178  -rw-r----- 1 oracle oinstall 4194304 Jul 31 10:40 ora_ora11g_19693577_179

相關文章
相關標籤/搜索