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