Oracle Redo Log 机制 小结(2)

2.2 LOG BUFFER 说明 2.2.1 Log Buffer 说明

--官网的说明:

The redolog buffer is a circular buffer in the SGA that stores redo entriesdescribing changes made to the database. Redo entries contain theinformation necessary to reconstruct, or redo, changes made to the database byDML or DDL operations. Database recovery applies redo entries to data files toreconstruct lost changes.

Oracle Databaseprocesses copy redo entriesfrom the user memory space to the redo log buffer in the SGA. The redo entriestake up continuous, sequential space in the buffer. The background process  writes the redo log buffer to the active online redo loggroup on disk.  shows this redo buffer activity.

Oracle Redo Log 机制 小结

LGWR writes redosequentially to disk while DBWn performs scattered writes of data blocksto disk. Scattered writes tend to be much slower than sequential writes.Because LGWR enable users to avoid waiting for DBWn to complete its slowwrites, the database delivers better performance.

The LOG_BUFFER initializationparameter specifies the amount of memory that Oracle Database uses whenbuffering redo entries. Unlike other SGA components, the redo log buffer andfixed SGA buffer do not divide memory into granules.

--MOS: [ID 147471.1]

The redo logbuffer is a circular buffer in the SGA that holds information about changesmade to the database. This information is stored in redo entries. Redo entriescontain the information necessary to reconstruct, or redo changes made to thedatabase . Redo entries are used for database recovery, if necessary.

Redo entries arecopied by Oracle server processes from the user's memory space to the redo logbuffer in the SGA. The redo entries take up continuous, sequential space in thebuffer. The background process LGWR writes the redo log buffer to the activeonline redo log file (or group of files) on disk.

The initialization parameter LOG_BUFFER determines the size (in bytes) of the redolog buffer. In general, larger values reduce log file I/O, particularly iftransactions are long or numerous. The default setting is four times themaximum data block size for the host operating system prior to 8i and 512k or128k x cpu_count whichever is greater, from 8i onwards.

-- MOS: [ID 147471.1]   Redolog Latches

Whena change to a data block needs to be done, it requires to create a redo recordin the redolog buffer executing the following steps:

(1)    Ensure that no other processeshas generated a higher SCN

(2)    Find for space available towrite the redo record. If there is no space available then the LGWR must writeto disk or issue a log switch

(3)    Allocate the space needed inthe redo log buffer

(4)    Copy the redo record to the logbuffer and link it to the appropriate structures for recovery purposes.

The database has threeredo latches to handle this process:

(1)Redo Copy latch

The redocopy latch is acquired for the whole duration of the process describedabove. The init.ora LOG_SIMULTANEOUS_COPIES determines the number of redo copylatches. It is only released when a log switch is generated to release freespace and re-acquired once the log switch ends.

(2)Redo  allocation latch

The redoallocation latch is acquired to allocate memory space in the log buffer. BeforeOracle9.2, the redo allocation latch is unique and thus serializes the writingof entries to the log buffer cache of the SGA. In Oracle 9.2. EntrepriseEdition, the number of redo allocation latches is determined by init.oraLOG_PARALLELISM.   The redo allocation latch allocates space in the logbuffer cache for each transaction entry.  If transactions are small, or ifthere is only one CPU on the server, then the redo allocation latch also copiesthe transaction data into the log buffer cache. If a log switch is needed toget free space this latch is released as well with the redo copy latch.

(3)Redo writing latch

This uniquelatch prevent multiple processes posting the LGWR  process requesting logswitch simultaneously. A process that needs free space must acquire the latchbefore of deciding whether to post the LGWR to perform a write, execute a logswitch or just wait.

-- MOS: [ID 147471.1]

Instance ParametersRelated with the Redolog Latches   

In Oracle7 andOracle 8.0, there are two parameters that modify the behavior of the latchallocation in the redolog buffer: LOG_SIMULTANEOUS_COPIES (This parametercontrols the number of redo copy latches when the system has morethan one CPU),  and LOG_SMALL_ENTRY_MAX_SIZE. When LOG_SIMULTANEOUS_COPIESis set to a non-zero value, and the size of the transaction entry is smallerthan the value of the LOG_SMALL_ENTRY_MAX_SIZE parameter then the copy of thetransaction entry into the log buffer cache is performed by the redoallocation latch.  If the size of the transaction entry exceedsLOG_SMALL_ENTRY_MAX_SIZE, then the transaction entry is copied into the logbuffer cache by the redo copy latch.

In Oracle8i andOracle9.0, a redo copy latch is always required regardless of the redo size sothe check is no longer performed. The init.ora LOG_SIMULTANEOUS_COPIES becomesobsolete and the number of redo copy latches defaults to twice the number ofcpus. The parameter LOG_SMALL_ENTRY_MAX_SIZE is also obsolete. For furtherdetail on the change of this parameters in Oracle 8i seeNote:94271.1

In Oracle9.2 andhigher, multiple redo allocation latches become possible with init.oraLOG_PARALLELISM. The log buffer is split in multiple LOG_PARALLELISM areas thateach have a size of init.ora LOG_BUFFER. The allocation job of each area isprotected by a specific redo allocation latch. The number of redo copy latchesis still determined by the number of cpus

LOG BUFFER 是SGA中一块循环使用的内存区域,它一般很小.

