【深入解析--eygle】学习笔记
在Oracle10g之前,你可能面对过这样的情况,你的数据库在白天需要处理大量的OLTP任务,这些任务需要大量的Buffer Cache内存,而在夜间系统可能需要运行大量的并行批处理任务,这些任务又需要大量的Large Pool内存,为了让这样一个系统在有限的资源下高效率运行,可能你需要在各类峰值业务来临之前对数据库进行不断的调整
那么在Oracle10g的自动共享内存管理(Automatic Shared Memory Management-ASMM)下,这些动作不再需要人工介入,当运行OLTP任务时,Buffer Cache会获取大部分内存以达到良好的I/O性能。当系统需要运行DSS批处理任务时,内存会自动转移给Large Pool,以便并行查询等可以获得更多的内存,更快的执行。
Oracle10g使用了一个新的初始化参数SGA_TARGET,通过指定这个参数,让Oracle自动管理SGA中以下大多数的内存分配。SGA_TARGET是个动态参数,但是该参数不能超过SGA_MAX_SIZE参数的设置
11:47:40 sys@felix SQL>show parameter sga
NAME TYPE VALUE
---------------------------------------------------------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 400M
sga_target big integer 0
13:21:25 sys@felix SQL>
如果试图修改SGA_TARGET超越SGA_MAX_SIZE的限制,系统会给出错误信息:
SQL> alter system set sga_target=500M;
alter system set sga_target=500M
*
ERROR at line 1:
ORA-02097: parameter cannot be modified becausespecified value is invalid
ORA-00823:Specified value of sga_target greater than sga_max_size
并非所有SGA组件都可以自动调整,可以自动分配的内存包括 Buffer Cache、Shared Pool、Java Pool、 Large Pool
启用自动共享内存管理,我们可以估算一个 SGA 的总大小,然后设置SGA_TARGET 参数为非零值, Oaracle将启用自动共享内存管理。自动共享内存管理需要STATISTICS_LEVEL参数设置为TYPICAL 或者 ALL.
Oracle服务器根据系统运行的情况自动调整这些内存的大小,并记录在SPFILE中,数据库实例重新启动时,不会丢失之前的调整结果。
但是注意以下相关初始化参数还是需要手工配置的: 非标准BLOCK_SIZE的Cache、Keep/Recycle Buffer Cache、Redo Log Buffer、Streem Pool
如果不想使用自动共享内存管理的新特性,Oracle也允许使用手工管理,只需要简单的将SGA_TARGET参数设置为0,Oracle就会回到手工管理的模式,当前的各内存组件值会被计入spfile,做为手工管理的初始值使用.
随着自动共享内存管理新特性的引入,许多相关参数的使用也发生了改变。当我们从开始就设置了SGA_MAX_SIZE参数,启用了自动共享内存管理之后,相关内存参数值会处于未设置状态:
13:35:01 sys@felix
SQL>select name, value
fromv$parameter
where namein ('large_pool_size',
'java_pool_size',
'shared_pool_size',
'streams_pool_size',
'db_cache_size');
NAME VALUE
------------------------------------------------------------
shared_pool_size 0
large_pool_size 0
java_pool_size 0
streams_pool_size 0
db_cache_size 0
13:35:01 sys@felix SQL>
真正决定各组件大小的,是由一组新引入的参数决定:
SELECT x.ksppinm NAME, y.ksppstvl VALUE,x.ksppdesc describ
FROMSYS.x$ksppi x, SYS.x$ksppcv y
WHEREx.inst_id = USERENV('Instance')
ANDy.inst_id = USERENV('Instance')
ANDx.indx = y.indx
ANDx.ksppinm like '%pool_size%' ;
13:37:18 sys@felix SQL>/
NAME VALUE DESCRIB
------------------------------------------------------------ --------------------------------------------------
_NUMA_pool_size Not specified aggregate size in bytes of NUMA pool
__shared_pool_size 171966464 Actual size in bytes of shared pool
shared_pool_size 0 size in bytes of sharedpool
__large_pool_size 4194304 Actual size in bytes of largepool
large_pool_size 0 size in bytes of large pool
__java_pool_size 4194304 Actual size in bytes of java pool
java_pool_size 0 size in bytes of java pool
__streams_pool_size 8388608 Actual size in bytes of streams pool
streams_pool_size 0 size in bytes of thestreams pool
_io_shared_pool_size 4194304 Size of I/O buffer pool from SGA
_backup_io_pool_size 1048576 memory to reserve from the largepool
__shared_io_pool_size 0 Actual size of shared IOpool
_shared_io_pool_size 0 Size of shared IO pool
global_context_pool_size GlobalApplication Context Pool Size in Bytes
olap_page_pool_size 0 size of the olap page poolin bytes
_trace_pool_size trace pool size in bytes
16 rows selected.
13:37:18 sys@felix SQL>
这些由两个下划线开头的参数决定了当前SGA的分配,也是动态内存管理调整的参数。这些参数的更改会被记录到spfile文件当中,在下一次数据库启动时仍然有效
这是Oracle10g在参数上的一些变化,通过动态视图v$sga_dynamic_components,可以看到各动态组件调整的时间和调整类型等信息
select COMPONENT,
CURRENT_SIZE,
MIN_SIZE,
LAST_OPER_TYPE,
LAST_OPER_MODE,
to_char(LAST_OPER_TIME, 'yyyy-mm-dd hh24:mi:ss') LOT
fromv$sga_dynamic_components
whereLAST_OPER_TIME is not null;
在Oracle11g中,Oracle将内存管理的自动化更进了一步,引入了自动内存管理(AutomaticMemory Management-AMM)的 新 特 性,现 在Oracle将SGA和PGA都纳入了自动管理的范畴。
在Oracle10g中,Oracle对SGA引入了自动管理,相关的参数为SGA_TARGET和SGA_MAX_SIZE;在Oracle9i中,Oracle已经引入了自动的PGA管理,相关的初始化参数为pga_aggregate_target。
Oracle11g引入了一个新的参数MEMORY_TARGET。现在只要设置了这个参数,可以不需要设置SGA_TARGET和PGA_AGGREATE_TARGET两个参数,使用自动内存管理,Oracle数据库将自行决定SGA以及PGA的分配和使用,这极大的简化了DBA对于内存的调整和管理工作。
13:49:44 sys@felix SQL>show parameter memory_target
NAME TYPE VALUE
---------------------------------------------------------- ------------------
memory_target big integer 400M
13:49:54 sys@felix SQL>show parametermemory_max_
NAME TYPE VALUE
---------------------------------------------------------- --------------------
memory_max_target big integer 400M
13:51:47 sys@felix SQL>show parameter pga
NAME TYPE VALUE
---------------------------------------------------------- --------------------
pga_aggregate_target big integer 0
此时PGA和SGA参数可以无需设置:
13:52:14 sys@felix SQL>show parameter sga
NAME TYPE VALUE
---------------------------------------------------------- ---------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 400M
sga_target big integer 0
13:52:22 sys@felix SQL>
当MEMORY_TARGET参数设置超过了系统允许的限制后,会出现ORA-00845错误:
SYS@felix>alter system setmemory_max_target=2048M scope=spfile;
System altered.
SYS@felix>alter system set memory_target=2048Mscope=spfile;
System altered.
SYS@felix>startup force;
ORA-00845: MEMORY_TARGET not supported on this system
这个错误经常使人误解,实际上系统并非不支持MEMORY_TARGET,而是不支持当前的参数设置。检查告警日志文件,在Linux上可以看到如下的ᨀ示信息:
Starting ORACLE instance(normal)
WARNING: You are tryingto use the MEMORY_TARGET feature. This feature requires the /dev/shm filesystem to be mounted for at least 2063597568 bytes. /dev/shm is either notmounted or is mounted with available space less than this size. Please fix thisso that MEMORY_TARGET can work as expected. Current available is 1073741824 andused is 0 bytes. memory_target needs larger /dev/shm
这是因为在Linux的VLM(Very Large Memory)支持中,使用了shmfs/tmpfs选项(另外一种实现方式是使用(ramfs),如果/dev/shm不足够,则会出现如上错误。
检查一下/dev/shm设置:
[root@felix kernel]# df -k /dev/shm
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 510436 261884 248552 52% /dev/shm
[root@felix kernel]#
重新设置和加载一下/dev/shm:
[root@felix kernel]# umount /dev/shm
[root@felix /]# mount -t tmpfs shmfs -o size=3192M/dev/shm
[root@felix /]# df -k /dev/shm
Filesystem 1K-blocks Used Available Use% Mountedon
shmfs 3268608 0 3268608 0% /dev/shm
[root@felix /]# ls -l /dev/shm
total 0
设置完成之后,数据库就可以正常启动。
检查一下现在的shm内存使用:
[oracle@felix admin]$ df -k /dev/shm
Filesystem 1K-blocks Used Available Use% Mountedon
shmfs 3268608 1244436 2024172 39% /dev/shm