阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Oracle Online redo log 深入理解

127次阅读
没有评论

共计 13497 个字符,预计需要花费 34 分钟才能阅读完成。

Oracle online redo log 是 Oracle 数据库中核心文件之一。在数据库操作中,只要有任何的数据块变化,都会生成相应的 redo entry。redo entry 首先保存在 log buffer 中,最后由 lgwr 进程写入到 Redo log 里面。

Online Redo Log 的维护和性能是影响 Oracle 工作的一个重要方面。本文从日常维护角度出发,介绍几个常见的场景处理方法。

1、Redo Log Group 和 Redo Log Group Member

Redo Log 在数据库中的作用主要在于进行实例恢复(Instance Recovery)。当数据库中一个事务提交 commit 的时候,由 server process 修改的数据块是不会直接写回到数据文件里面的。commit 动作是会引发 lgwr 进程将事务生成的 redo log 写入到 online redo log file。这样,形成日志在先的策略。

如果此时发生数据库突然的停机,如断电、事故,在内存中的数据块是会丢失的。此时,文件的事务编号与日志的进程是不一致的。在服务器启动的 open 阶段,Oracle 会根据 online redo log 的记录,从最后一个检查点 checkpoint 开始,进行数据库事务重演。所以,online redo log 对数据库的事务一致性和数据恢复是极其重要的。

Online Redo Log Group 是一系列完全相同的 online redo log file 的集合。在一个数据库中,至少要有两个 redo log group 交替进行 redo log 写入操作。但是,我们建议是使用至少三个日志组。

SQL> select group#, sequence#, bytes, members, status from v$log;
                                                                         
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 CURRENT
        2        215  52428800          2 INACTIVE
        3        216  52428800          2 INACTIVE

三个日志组是按照交替的顺序进行读写。我们从视图 v$log 中,可以看到当前正在使用的日志组。这个视图中,我们着重关注 group#,sequence# 和 status 三个视图列。

group# 表日志组编号。redo log group 的标志是通过组编号来实现的。我们创建 group 和修改维护 group,都是通过制定 group# 完成。

sequence#表示日志顺序号。每个日志都是唯一的,分配给日志的编号也是唯一的。这个就是 sequence# 编号,这个编号会随着 archive redo log 一起记录。

status 表示当前日志的所处状态,常见的有 active,current,inactive 和 unused。下面详细介绍一下几个状态的含义:

üCurrent:表示当前正在进行写入的日志组,也是最新的日志组;

üActive:当一个事务完成 commit 之后,redo entry 写入到了日志文件。并且这个日志已经不是当前 current,但是对应的数据块 data block 还没有从 buffer cache 中写入到文件中。此时,日志组状态为 active。处在 active 状态的日志组,是不能够被覆盖和删除的;

üInactive:日志并不是当前正在读写的日志,并且对应的事务数据块都已经写回到数据文件中;

üUnused:表示新创建的 online 日志组,还没有使用过;

下面再来说一说 redo group member。在每个 redo log group 中,都有一个或者多个完全相同的 log file。在一个组内,log file 完全相同,一个写入日志动作要在组内所有的文件上写入成功之后,才算写入完成。

在生产条件下,redo group member 通常是放置在不同的磁盘存储日志文件。进行这种“multi-path”配置的理由就在于冗余防错。当一个文件出现损坏,虽然一时不能启动数据库,但是我们可以方便利用其它副本进行替换。

在诸多的 Oracle 文件中,采用相同 multi-path 保存配置的还有控制文件 control file。

此处有一点需要注意:很多系统由于各种原因,配置的多路径过多,反而影响效率。相同的 redo log 在一个文件中写入的时间和十个文件中写入的时间天差地别。配置多路径目的是利用物理冗余防错,过多的冗余事倍功半。

2、常用的 Redo Log 调整操作

在 Oracle 安装的时候,我们是可以调整 Redo Log 的大小和组数。同时,在系统运行过程中,我们也可以对现有的日志进行调整。下面是常见的集中类型的 redo log 操作实例。我们选择 Oracle 11R2 进行试验。

SQL> select * from v$version;
                                                                   
BANNER
————————————————————————
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 – Production
PL/SQL Release 11.2.0.1.0 – Production
CORE        11.2.0.1.0        Production

注意:进行 redo log 的调整,一定要选择系统相对空闲的时候,避免业务高峰期。特别是生产环境尤其重要。