在Oracle 10g之前,LOG BUFFER参数的默认设置为Max(512 KB,128 KB * CPU_COUNT),按照默认设置,LOG_BUFFER消耗的内存都不会太高,而由于LGWR对Log Buffer内容的写出非常频繁,所以很小的Log Buffer也可以工作得很好,根据经验,有很多对Log Buffer的指导性设置,比如经常提到的3MB大小,但是在Oracle10g中,Redo Log Buffer默认的已经大大超过了原来的想象。

这和Oracle 9i引入了Granule的概念有关,在动态SGA管理中,Granule是最小的内存分配单元,其大小与SGA及操作系统平台有关。

在10g中ORACLE会自动调整它的值,他遵循这样一个原则,'Fixed SGA Size'+ 'Redo Buffers'是granule size 的整数倍(如果是一倍,那么他们的比值可能为0.999...如果是2倍,那么他们的比值可能是1.999...)。

一般的granule value 为4194304 ,也就是4M, 而fixed size 一般为 1.2M,这个值不确定,也不精确,根据不同的平台有所差异,而默认的log_buffer+fixedsize 的大小为 granulesize 的整数倍,所以默认的情况下你看见的log_buffer大小约为6.67m或者为2.7M。

所以如果我们手动的设置log_buffer的值,那么ORACLE会将它加上fixedsize 然后除以granule ,得到一个值,然后四舍五入,看最接近哪个整数,然后就取最接近的那个值。

SQL> select * from v$version whererownum <2; 

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise EditionRelease 10.2.0.4.0 - Prod

SQL> select * from v$sgainfo where namein ('Fixed SGA Size','Redo Buffers','Granule Size'); 

NAME                                  BYTES RES

-------------------------------- -------------

Fixed SGA Size                      1270508 No

Redo Buffers                        2920448 No

Granule Size                        4194304 No

SQL> select sum(bytes)/1024/1024 fromv$sgainfo where name in ('Fixed SGA Size','Redo Buffers'); 

SUM(BYTES)/1024/1024

--------------------

3.9968071

--查看'FixedSGA Size' + 'Redo Buffers' 与 Granule Size的比值:

SQL> select 3.9968071/4 from dual;

3.9968071/4

-----------

.999201775

这里验证了我们前面的说法:'Fixed SGA Size' + 'Redo Buffers' 是Granule Size 整数倍。

2.2.2 Log Buffer 中的Latch

由于log buffer是一块“共享”内存,为了避免冲突,它是受到redo allocation latch保护的,每个服务进程需要先获取到该latch才能分配redobuffer。因此在高并发且数据修改频繁的oltp系统中,我们通常可以观察到redoallocation latch的等待。

为了减少redo allocation latch等待,在oracle 9.2中,引入了log buffer的并行机制。其基本原理就是,将log buffer划分为多个小的buffer,这些小的buffer被成为Shared Strand。每一个strand受到一个单独redo allocation latch的保护。多个shared strand的出现,使原来序列化的redo buffer分配变成了并行的过程,从而减少了redo allocationlatch等待。

为了进一步降低redo buffer冲突,在10g中引入了新的strand机制——Private strand。Private strand不是从log buffer中划分的,而是在shared pool中分配的一块内存空间。

Private strand的引入为Oracle的Redo/Undo机制带来很大的变化。每一个Private strand受到一个单独的redo allocation latch保护,每个Private strand作为“私有的”strand只会服务于一个活动事务。获取到了Private strand的用户事务不是在PGA中而是在Private strand生成Redo,当flush private strand或者commit时,Privatestrand被批量写入log文件中。如果新事务申请不到Private strand的redo allocation latch,则会继续遵循旧的redo buffer机制,申请写入shared strand中。事务是否使用Private strand,可以由x$ktcxb的字段ktcxbflg的新增的第13位鉴定。

对于使用Private strand的事务,无需先申请Redo Copy Latch,也无需申请Shared Strand的redo allocation latch,而是flush或commit是批量写入磁盘,因此减少了Redo Copy Latch和redo allocation latch申请/释放次数、也减少了这些latch的等待,从而降低了CPU的负荷。

2.2.3 Log Buffer 大小问题

一般默认情况下的log_buffer的大小够用了,查看Log_buffer是否需要调整,可以查看数据库是否有大量的log buffer space等待事件出现。redo log 最开始是在pga中的uga产生的(数据库一般是专有模式),oracle会把它拷贝到SGA中的log_buffer中去,如果log_buffer过小,或者lgwr不能够快速将redo 写入到log file中,那么就会产生log buffer space等待事件,遇到此类问题,可以增加 log_buffer大小,调整log file 到裸设备,I/0快的磁盘中。

MOS有两篇相关的文章:

(1)Oracle Calculation of Log_Buffer Size in 10g [ID604351.1]

A big difference can be seen between 10.2.0.3 and 10.2.0.4 when usingthe same system configuration (in terms of the application and its dbobjects and datafiles, ram size, number of CPUs etc). In 10.2.0.3 it was set byOracle to 14M and now in 10.2.0.4 to 15M. 

--在10.2.0.3 中Log Buffer 默认值是14M,在10.2.0.4中,默认值是15M。

The LOG_BUFFERsize will be set by default, by Oracle internal algorithm. 

In 10G R2,Oracle combines fixed SGA area and redo buffer [log buffer] together. 

(2)Tuning the Redolog Buffer Cache and Resolving RedoLatch Contention [ID 147471.1]

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

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