【内存管理】Oracle sga_target与SGA实际分配大小不一致的延伸学习

在学习Oracle内存结构的时候,发现一个问题:我的虚拟机Oracle环境参数文件中设置的sga_target=960M,但是在启动数据库时候,显示分配的Total System Global Area为1002127360 bytes(955.7M),那么问题就来了,为什么会不一致?相差的4.3M去干什么了?

学习后了解到SGA的分配与粒度(granule)相关,总结下知识。

1.什么是内存粒度

  • 是连续的内存单元(unit of contiguous memory)。
  • SGA分配的最小单位
  • 按granule size的整数倍分配
  • SGA组件,如Shared Pool、buffer cache、java池和其他池,在相同大小的粒度中进行分配和回收
  • redo log buffer和Fixed Size不是按照granule分配

2.粒度的大小

  • 粒度的大小是在实例启动时确定的,它取决于SGA_MAX_SIZE参数的大小
  • 实例启动后,粒度大小不会改变,也就是说粒度大小在实例的生命周期内不变
  • 数据库的粒度大小取决于平台和所分配的SGA总大小,下图显示的是linux下11gR2版本的粒度规则
    image.png
  • 如果你想要一个5MB的Java池,而你的粒度大小为4MB,Oracle实际上会为这个Java池分配8MB
  • 查询granule size大小可以通过以下两个视图查询
select * from  V$SGAINFO;

image.png

select component,current_size/1024/1024 as MB,granule_size from V$SGA_DYNAMIC_COMPONENTS;
  • 粒度大小受内部隐含参数_ksmg_granule_size的控制
--查看隐含参数
col name for a30;
col value for a10;
select 
x.ksppinm  name,
y.ksppstvl  value,
y.ksppstdf  isdefault,
decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE')  ismod,
decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE')  isadj 
from 
sys.x$ksppi x,
sys.x$ksppcv y 
where 
x.inst_id = userenv('Instance') and 
y.inst_id = userenv('Instance') and 
x.indx = y.indx and x.ksppinm ='_ksmg_granule_size' 
order by 
translate(x.ksppinm, ' _', ' ') 
/

image.png

3.回到开头的问题

我的虚拟机Oracle环境参数文件中设置的sga_target=960M,但是在启动数据库时候,显示分配的Total System Global Area为1002127360 bytes(955.7M),那么问题就来了,为什么会不一致?相差的4.3M去干什么了?我们先来查看一下sga各个部分的情况

show sga

image.png
Total System Global Area=Fixed Size+Variable Size+Database Buffers+Redo Buffers
单位bytes:1002127360=2259440+314574352+679477248+5816320
单位MB:955.7=2.15+300+648+5.55

  • Fixed Size:SGA中固定组件(它在编译oracle 数据库本身时就固定于其中)的大小。它是固定大小的内存,用来容指向SGA的其它部分。SGA这一部分的大小是不能改变的。
  • Database Buffers:就是buffer cache
  • Redo Buffers:就是redo log buffer
  • Variable Size:指分配的内存块大小可变。SGA的可变块,分为共享池、大池、JAVA池、游标区和其他结构。

再来看下V$SGA_DYNAMIC_COMPONENTS视图

select component,current_size/1024/1024 as MB,granule_size from V$SGA_DYNAMIC_COMPONENTS;

image.png

可见各个池确实都是粒度(4MB)的倍数,大小也与show sga命令的能对应上
我们再来看两个对基表的查询,看得更清晰些

--1
col component format a32
select min(BASEADDR), max(BASEADDR), count(1) Granules, sum(a.gransize)/1048576 MB, a.GRANFLAGS, component, a.GRANSTATE
from x$ksmge a, x$kmgsct b
where a.grantype = b.grantype (+)
group by a.GRANFLAGS, component, a.GRANSTATE
order by 1,2;

image.png

--2
select a.BASEADDR, a.gransize, a.GRANFLAGS, b.component, a.GRANSTATE
from x$ksmge a, x$kmgsct b
where a.grantype = b.grantype (+)
order by 1,2;

image.png
太长只截取部分,总共237行,代表237个粒度,237x4=948,948+2.15+5.55=955.7,与上面查的都能匹配

4.参考

http://dbaparadise.com/2018/05/all-a-dba-needs-to-know-about-granules/

5.总结

1.通过上面学习,我判断SGA_MAX_TARGET与实际分配相差的4.3MB实际并没有分配,但是4.3MB已经大于一个粒度了,为什么不分配呢?有知道的大佬请留言告诉我,感谢

2.学习了管理内存粒度的知识

3.另外ipcs -m命令查看oracle启用分配了三个共享内存段,为什么不是分配一个呢,这块也需要再深究
image.png

4.补全Linux内存管理知识https://www.cnblogs.com/aspirs/p/13896571.html

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值