Instance实例的作用
实例缓存曾经使用过的数据、减少磁盘IO
一. SGA
SGA管理的变迁
9i前,静态分配,修改完参数,重启数据库才能生效
db_block_buffers db_block_size
...
9i: 动态分配,即不重启数据库,修改可生效
各SGA组件单独指定
sga_max_size
db_cache_size
...
10g: 动态分配,
部分组件统一指定,各大小依据工作负载自动调整
sga_max_sizel
sga_target
pga_aggregate_target
11g: SGA和PGA都纳入了自动内存管理
memory_target
1.SGA组成和任务
sga_max_size
sga_target
db_cache_size
java_pool_size
large_pool_size
shared_pool_size
streams_pool_size
log_buffer
db_keep_cache_size
db_recycle_cache_size
db_nk_cache_size
sga_max_size<物理内存*40%
(sga_max_size+pga_aggregate_target)<物理内存*80%
Automatic Shared Memory Management (ASMM),自动共享内存管理,是10g中新增的特性,主要用来管理SGA中的内存组件,
它针对如下内存组件发挥作用:
Buffer cache池
共享池里还有下面的三个池:
大型池:shared server ,parallel execution ,backup processes for disk I/O buffers
Java池:Java memory manager
流 池:Streams in a database transfers
有一个专门的后台进程MMAN(内存管理),负责完成这项任务。
启用ASMM:
SGA_TARGET>0
STATISTICS_LEVEL=TYPICAL (or ALL)
MMAN进程必须根据工作负载情况,调节各内存组件的大小
ps -ef |grep LH
ora_mman_LH
SELECT name, value
FROM v$parameter
WHERE name in ('db_cache_size', 'large_pool_size', 'java_pool_size',
'shared_pool_size', 'streams_pool_size', 'sga_target',
'sga_max_size', 'statistics_level')
alter system set db_keep_cache_size=12M;
select * from dba_tables where owner='SCOTT'
and table_name='EMP'
alter table EMP storage (buffer_pool keep);
获得该版本的显式参数
select * from v$parameter
259
获得该版本的隐式参数 1127
SELECT a.ksppinm NAME,
b.ksppstvl "value",
a.ksppdesc DESCRIPTION
FROM x$ksppi a,
x$ksppcv b
WHERE a.indx=b.indx
AND substr(a.ksppinm,1,1)='_'
ORDER BY a.ksppinm
select
i.ksppinm name,
i.ksppdesc description,
cv.ksppstvl "value",
cv.ksppstdf isdefault,
decode(bitand(cv.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismodified,
decode(bitand(cv.ksppstvf,2),2,'TRUE','FALSE') isadjusted
from sys.x$ksppi i, sys.x$ksppcv cv
where i.inst_id=userenv('Instance') and
cv.inst_id=userenv('Instance') and
i.indx=cv.indx and
i.ksppinm like '%pool_size%'
alter system set "......"=..... scope=spfile;***********更改隐式参数
内存组件的真正大小:
SELECT name, bytes FROM v$sgainfo;
show sga
固定区域 fixed area
包含几千个变量和一些小的数据结构,
如latch和地址指针等,不受用户控制
通过x$ksmfsv查询 Kernel Service layer,
Memory management,
addresses of Fixed Sga Variables
x$ksmmem记录了整个SGA的地址映射关系.
通过查询 x$ksmfsv和x$ksmmem,可以找出
fixed area 中每个变量的位置.
select * from x$ksmfsv a,x$ksmmem b
where a.ksmfsadr=b.addr
and a.ksmfsnam like 'sga%'
select * from x$ksmfsv a,x$ksmmem b
where a.ksmfsadr=b.addr --3705个 10gR2
variable size
包括 shared_pool_size, java_pool_size,
large_pool_size等
2.转储SGA信息
SGA使用的内存空间
$ ps -ef|grep dbw
oracle 31822 ora_dbw0_LH
$ more /proc/31822/maps
20000000-2de00000 rw-s 十六进制
alter session set events 'immediate trace name heapdump/buffers level n';
level 1: PGA汇总信息
level 2: SGA汇总信息
level 1025: PGA详细信息
level 2050: SGA详细信息
转储db buffer cache 6
cd /opt/oracle/admin/LH/udump
rm *.trc
sqlplus sys/oracle as sysdba
sql>alter session set events 'immediate trace
name buffers level 2'; 2-3minutes
sql>quit
lh_ora_23755.trc 387M
vi lh_ora_23755.trc
(1)buffer cache
granule是9i引入的一个新概念,是连续内存分配的单位,
增加内存大小的步长单位
其大小取决于SGA的大小(SGA_MAX_SIZE):
9i:
如SGA<128MB,则granule=4MB
否则为16MB(32位windows为8MB)
10g:
如SGA<1GB,则granule=4MB
否则为16MB(32位windows为8MB)
一个粒度 granule的大小由隐含参数
_ksmg_granule_size决定
select
i.ksppinm name,
i.ksppdesc description,
cv.ksppstvl "value",
cv.ksppstdf isdefault,
decode(bitand(cv.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismodified,
decode(bitand(cv.ksppstvf,2),2,'TRUE','FALSE') isadjusted
from sys.x$ksppi i, sys.x$ksppcv cv
where i.inst_id=userenv('Instance') and
cv.inst_id=userenv('Instance') and
i.indx=cv.indx and
i.ksppinm = '_ksmg_granule_size'
alter system set "_ksmg_granule_size"=2M scope=spfile;
create pfile from spfile;
各内存组件所使用的 granule大小可以通过查询
v$sga_dynamic_components获得
select t.component,t.granule_size
from v$sga_dynamic_components t
db_cache_size
db_keep_cache_size
db_recycle_cache_size
db_nk_cache_size
在buffer cache中,ORACLE通过几个链表进行内存管理
LRU List
Dirty List (也称Write List) 同时链接到ckptq和fileq
checkpoint queue,CKPTQ 检查点队列
file queue fileq 文件检查点队列
bucket(包含多个buffer)
(在bucket内部,通过Cache buffer chain
(一个双向链表)将
各buffer通过buffer header信息联系起来)
一个bucket,一个Cache buffer chain
buffer cache中 bucket的数量由
_db_block_hash_buckets决定
select
i.ksppinm name,
i.ksppdesc description,
cv.ksppstvl "value",
cv.ksppstdf isdefault,
decode(bitand(cv.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismodified,
decode(bitand(cv.ksppstvf,2),2,'TRUE','FALSE') isadjusted
from sys.x$ksppi i, sys.x$ksppcv cv
where i.inst_id=userenv('Instance') and
cv.inst_id=userenv('Instance') and
i.indx=cv.indx and
i.ksppinm = '_db_block_hash_buckets' (10gR2:32768,in my server)
由于异步和多DBWn的引入,ORACLE引入了一个新的概念
Working Sets(WS)工作集,
在每个WS中包含几个不同功能的list,每个list都通过
cache buffers LRU CHAIN Latch 进行保护,
当使用多个DBWR进程时,数据库会存在多个WS,
数据库中的每个缓冲池default,keep,recycle,
都有各自独立的WS
LRU List 用于维护内存中的buffer,数据库初始化时,
所有的buffer都被hash到LRU List上管理.
当需要从数据文件上读取数据时,首先在LRU List
上寻找FREE的buffer,然后读取数据到buffer cache中;
当数据被修改之后,状态变为dirty,就可以被移动到
dirty list.一个buffer的地址要么存在于LRU List,
要么存在于dirty list.
checkpoint: 检查点
只是一个数据库事件,其意义在于减少崩溃恢复crash recovery时间.
检查点事件会触发CKPT
检查点完成后,记录的SCN,是数据已写入到数据文件后的SCN频度增大,恢复的数据少,但会影响性能
(1)常规检查点conventional checkpoint,也称完全检查点global checkpoint
oracle8之前,把脏数据(dirty list)全部写出到数据文件
(2)增量检查点incremental checkpoint
从oracle8开始,引入检查点队列
checkpoint queue,CKPTQ机制
通过增量检查点,数据库将以前的全量写出
变更为增量渐进写出,
从而极大地减少对数据库性能的影响.
检查点队列在数据库内部通过latch保护
checkpoint queue latch
alter system set log_checkpoints_to_alert=true ;
(3)自动检查点
from 10g,自动检查点调整
当FAST_START_MTTR_TARGET=0时,
自动检查点调整生效:利用系统的低I/O负载时段
写出内存中的脏数据.
如果需要严格控制实例或节点的恢复时间,
则设置FAST_START_MTTR_TARGET,
如果不需要严格控制,
则不设置FAST_START_MTTR_TARGET,
启用10g的自动检查点调整.
db buffer cache
lru list
dirty list (lruw list),同时链接到ckptq和fileq
ckptq
fileq 文件检查点队列 file queue,每个文件包含一个fileq
fileq的引入,提高了表空间检查点
tablespace checkpoint的性能.当对tbs执行offline等操作时,会触发
表空间检查点.
转储db buffer cache
alter session set events
'immediate trace name buffers level 10';
shared pool
from 10g: 增对象检查点队列Object Queue,objq
CKPTQ负责按照数据块的修改顺序记录数据块,
同时将RBA和数据块关联起来,
这样在进行增量检查点时,数据库可以按照
数据块修改的先后顺序将其写出,
从而在进行恢复时,可以根据最后写出的
数据块和相关的RBA(redo byte address)开始进行快速恢复.
在检查点触发时DBWR根据CKPTQ执行写出,
在其他条件触发时,DBWR由dirty list
执行写出.CKPTQ的内存在shared pool中分配,
有latch对其进行保护.
select * from v$sgastat where name like 'Check%'
alter system flush buffer_cache;
(2)shared pool
由chunk组成
shared_pool_size
v$librarycache 库缓存
v$rowcache 字典缓存
11g: shared pool 增加了 result cache memory
存储SQL查询的结果集
shared pool 通过 free list
管理free内存块(chunk),chunk按不同大小被
划分到不同的部分bucket进行管理.
cd /opt/oracle/admin/LH/udump
rm *.trc
sqlplus sys/oracle as sysdba
alter session set events 'immediate trace name
heapdump level 2';
quit
cat lh_ora_6877.trc |grep Bucket |more
观察每个bucket的chunk的大小,单位:字节
shared pool latch: 一种低级锁,通过串行机制
保护共享内存,微妙级
from oracle9i,shared pool可以被分割为多个
子缓冲池subpool,
有独立的free list,内存结构,latch等.
9i, 每个subpool至少128MB
10g,每个subpool至少256MB
11g,每个subpool至少512MB
alter system flush shared_pool;
查看Oracle异步IO是否开启
ldd /opt/oracle/db/bin/oracle |grep libaio
查看linux是否安装了AIO的包rpm -qa |grep aio
从Oracle9iR2开始支持Linux上的异步IO,
但是Oracle9iR2和Oracle10gR1中的AIO模块默认
是disable的,
在Oracle10gR2中AIO默认已经是开启的了。
如果要启用必须relink一下:
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk async_on
--关是async_off
make -f ins_rdbms.mk ioracle
二. PGA
1. UGA(The User Global Area):用户全局区
用户会话数据,
游标:绑定变量、结果集指针、
还有排序区(又称工作区)等
2. CGA (The Call Global Area):调用全局区(会话区)
某段代码被调用期间需要使用的区域。
它是一块动态的内存区域,
随着调用(call)的开始而创建,在调用过程中一直存在,
直到调用结束时被释放。
局部变量和其他一些本地信息
UGA中的信息是到会话关闭时才释放。
CGA还包含一些低层次调用的中间结果,如解析(parse)调用、
执行(executive)调用、
抓取(fetch)调用以及递归SQL调用和PL/SQL调用。
就像抓取,服务器进程从Buffer cache的块中
把行抓取出来,
在最终交给用户前,就暂时放置在CGA中(组读取行缓存)
3. PGA(Program Global Area):程序全局区
在专用服务器方式中,UGA和CGA都在PGA中分配空间,
这时,PGA就是由UGA和CGA构成的。
在共享服务器方式下,UGA会在 large pool 中分配空间
(如果没有配置large pool就在 shared pool 中分配),
此情况下,PGA其实就是CGA。
注意,CGA不象UGA可以位于SGA中(以共享服务器模式连接),
CGA一定是位于PGA中的。
如果当前进程正在运行,则每个PGA中只有一个CGA。
如果当前进程没有运行,则该进程的PGA中就没有CGA。
虽然相关SQL的信息都在UGA中,但相关PL/SQL过程、
函数的信息并不在UGA中。
关于存储过程,它的代码被放在共享池中 ,
只有存储过程中的变量,才存放在PGA中。
这部分用来存放用户进程信息的空间叫做堆栈空间
(堆栈空间是CGA中的重要部分)。
三. 后台进程
oracle:
(1)user processes
(2)oracle server oracle
(3)background processes
CKPT:
工作:
(1)更新控制文件,数据文件头信息,记录检查点
(2)向DBWR布置写数据文件
触发:
(1)日志组切换(自动,手动)
(2)alter system checkpoint;
(3)将tbs->offline,read only,backup
(4)初始化参数
log_checkpoint_interval
log_checkpoint_timeout
fast_start_mttr_target
DBWR:
触发:
(1) db buffer 空间不足
(2)触发了检查点
LGWR:
触发:
(1)每隔3秒
(2)commit,ddl
(3)redo buffer被写满1/3
(4)redo buffer具有1MB脏数据
(5)DBWR要运行
1.7GB SGA
win:
(1)
edit c:\boot.ini
optin /fastdetect/pae
(2)
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb10g_home1
添加一个字符串值项:AWE_WINDOW_MEMORY ,这个值是你准备分配给数据库用的最大内存数(以BYTE为单位),例如你想分配4G,那这个值就是
4*1024*1024*1024
(3)edit initsid.ora
第一注销掉以下行:
sga_max_size
sga_target
DB_CACHE_SIZE
修改或者添加以下参数
*.db_block_buffers=262144 #等于原来的DB_CACHE_SIZE/db_block_size, 例如你希望DB_CACHE_SIZE的大小是2G,则此值是2*1024*1024K/8K= 262144
*.SHARED_POOL_SIZE=419430400 #是以byte为单位的 400M(这个参数设置过大会报错的,因为ORACLE AWE的配置不是针对他的)
*.log_buffer=73400320 #是以byte为单位的 70M(这个参数设置过大会报错的,因为ORACLE AWE的配置不是针对他的)
*.use_indirect_data_buffers=true # 这个参数的含义是我们是通过设置db_block_buffers来计算得到DB_CACHE_SIZE
(4)startup pfile=initsid.ora nomount
create spfile from pfile;
shutdown immediate
startup
2.linux
在32位平台上,缺省的SGA最大只能扩展到1.7G,如果需要支持更大的内存,
就需要降低mapped_base,重新Link Oracle软件.
cd $ORACLE_HOME/rdbms/lib
cp ksms.s ksms.s.bak
genksms -s 0x12000000 > ksms.s
make -f ins_rdbms.mk ksms.o
make -f ins_rdbms.mk ioracle
此处先备份ksms.s文件,如果编译过程中出现错误,保证操作可以被恢复:
恢复步骤大致如下:
cd $ORACLE_HOME/rdbms/lib
cp ksms.s.bak ksms.s (if u have backup ksms.s file)
genksms > ksms.s
make -f ins_rdbms.mk ksms.o
make -f ins_rdbms.mk ioracle
此后数据库可以以超过1.7G的SGA区设置启动