oracle 切出的归档日志小于设置的redo大小

数据库产生大量的小日志,原因和log_buffer的大小和redo log file size有关。为了说明这个问题,我们先来看看从log buffer开始写redo log file的过程:

(1)写redo log buffer

在pga中产生redo entry(即change record,包含data change vector和undo change vector),服务器进程需要先获取redo copy latch,接着再获取redo allocation latch,分配log buffer。在分配的log buffer 之后,释放redo allocation latch,然后再将redo entry写入到log buffer,最后释放redo copy latch。

(2)redo strand

为了减少redo allocation latch的等待,提高并发,orale将redo buffer分成若干小的buffer,每份小的buffer叫strand(我们姑且称其为public strand,因为在10g之后,在shared pool中又划了一块private strand区域,我们先不讨论private strand。),每个strand有一个redo allocation latch保护。使得log buffer的分配从单个变成并发。

redo strand的个数为cpu_count/16,因此,在某些高cpu_count的环境下,redo strand的个数就会比较多了。在一个cpu_count为256的环境中,redo strand为16个。

(3)写log file

完成redo copy之后,进程需要获得Redo Writing Latch去检查lgwr是否active,如果已经active,则释放redo writing latch。lgwr负责将redo buffer中的信息写入到redo file,触发条件为超时3秒,3分之一满logbuffer,commit等等。

注意log file的大小和log buffer之间有密切关系影响log file的大小,也影响后续的archive log的大小。

(4)log file size 和log buffer size

log file size的大小由建redo的时候设置,这个大小可以人为的设定。

log buffer size的大小,即为public strand的总大小,即log buffer大小=每个strand的大小×strand的个数。

而log buffer 可以设置,也可以不设置,在默认没有显式设置的情况下,log buffer的每个strand的大小=128k×cpu_count。而设置了log buffer的大小之后,log buffer大小=每个strand的大小×strand的个数,这个等式还是成立,strand的个数不变,只是每个strand的大小改变了。

我们来看看某数据库的情况:

a)log buffer在没有显式设置的情况下:
--该数据库使用的是spfile,检查spfile中,没有关于log_buffer的设置
SQL> show parameter spfile                                                                                          
                                                                                                                     
NAME                                 TYPE        VALUE                                                              
------------------------------------ ----------- ------------------------------                                      
spfile                               string      /dbcq/dj/mybbo/data/mybbo/app/                                      
                                                 oracle/product/10.2.0/dbs/spfi                                      
                                                 lemybbo.ora                                                        
SQL>                                                                                                                
SQL> !                                                                                                              
z2cs702003[mybbo]$ strings /dbcq/dj/mybbo/data/mybbo/app/oracle/product/10.2.0/dbs/spfilemybbo.ora |grep -i log_buffer
z2cs702003[mybbo]$
 
-- 在没有显式设置的情况下,log_buffer大小为128M:
SQL> show parameter log_buffer                                                                                      
                                                                                                                     
NAME                                 TYPE        VALUE                                                              
------------------------------------ ----------- ------------------------------                                      
log_buffer                           integer     134217728                                                          
SQL>    
 
--数据库的cpu count为128:
SQL> show parameter cpu_count                                                                                        
                                                                                                                     
NAME                                 TYPE        VALUE                                                              
------------------------------------ ----------- ------------------------------                                      
cpu_count                            integer     128                                                                
SQL>
因此,根据计算,每个strand的大小为128K×cpu_count,即128K×128=16384k=16M。strand的个数为cpu_count/16=128/16=8, 因此log buffer=每个strand的大小×strand的个数=16M×8=12M。这也就是我们通过show parameter看到的log_buffer的大小。
我们可通过查询x$kcrfstrand来看strand的情况,也确实看到了8个strand,且每个strand 16M:
SQL> select indx,strand_size_kcrfa from x$kcrfstrand where last_buf_kcrfa != '00';                                  
                                                                                                                     
      INDX STRAND_SIZE_KCRFA                                                                                        
---------- -----------------                                                                                        
         0          16777216                                                                                        
         1          16777216                                                                                        
         2          16777216                                                                                        
         3          16777216                                                                                        
         4          16777216                                                                                        
         5          16777216                                                                                        
         6          16777216                                                                                        
         7          16777216                                                                                        
                                                                                                                     
8 rows selected.                                                                                                    
                                                                                                                     
SQL>
b)在显式设置log_buffer的情况:

--显式设置log_buffer的大小:
SQL> alter system set log_buffer=167772160 scope=spfile;                                                            
                                                                                                                     
