概念描述
oracle数据库根据每16个CPU分一股strand,每一股独立从log_buffer和redo logfile中分配一块空间,当其中一股log_buffer空间写满,会要求继续从redo logfile中分配一个空间,如果没有剩余空间可以用,则redo会发生切换。所以log_buffer设置不当也会是引起日志切换过快,并且归档日志碎片化的原因。
详情解释
log_buffer和redo logfile存在以下3种情况
1、log buffer大于redo logfile
如果log buffer是1G,redo logfile是512M,如果oracle的cpu_count是64,那么刚好可以分成4个strand,即log buffer可以分成4个256M的strand,redo logfile分成4个128M的strand,当log buffer中第一个256M还没写完的时候会发现redo中已经没有可以分配的新的空间了,此时写满128M就无法分配新的空间了,只能进行切换,假设此时只有1个进程在写redo,那么切换时就只写了128M数据,此时归档日志只有128M。
2、log buffer等于redo logfile
如果log buffer是1G,redo logfile也是1G,如果oracle的cpu_count是64,那么刚好可以分成4个strand,即log buffer可以分成4个256M的strand,redo logfile也分成4个256M的strand,当log buffer中第一个256M写完的时候会发现redo的第一个strand同时也写了256M,此时需要分配新的空间,但是因为redo log刚好分配了4个256M空间,已经无法分配新的空间了,只能进行切换,假设此时只有1个进程在写redo,那么切换时就只写了256M数据,此时归档日志只有256M。
2、log buffer小于redo logfile
如果log buffer是512M,redo logfile也是1G,如果oracle的cpu_count是64,那么刚好可以分成4个strand,即log buffer可以分成4个128M的strand,redo logfile也先分成4个128M的strand,剩余的512M空间暂时不动,用于后续分配。当log buffer中第一个128M写完的时候会发现redo的第一个strand同时也写了128M,此时需要分配新的空间,redo log于是将剩下的空间再开辟一个128M的strand进行数据写入,故无需切换即可继续写入数据,所以当最后实在是没有空间可以划分的时候再进行切换,归档日志可以近似redo log大小。
知识总结
以上只是我们假设的只有1个进程写入redo的情况,实际上我们写入数据时肯定是并行写数据的,即我们实例中的4个strand都在同时写数据,只会存在分别写多写少的情况。所以实际情况中,我们建议log_buffer不要设置过大,建议小于redo log的大小,不然出现归档日志碎片化的概率会非常高
参考文档
一个LOG_BUFFER设置过大导致的日志切换问题
https://www.modb.pro/db/49823