为什么有这样的标题,是因为我们都知道这样的结论:
转载自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 PUBLISHED
The 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 = 512000
SQL> 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
于是从上面在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自动设定表现“异常”的例子,来推翻或者佐证这些实验结论。
转载自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 PUBLISHED
The 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 = 512000
SQL> 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博客 ” ,链接:http://blog.itpub.net/15415488/viewspace-667516/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15415488/viewspace-667516/