System altered.                                                                                                      
                                                                                                                     
SQL>   
--重启数据库,检查在spfile中已经显式设置
z2cs702003[mybbo]$ strings /dbcq/dj/mybbo/data/mybbo/app/oracle/product/10.2.0/dbs/spfilemybbo.ora |grep -i log_buffer
*.log_buffer=167772160                                                                                              
z2cs702003[mybbo]$   
--在数据库中看到,log_buffer已经变成了我们设置的值:
SQL> show parameter log_buffer
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
log_buffer                           integer     167772160
SQL>                                                                                 
                                                                                                                     
SQL> 
--检查strand的情况:
SQL> select indx,strand_size_kcrfa from x$kcrfstrand where last_buf_kcrfa != '00';                                  
                                                                                                                     
      INDX STRAND_SIZE_KCRFA                                                                                        
---------- -----------------                                                                                        
         0          20971520                                                                                        
         1          20971520                                                                                        
         2          20971520                                                                                        
         3          20971520                                                                                        
         4          20971520                                                                                        
         5          20971520                                                                                        
         6          20971520                                                                                        
         7          20971520                                                                                        
                                                                                                                     
8 rows selected.                                                                                                    
                                                                                                                     
SQL>   
--我们发现,strand的个数还是没变,但是每个strand的大小变了。log_buffer的大小还是每个strand的大小×strand的个数。即20M×8=160M=167772160
c)改变log_buffer的大小,再次检验每个strand的大小、strand的个数如何变化:

-- 更改log_buffer大小到192M:
SQL>  alter system set log_buffer=201326592 scope=spfile;                                                            
                                                                                                                     
System altered.                                                                                                      
                                                                                                                     
SQL>                                                                                                                
 --重启数据库,检查在spfile中已经显式设置                                                                                                      
SQL> !                                                                                                              
z2cs702003[mybbo]$ strings /dbcq/dj/mybbo/data/mybbo/app/oracle/product/10.2.0/dbs/spfilemybbo.ora |grep -i log_buffer
*.log_buffer=201326592                                                                                              
z2cs702003[mybbo]$                                                                                                  
z2cs702003[mybbo]$ exit                                                                                              
--在数据库中也显示成我们设置的大小:                                                                                                                                                                     
SQL> show parameter log_buffer                                                                                      
                                                                                                                     
NAME                                 TYPE        VALUE                                                              
------------------------------------ ----------- ------------------------------                                      
log_buffer                           integer     201326592                                                          
SQL>   
--检查每个strand的情况:                                                                                                             
SQL> select indx,strand_size_kcrfa from x$kcrfstrand where last_buf_kcrfa != '00';                                  
                                                                                                                     
      INDX STRAND_SIZE_KCRFA                                                                                        
---------- -----------------                                                                                        
         0          25165824                                                                                        
         1          25165824                                                                                        
         2          25165824                                                                                        
         3          25165824                                                                                        
         4          25165824                                                                                        
         5          25165824                                                                                        
         6          25165824                                                                                        
         7          25165824                                                                                        
                                                                                                                     
8 rows selected.                                                                                                    
                                                                                                                     
SQL>   
--我们看到,更改log_buffer的大小,strand的个数还是8个,但是每个strand的大小变大了。
 
--因此,显式的设置log_buffer的值,log_buffer的大小=每个strand的大小×strand的个数,这个等式还是成立。strand的个数不变,但每个strand的大小改变。
由于log file是lgwr写log buffer到文件,因此他们之间有对应的关系,当切换一个日志到新的日志时,我们分两种情况进行讨论:

a)当log file size 大于log buffer size时,所有的redo strand都会映射到logfile的空间中,并且log file中还会有剩余的空间多出来。
b) 当log file size小于等于log buffer size时,log file会按照strand的个数,被等分成若干个,每个区域都map到一个strand,此时的log file被各个strand瓜分,没有剩余的空间。在低workload的情况下(注,这里的低workload是指低并发,没有redo相关的latch争用),oracle只动态的激活一个strand,也就是只会有一个strand的内容会写到其对应映射的log file区域中。当进程填满一个strand,即该strand所映射的log file区域,并且没有剩余空间时,日志切换就发生了,切到了下一个的日志。
因此,综上所述,我们的总体原则是让log file size 大于log buffer size,而log buffer size的大小由于和CPU有关,目前的主机性能非常强大,几百个CPU已经是很正常的现象,所以算出来的默认的log buffer往往会很大,我的建议是100G左右的SGA,大约显式的设置log buffer为96M或者128M。当然,这只是一个参考值,如果有log buffer space的等待,那还是得继续加大log buffer。

