Oracle归档日志的大小比在线日志的大小 小很多

有些用户会对于归档日志的大小比在线日志小感到疑惑,对于这种情况:

首先请检查您的归档日志文件是否压缩:
SELECT to_char(first_time,'yyyy-mm-dd hh24:mi:ss'),blocks*block_size/1024/1024,compressed from v$archived_log;

如果未压缩,那么这个问题可能和您的CPU个数有关。
请查看您的CPU个数:
show parameter CPU_COUNT

归档日志的大小是真实的在线日志文件的使用量,也就是在线日志文件切换前其中写入的内容的大小。
但是为了更好的并行减少冲突,Oracle会按每16个CPU分一股(strand),每一股独立从redo buffer以及redo log中分配一块空间,当这一块redo buffer用完,会写入redo log并且继续从redo log中分配相同大小的空间,如果无法分配空闲空间就会进行日志切换,而不管其他strand是否写完。
下面举例子来说明这个算法:
比如CPU的个数是64个,则会有64/16=4个strand
例1)当log buffer的大小和redo log file的大小都是256M的时候,则每个strand都是256M/4=64M。
每一个redo log file被启用时,会预先将redo log file中的大小分配出4个64M与log buffer对应,如图:

Oracle归档日志的大小比在线日志的大小 小很多


因为log buffer的大小和redo log file的大小都是256M,则redo log file没有剩余的未分配的空间了。

每个进程产生的redo会分配到log buffer上的1,2,3,4其中的某一个strand上,单个进程只能对应一个strand,
这样当数据库中只有某些进程(比如极端的情况,只有某一个进程)产生的redo很多的时候,其中一个strand会快速写满,比如图中的strand 1:

Oracle归档日志的大小比在线日志的大小 小很多


写满之后LGWR会将log buffer中strand 1的内容写入到redo log file中,并且试图从redo log file中分配一个新的64M空间,发现没有了,则将所有strand中的内容写入日志,并作日志切换。

Oracle归档日志的大小比在线日志的大小 小很多


这样,可能会导致redo log file只写入了一个strand的内容,其他部分几乎是空的,则产生的archive log会只接近64M,而不是256M。
当CPU_COUNT很大时,这个差值会更大。

例2)当log buffer的大小是256M,而redo log file的大小是1G的时候,每个strand还是256M/4=64M。
每一个redo log file被启用时,会预先将redo log file中的大小分配出4个64M与log buffer对应,如图:

Oracle归档日志的大小比在线日志的大小 小很多


这时,redo log file中还有1G-256M=768M剩余的未分配的空间。


如果strand 1写满之后,LGWR会将log buffer中strand 1的内容写入到redo log file中,并且试图从redo log file中分配一个新的64M空间,然后不断往下写。

Oracle归档日志的大小比在线日志的大小 小很多

直到redo log file中再没有可分配空间了,则将所有strand中的内容写入日志,并作日志切换。

Oracle归档日志的大小比在线日志的大小 小很多


例3)当log buffer的大小是256M,而redo log file的大小是100M的时候,每个strand还是256M/4=64M。
但是redo log file中的空间会按strand的个数平均分配,也就是每块100M/4=25M。

Oracle归档日志的大小比在线日志的大小 小很多


这样,当每个strand中的内容写到25M的时候,就会日志切换,而不是64M。相当于log buffer中的一部分空间被浪费了。

请参考以下文档:
1.Archive Logs Are Created With Smaller, Uneven Size Than The Original Redo Logs. Why? (Doc ID 388627.1)
With a high CPU_COUNT, a low load and a redo log file size smaller than the redolog buffer, you may small archived log files because of log switches at about 1/8 of the size of the define log file size.
This is because CPU_COUNT defines the number of redo strands (ncpus/16). With a low load only a single strand may be used. With redo log file size smaller than the redolog buffer, the log file space is divided over the available strands. When for instance only a single active strand is used, a log switch can already occur when that strand is filled.

<==高 CPU_COUNT和低workload(实际上数据库不一定不繁忙,只是在产生redo的进程很少的情况下)会导致 Archive Log比redo log小很多,而且日志频繁切换。

2.Archived redolog is (significant) smaller than the redologfile. (Doc ID 1356604.1)
The logfile space reservation algorithm
If the logfile is smaller than the log buffer, then the whole logfile space is divided/mapped/reserved equally among all the strands, and there is no unreserved space (ie no log residue).
When any process fills a strand such that all the reserved underlying logfile space for that strand is used, AND there is no log residue, then a log switch is scheduled.

<==log strand 和 log switch的算法在这个note中讲的更明白。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/93a9218e41bc2a800f0f4bde28a97509.html