ü查看当前 redo 情况

通过视图 v$log 和 v$logfile 可以分别查看当前的日志组和文件情况。

SQL>select group#, sequence#, bytes, members, status from v$log;
                                                           
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 CURRENT
        3        216  52428800          2 INACTIVE
                                                           
SQL> select group#,member from v$logfile;
                                               
GROUP#  MEMBER                                     
—  —————————————————————-
  3  /u01/oradata/WILSON/onlinelog/o1_mf_3_6bcsqtfj_.log           
  3  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_3_6bcsqtwv_.log
  2  /u01/oradata/WILSON/onlinelog/o1_mf_2_6bcsqs3t_.log           
  2  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_2_6bcsqstm_.log
  1  /u01/oradata/WILSON/onlinelog/o1_mf_1_6bcsqpty_.log           
  1  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_1_6bcsqqt0_.log
                                               
6 rows selected

ü添加 redo log group

一些场景下,添加 redo log group 操作,需要指定 group 的编号和成员文件。

SQL> alter database add logfile (‘/u01/oradata/WILSON/onlinelog/redo4a.log’, ‘/u01/flash_recovery_area/WILSON/onlinelog/redo4b.log’) size 10m;
                                           
Database altered
                                           
SQL>  select group#, sequence#, bytes, members, status from v$log;
                                           
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 CURRENT
        3        216  52428800          2 INACTIVE
        4          0  10485760          2 UNUSED
                                           
SQL> select group#,member from v$logfile;
GROUP# MEMBER                                                 
– —————————————————————-
 3  /u01/oradata/WILSON/onlinelog/o1_mf_3_6bcsqtfj_.log           
 3  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_3_6bcsqtwv_.log
 2  /u01/oradata/WILSON/onlinelog/o1_mf_2_6bcsqs3t_.log           
 2  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_2_6bcsqstm_.log
 1  /u01/oradata/WILSON/onlinelog/o1_mf_1_6bcsqpty_.log           
 1  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_1_6bcsqqt0_.log
 4 /u01/oradata/WILSON/onlinelog/redo4a.log                     
 4 /u01/flash_recovery_area/WILSON/onlinelog/redo4b.log         
                                           
8 rows selected

注意,在 10g 以后,我们可以借助 OMF(Oracle Managed File)对数据文件和日志文件进行透明化管理。Oracle 会自动进行路径选择和名字命名。

SQL> alter database add logfile size 10m;
                                   
Database altered
                                   
SQL> show parameter create
                                   
NAME                                TYPE        VALUE
———————————— ———– ———————
create_bitmap_area_size              integer    8388608
create_stored_outlines              string 
db_create_file_dest                  string      /u01/oradata
db_create_online_log_dest_1          string 
db_create_online_log_dest_2          string 
db_create_online_log_dest_3          string 
db_create_online_log_dest_4          string 
db_create_online_log_dest_5          string 
                                   
SQL>  select group#, sequence#, bytes, members, status from v$log;
                                   
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 CURRENT
        3        216  52428800          2 INACTIVE
        4          0  10485760          2 UNUSED
        5          0  10485760          2 UNUSED
                                   
SQL> select group#,member from v$logfile;
                                   
    GROUP# MEMBER                                                       
———- ———————————————————–
(篇幅原因,部分省略……)
 1  /u01/oradata/WILSON/onlinelog/o1_mf_1_6bcsqpty_.log           
 1  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_1_6bcsqqt0_.log
 4  /u01/oradata/WILSON/onlinelog/redo4a.log                     
 4  /u01/flash_recovery_area/WILSON/onlinelog/redo4b.log         
 5  /u01/oradata/WILSON/onlinelog/o1_mf_5_7vqh94p2_.log           
 5  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_5_7vqh94t6_.log
                                   
10 rows selected

üActive 状态日志组解决

在上文中,我们讨论过 Active 状态下,dbwr 还没有将相应的事务数据块写入到 DB File 中,此时 Log Group 的状态是 Active。将 Active 状态转变为 Inactive 的方法,就是手工的进行 checkpoint,强制启动 dbwr 一次写入动作。

– 当前是 group 4 为当前日志;
SQL>  select group#, sequence#, bytes, members, status from v$log;
                             
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 ACTIVE
        3        216  52428800          2 INACTIVE
        4        219  10485760          2 CURRENT
        5          0  10485760          2 UNUSED
                             
