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正在往智能化方向發展。若是咱們如今找一些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開始並無很是大的變化,他們包括:
在9i中還沒有引入ASMM,惟一的選擇是手動管理的SGA,有時候也叫作MSMM。在9i中除去buffer cache的大小能夠手動修改外,其他組件都沒法動態修改。由於缺少一種動態管理的機制,因此在9i中若是有某個內存區域有急用,也沒法從其餘有空閒內存的組件中捐獻一些來解燃眉之急。
手動管理SGA的缺點在於:
ASMM的優點在於:
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的內存交換模型中存在三類組件
內存交換模型中內存大小調整的申請(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被使用前須要完成如下步驟:
接着咱們來了解一下內存轉移的基本原理,當將buffer cache中的granule轉移給shared pool時,將按照如下步驟:
實際使用中ASMM受到衆多隱藏參數的影響,其中比較主要的參數有:
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的文章,做爲對這篇的補充。
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 |
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***
The purpose of this document is to demonstrate how Automatic Memory Management (AMM) manages memory in the SGA and PGA.
The intended audience of this document is experienced Database Administrators and Oracle Support engineers interested in Automatic Memory Management.
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:
AMM functionality is implemented by the Memory Manager process (hereafter called MMAN).
AMM is enabled by the use of EITHER of these parameters:
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.
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:
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.
There are some options available to the Database Administrator to determine how memory is allocated to the various memory components.
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.
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:
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.
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.
The following instance parameters are set:
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:
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) |
The following instance parameters are set:
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:
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 |
The following instance parameters are set:
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:
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 |
The above examples show that:
Note: if MEMORY_MAX_TARGET would have been manually set to a value higher than MEMORY_TARGET the following situation would occur:
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:
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 |
Oracle Database - Enterprise Edition - Version 11.1.0.6 and later
Generic Linux
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
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.
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