Oracle归档日志远小于联机重做日志的情况总结本文转载请联系DBA杂念公众号。Oracle存档日志比联机重做日志小得多。造成这种情况的原因有很多。我们可以从以下几个方面进行排查,并一一排除。1:查看参数ARCHIVE_LAG_TARGETARCHIVE_LAG_TARGET该参数可以设置一个时间,通过这个时间限制,强制指定的数据库进行LogSwitch进行归档。如果这个参数设置的太小,可能会导致在线重做日志还没有满就被切换,这可能会导致归档日志比在线重做日志(redolog)小很多。SQL>showparameterarchive_lag_target;NAMETYPEVALUE--------------------------------------------------------------------------archive_lag_targetinteger0SQL>如果参数archive_lag_target为0,那么可以排除这个因素。2:检查是否存在人为切换redolog的可能。有些命令会引起redolog切换,详见下文SQL>altersystemarchivelogcurrent;#archive命令也会引起log切换SQL>altersystemswitchlogfile;#直接切换日志组RMAN>backuparchivelogall;RMAN>backupdatabaseplusarchivelog;SELECTTO_CHAR(FIRST_TIME,'YYYY-MM-DDHH24:MI:SS'),BLOCKS*BLOCK_SIZE/1024/1024,COMPRESSEDFROMV$ARCHIVED_LOG;以下案例截图如下,从截图来看归档日志大小徘徊在31M左右。另外可以看到没有启用归档日志压缩选项(其实ORACLE是不支持归档日志压缩的,后面会说明)。从归档日志的大小可以看出,这不是重做日志切换命令造成的。3:一些Bug引起的,如下metalink文档所示:BUG9272059-REDOLOGSWITCHAT1/8OFSIZEDUETOCMTCPU'SBUG10354739-REDOLOGSIZENOTCOMPLETLYUSEDBUG12317474-FREQUENTREDOLOGSWITCHESGENERATINGSMALLSIZEDARCHIVELOGSBUG5450861-ARCHIVELOGSAREGENERATEDWITHASMALLERSIZETHANTHEREDOLOGFILESBUG7016254-DECREASECONTROLFILEENQUEUEWAITATLOGSWITCH4:跟CPU个数CPU_COUNT以及log_buffer、redologsize有关。Thesizeofthearchivedlogisthe在线日志文件的实际使用量,即切换前写入在线日志文件的内容大小。为了达到更好的并行性,减少冲突,提高并发性,减少等待redoallocationlatch,ORACLE将redobuffer分成若干个小buffer,每个小buffer称为一个strand。每16个CPU分成strand,每个strand独立地从redobuffer和redolog中分配一块空间。当redobuffer用完后,会写入redolog,并继续从redolog中分配相同大小。空间,如果不能分配空闲空间,则不管其他链是否写完,都会进行日志切换。如上图,CPU_COUNT为112,则112/16=7,则redobuffer和redolog可以分成7份SQL>select112.0/16fromdual;112.0/16----------7SQL>select341655552/1024/1024/7fromdual;--logbuffer341655552/1024/1024/7--------------------46.546875SQL>select200/7fromdual;--redologsize200/7----------28.5714286SQL>当日志缓冲区大小为325.828125M(341655552)时,如果分成7股,每股还是325.828125M/7=46.546875M。当redolog的大小为200M时,redolog中的空间会按照strand的个数平均分配,即每个block为200M/7=28.5714286M。这样,当每条strand中的内容写入超过28M时,log就会切换,不再是46M。相当于日志缓冲区中的一部分空间被浪费了。所以你看到的archivedlog大小基本在30M左右(一个strand(strand)28.6加上其他strand也写了一些内容,所以archivelog的大小是一个波动范围)其他特殊场景分析,可以参考《归档日志的大小远小于在线日志的大小[1]》一文介绍。当然,本文的分析过程也忽略了其他股票其实也有一些数据。这需要特别注意。如果你对这个机制不是很清楚,上面链接的博客已经不能访问了。以下是我这里摘录的部分内容,方便大家深入理解:比如CPU个数为64,则有64/16=4strands例1):当log的大小buffer和redologfile的大小都是256M,每条strand是256M/4=64M。当启用每个redologfile时,redologfile的大小会提前分配到logbuffer对应的4个64M,如图:因为logbuffer的大小和redologfile的大小都是256M,那么重做日志文件就没有未分配空间了。每个进程产生的redo会分配到logbuffer上的strand1,2,3,4之一。单个进程只能对应一个链。这样,当数据库中只有某些进程时(比如极端情况下,只有某个进程时)产生大量的redo时,其中一根strand会被快速填充,如图中的strand1:LGWR写满后会将logbuffer中strand1的内容写入redologfile,并尝试从redologfile中分配新的64M空间。如果发现没有空间了,就将strand中的内容全部写入日志,进行日志切换。这样一来redolog文件可能只写了一个strand的内容,其他部分几乎是空的,所以生成的archivelog只会接近64M,而不是256M。当CPU_COUNT很大时,这个差异会更大。例2):当logbuffer大小为256M,redologfile大小为1G时,每条strand仍为256M/4=64M。当启用每个redologfile时,redologfile中的size会被提前分配到logbuffer对应的4个64M,如图:此时,redologfile中还有1G-256M=768M剩余未分配重做日志文件空间。如果strand1满了,LGWR会将logbuffer中strand1的内容写入redologfile,并尝试从redologfile分配新的64M空间,然后继续往下写。映像直到redolog文件中没有更多的空间可供分配,将strand中的所有内容写入日志,并进行日志切换。例3):当logbuffer大小为256M,redologfile大小为100M时,每条strand仍为256M/4=64M。但是redolog文件中的空间会按照strand的个数平均分配,即每个block为100M/4=25M。这样,当每条strand中的内容写到25M时,log就会切换,而不是64M。相当于日志缓冲区中的一部分空间被浪费了。5:查看归档日志压缩是否开启。该功能的目的是在归档文件传输到远程或存储到磁盘之前对其进行压缩,以减少归档日志传输的时间和占用的磁盘空间。您可以使用下面的脚本来检查。SELECTNAME,ARCHIVELOG_COMPRESSIONFROMV$DATABASE;SELECTTO_CHAR(FIRST_TIME,'YYYY-MM-DDHH24:MI:SS'),BLOCKS*BLOCK_SIZE/1024/1024,COMPRESSEDFROMV$ARCHIVED_LOG;SQL>SELECTNAME,2ARCHIVELOG_IVELVSEROM$ARCHDABAF-------------GSP??PDISABLED一开始估计很多人会被这个搞糊涂。其实ORACLE10g和11g都不支持归档日志压缩,官方也没有明确的文档说明。其实归档日志压缩本来就是ORACLE10g计划引入的新特性。不幸的是,这个计划已经被放弃了,ORACLE11g不支持它。Archivecompression是10G计划的新功能,但不幸的是它被撤回了,在11g中仍然没有。这个功能预计在未来的版本中最后,你可以去metalink看看Archivedredologis(significant)smallerthantheredologfile.(文档ID1356604.1)这篇文章,官方文档不愧是官方文档。它最全面地解释了为什么归档日志比重做日志小。存档的重做日志(显着)小于重做日志文件。(文档ID1356604.1)Thereare2possiblecausesforthis:1.DocumentedanddesignedbehaviourduetoexplicitforcinganarchivecreationbeforetheredologfileisfullSQL>altersystemswitchlogfile;SQL>altersystemarchivelogcurrent;RMAN>backuparchivelogall;RMAN>backupdatabaseplusarchivelog;ARCHIVE_LAG_TARGET:limitstheamountofdatathatcanbelostandeffectivelyincreasestheavailabilityofthestandbydatabasebyforcingalogswitchafterthespecifiedamountoftimeelapses.youcanseethisaswellinRACwithanidle/low-loadinstance.>2.Undocumented,butdesignedbehaviour:BUG9272059-REDOLOGSWITCHAT1/8OFSIZEDUETOCMTCPU'SBUG10354739-REDOLOGSIZENOTCOMPLETLYUSEDBUG12317474-FREQUENTREDOLOGSWITCHESGENERATINGSMALLSIZEDARCHIVELOGSBUG5450861-ARCHIVELOGSAREGENERATEDWITHASMALLERSIZETHANTHEREDOLOGFILESBUG7016254-DECREASECONTROLFILEENQUEUEWAITATLOGSWITCHExplanation:AsperBug:5450861(closedas'NotaBug'):*Thearchivelogsdonothavetobeeveninsize.Thiswasdecidedaverylongtimeago,whenblankpaddingthearchivelogswasstopped,foraverygoodreason-inordertosavediskspace.*Thelogswitchdoesnotoccurwhenaredologfileis100%full.Thereisaninternalalgorithmthatdeterminesthelogswitchmoment.Thisalsohasaverygoodreason-doingthelogswitchatthelastmomentcouldincurperformanceproblems(forvariousreasons,outofthescopeofthisnote).Asaresult,afterthelogswitchoccurs,thearchiversarecopyingonlytheactualinformationfromtheredologfiles.Sincetheredologsarenot100%fullafterthelogswitchandthearchivelogsarenotblankpaddedafterthecopyoperationhasfinished,thisresultsinuneven,smallerfilesthantheoriginalredologfiles.Thereareanumberoffactorswhichcombinetodeterminethelogswitchfrequency.Thesearethemostrelevantfactorsinthiscase:a)RDBMSparameterLOG_BUFFER_SIZEIfthisisnotexplicitlysetbytheDBAthenweuseadefault;atinstancestartuptheRDBMScalculatesthenumberofsharedredostrandsasncpus/16,每条链的大小为128Kb*ncpus(其中ncpus是CPU的数量inthesystem).Thelogbuffersizeisthenumberofstandsmultipliedbythestrandsize.ThecalculatedorspecifiedsizeisroundeduptoamultipleofthegranulesizeofamemorysegmentintheSGA.For11.2ifSGAsize>=128GBthengranulesizeis512MB64GB<=SGAsize<128GBthengranulesizeis256MB32GB<=SGAsize<64GBthengranulesizeis128MB16GB<=SGAsize<32GBthengranulesizeis64MB8GB<=SGAsize<16GBthengranulesizeis32MB1GB<=SGAsize<8GBthengranulesizeis16MBSGAsize<1GBthengranulesizeis4MBTherearesomeminimumsandmaximumsenforced.b)SystemloadInitiallyonlyoneredostrandisused,iethenumberof"active"redostrandsis1,并且所有进程将它们的重做复制到那个链中。当/如果存在对该链的争用,则活动重做链的数量将增加到2。随着对活动链的争用增加,活动链的数量也会增加。活动重做链的最大可能数量是最初分配在日志缓冲区中的链数。(此功能称为“动态链”,并且有ahiddenparametertodisableitwhichthenallowsprocessestouseallthestrandsfromtheoutset).c)LogfilesizeThisisthelogfilesizedecidedbytheDBAwhenthelogfilesarecreated.d)ThelogfilespacereservationalgorithmWhentheRDBMSswitchesintoanewonlineredologfile,allthelogbufferredostrandmemoryis"mapped"tothelogfilespace.Ifthelogfileislargerthanthelogbuffertheneachstrandwillmap/reserveitsstrandsizeworthoflogfilespace,andtheremaininglogfilespace(the"logresidue")isstillavailable.Ifthelogfileissmallerthanthelogbuffer,thenthewholelogfilespaceisdivided/mapped/reservedequallyamongallthestrands,andthereisnounreservedspace(ienologresidue).Whenanyprocessfillsastrandsuchthatallthereservedunderlyinglogfilespaceforthatstrandisused,ANDthereisnologresidue,thenalogswitchisscheduled.Example:128CPU的RDBMS分配一个大小为128Mb的log_buffer,其中包含8个大小为16Mb的共享链。它可能比128Mba大一点,向上绕到一个SGA颗粒边界。日志文件是100Mb,所以当RDBMSswitchesintoanewonlineredologfileeachstrandreserves100Mb/8=25600blocksandthereisnologresidue.Ifthereislowsystemload,onlyoneoftheredostrandswillbeactive/usedandwhen25600blocksofthatstrandarefilledthenalogswitchwillbescheduled-thecreatedarchivelogshaveasizearound25600blocks.Witheverythingelsestayingthesame(128cpu'sandlowload),usingalargerlogfilewouldnotreallyreducetheamountofunfilledspacewhenthelogswitchesarerequested,butitwouldmakethatunfilledspacelesssignificantasapercentageofthetotallogfilespace,eg-witha100Mblogfile,thelogswitchhappenswith7x16Mblogfilespaceunfilled(iethelogfileis10%fullwhenthelogswitchisrequested)-witha1Gblogfile,thelogswitchwouldhappenwith7x16Mblogfilespaceunfilled(iethelogfileis90%fullwhenthelogswitchisrequested)WithahighCPU_COUNT,alowloadandaredologfilesizesmallerthantheredologbuffer,youmayseesmallarchivedlogfilesbecauseoflogswitchesatabout1/8ofthesizeofthedefinelogfilesize。这是因为CPU_COUNT定义了redostrand的数量s(ncpus/16).Withalowloadonlyasinglestrandmaybeused.Withredologfilesizesmallerthantheredologbuffer,thelogfilespaceisdividedovertheavailablestrands.Whenforinstanceonlyasingleactivestranddisused,alogswitchcanalreadyoccurwhenthatstranddisfilled.Reference[1]链接不再有效:http://www.ctonote/32.com/