时间: 2024-08-03 09:11:25

oracle 切出的归档日志小于设置的redo大小的相关文章

【Oracle】 rman 删除归档日志的命令

   因为数据仓库上asm的磁盘空间不足,需要删除早期的归档日志,查看资料有以下两种方式: delete archivelog until time 'sysdate-N'; delete archivelog all completed before 'sysdate-N'; 这两个命令的差别在哪里呢? 使用list 命令来查看一下究竟... RMAN>  list archivelog until time 'sysdate-1'; using target database control

查看oracle归档日志路径2

在Oracle中,数据一般是存放在数据文件中,不过数据库与Oracle最大的区别之一就是数据库可以在数据出错的时候进行恢复. 这个也就是我们常见的Oracle中的重做日志(REDO FILE)的功能了.在重做日志分成2部分,一个是在线重做日志文件,另外一个就是归档日志文件.      这里不详细说明在线重做日志,而是说一下归档日志(Archive Log).在线重做日志大小毕竟是有限的,当都写满了的时候,就面临着2个选择,第一个就是把以前在线重做日志从头擦除开始继续写,第二种就是把以前的在线重做

RMAN 配置归档日志删除策略

        Oracle 11g中对于归档日志的删除,除了遵循RMAN保留策略外,也可以通过RMAN来配置归档日志的删除策略,也就是归档日志何时可以被删除.归档日志删除策略适用于所有归档位置(使用快速闪回区FRA/不使用FRA).本文主要描述归档日志删除策略并给出了具体的演示.  1.关于归档日志删除策略      也就是哪些归档日志符合删除策略能够被删除,如前所述,归档位置适用于所有归档位置(使用快速闪回区FRA/不使用FRA)      当启用该策略后,如归档日志存在于FRA中,则Ora

Oracle 归档日志

--==================== -- Oracle 归档日志 --====================       Oracle可以将联机日志文件保存到多个不同的位置,将联机日志转换为归档日志的过程称之为归档.相应的日志被称为归档日志.   一.归档日志     是联机重做日志组文件的一个副本     包含redo记录以及一个唯一的log sequence number     对日志组中的一个日志文件进行归档,如果该组其中一个损坏,则另一个可用的日志将会被归档     对于归

Oracle的归档日志

Oracle可以将联机日志文件保存到多个不同的位置,将联机日志转换为归档日志的过程称之为归档.相应的日志被称为归档日志. 一.归档日志 是联机重做日志组文件的一个副本 包含redo记录以及一个唯一的log sequence number 对日志组中的一个日志文件进行归档,如果该组其中一个损坏,则另一个可用的日志将会被归档 对于归档模式的日志切换,当日志归档完成后,下一个日志才能被覆盖或重新使用 自动归档功能如开启,则后台进程arcn在日志切换时自动完成归档,否则需要手动归档 归档日志用途 恢复数

查看oracle归档日志路径1

查看oracle归档日志路径 1.修改归档日志的格式 默认格式是:" %t_%s_%r.dbf",我们尝试将格式修改为"%t_%s_%r.arch",这是一个静态参数,需要重新启动数据库才生效.sys@ora10g> show parameter log_archive_format NAME                  TYPE        VALUE--------------------- ----------- ----------------

Oracle基于用户管理的不完全恢复(四)完全恢复时丢失部分归档日志

案例3--在做完全恢复时,丢失了部分归档日志 (recover database until cancel;) 1.基于cancel 的不完全恢复 --模拟环境 SQL> col table_name for a20 SQL> col tablespace_name for a10 SQL> select table_name,tablespace_name from user_tables; TABLE_NAME           TABLESPACE ---------------

oracle物理结构(四)归档日志文件

归档日志文件是重做日志文件的截断备份,Oracle运行的两种模式:归档模式和不归档模式. 1.启用/禁用归档模式 SQL>archive log list; 查询归档模式 SQL>shutdown immediate SQL>startup mount SQL>alter database archivelog; SQL>alter database open; SQL>archive log list; Database log mode              A

oracle中升级到12.1.0.2之后rman无法删除已经归档日志

客户一个数据库,架构是2地3中心,本地有primary和standby,远程还有一个standby. primary的rman archivelog deletion policy是ship to all standby 同城standby的rman archivelog deletion policy是backup 1 time,备份在同城standby上进行. 远程standby的rman archivelog deletion policy是applied on all standby.