– 手工一次切换,形成 group 4 为 active 状态;
SQL> alter system switch logfile;
System altered
                             
                             
SQL>  select group#, sequence#, bytes, members, status from v$log;
                             
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 ACTIVE
        3        216  52428800          2 INACTIVE
        4        219  10485760          2 ACTIVE
        5        220  10485760          2 CURRENT
                             
– 写入检查点;
SQL> alter system checkpoint;
System altered
                             
SQL>  select group#, sequence#, bytes, members, status from v$log;
                             
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 INACTIVE
        3        216  52428800          2 INACTIVE
        4        219  10485760          2 INACTIVE
        5        220  10485760          2 CURRENT

ü删除 redo log group

删除 redo log group 要有至少两个前提,需要注意:

首先是要保证删除日志组状态为 unused 或者 inactive,否则不能删除。其次是删除后,系统日志组个数不能少于 2 个。

SQL>  select group#, sequence#, bytes, members, status from v$log;
                       
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 INACTIVE
        3        221  52428800          2 CURRENT
        4        219  10485760          2 INACTIVE
        5        220  10485760          2 ACTIVE
                       
–ACTIVE 状态删除报错。
SQL> alter database drop logfile group 5;
                       
alter database drop logfile group 5
                       
ORA-01624: 日志 5 是紧急恢复实例 wilson (线程 1) 所必需的
ORA-00312: 联机日志 5 线程 1: ‘/u01/oradata/WILSON/onlinelog/o1_mf_5_7vqh94p2_.log’
ORA-00312: 联机日志 5 线程 1: ‘/u01/flash_recovery_area/WILSON/onlinelog/o1_mf_5_7vqh94t6_.log’
                       
SQL>  select group#, sequence#, bytes, members, status from v$log;
                       
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 INACTIVE
        3        221  52428800          2 CURRENT
        4        219  10485760          2 INACTIVE
        5        220  10485760          2 ACTIVE
                       
SQL> alter system checkpoint;
System altered
                       
SQL>  select group#, sequence#, bytes, members, status from v$log;
                       
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 INACTIVE
        3        221  52428800          2 CURRENT
        4        219  10485760          2 INACTIVE
        5        220  10485760          2 INACTIVE

调整好状态之后,再进行删除。

SQL> alter database drop logfile group 5;
                 
Database altered
                 
SQL>  select group#, sequence#, bytes, members, status from v$log;
                 
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 INACTIVE
        3        221  52428800          2 CURRENT
        4        219  10485760          2 INACTIVE

ü增加 redo log group member

直接增加日志组成员的使用几率相对较少,我们一般是一次性直接将成员文件添加完毕。

SQL> alter database add logfile member ‘/u01/oradata/WILSON/onlinelog/redo4c.log’ to group 4;
Database altered
             
SQL> select group#, member from v$logfile;
             
GROUP# MEMBER
— —————————————————————-
 3 /u01/oradata/WILSON/onlinelog/o1_mf_3_6bcsqtfj_.log
 3 /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_3_6bcsqtwv_.log
 2 /u01/oradata/WILSON/onlinelog/o1_mf_2_6bcsqs3t_.log
 2 /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_2_6bcsqstm_.log
 1 /u01/oradata/WILSON/onlinelog/o1_mf_1_6bcsqpty_.log
 1 /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_1_6bcsqqt0_.log
 4 /u01/oradata/WILSON/onlinelog/redo4a.log
 4 /u01/flash_recovery_area/WILSON/onlinelog/redo4b.log
 4 /u01/oradata/WILSON/onlinelog/redo4c.log
             
9 rows selected

ü删除 redo log group member

删除 group member.

SQL> select group#,member from v$logfile;
         
GROUP#  MEMBER                                       
—  —————————————————————-
  3  /u01/oradata/WILSON/onlinelog/o1_mf_3_6bcsqtfj_.log           
  3  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_3_6bcsqtwv_.log
  2  /u01/oradata/WILSON/onlinelog/o1_mf_2_6bcsqs3t_.log           
  2  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_2_6bcsqstm_.log
  1  /u01/oradata/WILSON/onlinelog/o1_mf_1_6bcsqpty_.log           
  1  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_1_6bcsqqt0_.log
         
