为什么有这样的标题,是因为我们都知道这样的结论:转载自eygle的文章《Granule 与 Redo Log Buffer (log_buffer) 的关系》:http://www.eygle.com/archives/2009/07/granule_log_buffer.html“而实际上大家也发现,从Oracle10g开始,Redo Log Buffer缺省的已经是大大超过了原来的想象。
从Oracle 9i引入了Granule的概念后,在Oracle10g中,Oracle的内存分配会为'Fixed SGA Size'和'Redo Buffers'共享整数倍个Granule。”而且从metalink上我们也找到了同样说法的文章:Oracle Calculation of Log_Buffer Size in 10g [ID 604351.1]Modified 01-JUN-2010 Type HOWTO Status PUBLISHEDThe LOG_BUFFER size will be set by default, by Oracle internal algorithm. In 10G R2, Oracle combines fixed SGA area and redo buffer [log buffer] together.
If there is a free space after Oracle puts the combined buffers into a granule, that space is added to the redo buffer. Thus you see redo buffer has more space than expected. This is an expected behavior. Bug 4930608 documents this :
"In 10.2 the log buffer is rounded up to use the rest of the granule...
The granule size can be found from the hidden parameter "_ksmg_granule_size" "In 10G the log_buffer could fall between the log_buffer specified in spfile and the granule size. A minimum value can be specified, but Oracle can initialize it with a bigger value, as decided by its internal algorithm. 于是我也一直认为在10GR2中,有这样的公式存在:(Fixed SGA Size)+(Redo Buffers)=N*(Granule Size). Where N is an integer. 我可以拿一个实例,来证明这个公式是成立的:在pfile里,设置的log_buffer = 512000SQL> select * from v$sgainfo where name in ('Fixed SGA Size','Redo Buffers','Granule Size');NAME BYTES RES
-------------------------------- ---------- ---
Fixed SGA Size 2055512 No
Redo Buffers 31498240 No
Granule Size 33554432 No这里但是,事实并不是这样。至少,不全是这样。经过检查多个库,这些库都是10GR2,得到下面信息:其中Factor=(log_buffer(actually)+Fixed SGA Size)/Granule Size
DB(from haozhu)
|
Platform
|
Compatible
|
OS memory
|
SGA
|
log_ buffers (init.ora)
|
log_ buffers (actually)
|
Fixed SGA Size
|
Granule Size
|
Factor
|
1
|
T2000
|
10203
|
32G
|
22G
|
500K
|
30M
|
2M
|
32M
|
1
|
2
|
T5120
|
10203
|
64G
|
48G
|
500K
|
62M
|
2M
|
64M
|
1
|
3
|
T5120
|
10204
|
64G
|
56G
|
500K
|
62M
|
2M
|
64M
|
1
|
4
|
T5240
|
10203
|
96G
|
77G
|
9M
|
9M
|
2M
|
32M
|
N/A
|
5
|
T5240
|
10203
|
96G
|
78G
|
500K
|
6M
|
2M
|
32M
|
1/4
|
6
|
T5240
|
9205
|
96G
|
86G
|
500K
|
2M
|
2M
|
64M
|
1/16
|
7
|
T5240
|
9205
|
96G
|
81G
|
500K
|
2M
|
2M
|
64M
|
1/16
|
8
|
T5120
|
9205
|
64G
|
49G
|
500K
|
62M
|
2M
|
64M
|
1
|
于是从上面在Sun SPARC平台各个T系机器上的表现来看,似乎,在T5240上,实际的log_buffers+Fixed SGA Size并不为整数倍的Granule Size。我认为是因为当SGA的值超过了某个threshold后,log_buffers的自动计算就变得跟最上面的理论不一样了。于是有如下实验性结论(因为没有任何文档佐证,所以仅供参考,真实性需要更多实例证明):1.在10GR2,log_buffers+Fixed SGA Size会根据数据库的SGA计算出一个最小值,当log_buffer在init.ora里参数设定得比这个值小的时候,就会自动增加到这个最小值。从以上例子来看,这也就是为什么,参数log_buffers是500K,但是会被自动增加。2.在10GR2,当init.ora里log_buffers参数设定得比这个最小值大的话,就会使用参数log_buffers设定的值。也就是取两者取其大者。从以上例子来看,从DB=4,由于我设定的log_buffers是9M,而这个最小值估计是6M(从DB=5推算出),而实际的log_buffers=9M。3.在10GR2,当SGA比较小的时候:(Fixed SGA Size)+(Redo Buffers)=N*(Granule Size). Where N is an integer. 从上面例子来看,DB=1,2,3,8都可以证明,此时N=1.4.在10GR2,当SGA比较大的时候:(Fixed SGA Size)+(Redo Buffers)=N*(Granule Size). Where N is NOT an integer.其中,当compatible=10g时,N=1/4,当compatible=9i时,N=16/1。从上面例子可以看出,DB=5时证明前半句,DB=6,7时证明后半句。(BTW:1/4和1/16虽然出现在我的例子中,但我不保证随着SGA的不断增大,例如>100G以上,是否这个比例会更小,例如是否会出现1/64。)这点似乎也是合理的或者说可以理解的,Oracle不希望当SGA很大时,自动地将log_buffers设得太大。5.以上第3点和第4点对SGA的“小”和“大”的定义是有一个分界线的,即多小为“小”,多大为“大”。这个threshold根据以上所有例子我可以估算在一个大小。大约SGA达到70G以上时,可以认为其SGA“大”了,此时log_buffers+Fixed SGA Size就不满足整数个Granule Size了。或许是1/4*Granule Size,或许是1/16*Granule Size...希望大家能有其他大SGA情况下的log_buffers自动设定表现“异常”的例子,来推翻或者佐证这些实验结论。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15415488/viewspace-667516/
,如需转载,请注明出处,否则将追究法律责任。