6 rows selected
SQL> alter database add logfile (‘/u01/oradata/WILSON/onlinelog/redo4a.log’, ‘/u01/flash_recovery_area/WILSON/onlinelog/redo4b.log’) size 10m;
         
Database altered
         
SQL>  select group#, sequence#, bytes, members, status from v$log;
         
    GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
———- ———- ———- ———- —————-
        1        217  52428800          2 INACTIVE
        2        218  52428800          2 CURRENT
        3        216  52428800          2 INACTIVE
        4          0  10485760          2 UNUSED
         
SQL> select group#,member from v$logfile;
GROUP# MEMBER                                                   
– —————————————————————-
 3  /u01/oradata/WILSON/onlinelog/o1_mf_3_6bcsqtfj_.log           
 3  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_3_6bcsqtwv_.log
 2  /u01/oradata/WILSON/onlinelog/o1_mf_2_6bcsqs3t_.log           
 2  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_2_6bcsqstm_.log
 1  /u01/oradata/WILSON/onlinelog/o1_mf_1_6bcsqpty_.log           
 1  /u01/flash_recovery_area/WILSON/onlinelog/o1_mf_1_6bcsqqt0_.log
 4 /u01/oradata/WILSON/onlinelog/redo4a.log                     
 4 /u01/flash_recovery_area/WILSON/onlinelog/redo4b.log         
         
8 rows selected

3、关于 redo log sizing

最后聊聊 redo log 的大小问题。在负载较高和投产的系统中,我们经常会遇到 log 过小引起的一系列问题。通过 AWR 报告和 alert log,我们都可以发现这种现象的端倪。

如果系统在关键作业时生成的 redo size 峰值量很高,并且持续很长时间。我们在 Alert log 上可以看到频繁的 online log 切换,同时连带出现“check point not complete”或者“could not allocate log sequence”提示。说明日志切换过于频繁。

从 AWR 报告上,我们主要关注两个与 redo log 相关的事件:log file parallel write 和 log file sync。如果两个事件出现在 top events 中,作为 dba 和调试人员就需要注意了。

在 Oracle 的官方资料中,对 redo log 的大小设置也是以切换频率而定的,要求调整到 15-20 分钟进行一次切换。调整的手段主要是增加日志组数量和调大日志成员文件大小。这样,都可以给 dbwr 和 arc 进程更多的时间在后台进行数据写入和归档。

在实际中,笔者还要建议关注日志组成员的数目,我们对日志采用多路径冗余手段,是为了防止出现单磁盘文件以外损坏。但是,过多的日志成员数目也会带来性能瓶颈。笔者曾见过一个日志组成员数量是 10 个文件,散布在 10 个设备上。这样,就意味 lgwr 要写入十次才能将一个 log entry 写入,性能可想而知。

在 oracle 10g 中,官方提供了视图 v$instance_recovery,也可以提供一定程度的 log 大小建议。

SQL>  show parameter fast_start
     
NAME                                TYPE        VALUE
———————————— ———– ——————————
fast_start_io_target                integer    0
fast_start_mttr_target              integer    0
fast_start_parallel_rollback        string      LOW
     
SQL>
SQL> select ACTUAL_REDO_BLKS,TARGET_REDO_BLKS,TARGET_MTTR,ESTIMATED_MTTR,
  2      OPTIMAL_LOGFILE_SIZE,CKPT_BLOCK_WRITES  from v$instance_recovery;
     
ACTUAL_REDO_BLKS TARGET_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR OPTIMAL_LOGFILE_SIZE CKPT_BLOCK_WRITES
—————- —————- ———– ————– ——————– —————–
            1768            5174          0            16                                    219

日志切换过于频繁,会引起系统整体的 DML 操作等待。所以,如果在调优阶段发现这个问题,首先将其解决和缓解,之后再去看其他的一些问题。

最后,关于 redo log 的生成。我们说,很多时候,DBA 看到过于频繁的 redo size,不要单方面的想着如何满足这样的量。Redo size 是系统进行修改变化操作时候生成的,但是现实中确实存在很多 dml 操作是没有意义的。所以,要进行详细的分析诊断,和需求设计进行沟通。这样才能最大程度的实现调优。

5、结论

Redo log 是 Oracle 进行还原恢复的一个重要组件。Redo log 调整也是 DBA 的基本技能之一。

更多 Oracle 相关信息见 Oracle 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=12

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计13497字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中