01. Oracle 实例恢复

转载自:https://blog.csdn.net/leshami/article/details/5768233

一、Oracle实例失败

Oracle实例失败多为实例非一致性关闭所致,通常称为崩溃(crash)。实例失败的结果等同于shutdown abort。
--实例失败的原因
    电源负载故障
    硬件故障
    后台进程失败
    异常关闭数据库
--实例失败后的状况
    数据库可能丢失已提交的事务以及存储了未提交的事务,导致数据库出现不一致的情况
--解决方案
    使用startup 重新启动实例。实例实现自动恢复,根据联机日志文件前滚提交的事务,回滚未提交的事务
    查看告警日志、跟踪日志等找出出现故障的原因

二、检查点

检查点在体系结构中已经讨论,实例的恢复与检查点息息相关,因此再次讨论检查点进程

1.什么是检查点
    是一个数据库事件,用于减少崩溃恢复时间,检查点位置决定了实例恢复的起始位置
    由后台进程触发,触发时ckpt进程通知dbwn进程将数据缓冲区的脏数据写入到数据文件
    ckpt进程同时负责更新数据文件的头部信息及控制文件上的检查点信息
    
2.检查点的触发条件
        在日志切换的时候(自动切换或手动切换)
        数据库用immediate ,transaction ,normal选项shutdown数据库的时候
        用户手动触发(alter system checkpoint)
        alter tablespace tablespace_name begin | end bakcup 
        alter tablespace tablespace_name offline
        alter database datafile '<dir>' offline
        alter tablespace | datafile read only
        
3.检测点队列
    是一个脏数据库链表
    检查点队列中的每一条修改过的记录包一个唯一的数据块标识符(日志文件号,块编号,偏移量)
    最早队列将被优先写入到数据文件(而不论期间是否被多次修改)
    最早队列被写入完成后将从队列中清除
    
4.检查点的分类
    完全检查点
        在Oracle 8i 以前,当检查点发生时,Oracle将脏缓冲列表上的数据全部写入到数据文件,称为完全检查点,又称常规检查点
        特定的触发条件
            alter system switch logfile 
            shutdown normal,immediate,transactional
            alter system checkpoint
    增量检查点(fast-start checkpoint)
        主要是引入了检查点队列机制,每s,ckpt将检查点队列中最老的RBA更新到控制文件,RBA(重做日志块地址)同时将作为实例恢复的起点
        增量检查点则细分了完全检查点,使得数据可以周期性按最老的数据块写入到数据文件
        每一个脏块会被移到检查点队列里面去,按照LRBA(Low RBA第一次对此块修改对应的redo block address)来排列
        最早写入检查点队列数据块的low rba值是最小的,即便该队列中的最小队列被修改多次,但修改后它在检查点队列里的顺序不会改变
        当执行增量检查点时,DBWn从检查点队列按照LRBA的顺序来保证先修改的数据可以按顺序优先被写出来实现检查点的增进
        此时ckpt进程使用轻量级的控制文件更新协议,将当前最低的RBA写入控制文件
        ckpt在进行轻量级更新时,并不会改写控制文件中数据文件的检查点信息及数据文件头信息
        仅仅是记录控制文件检查点SCN并根据增量检查点写出增进RBA信息
        通过将完全检查点转变为增量检查点将大大缩短实例的恢复时间
        注:更新数据文件头部及控制文件滞后于检查点事件的发生
        增量检查点的触发    
            满足初始话文件log_checkpoint_interval、log_checkpoint_timeout、
                          fast_start_io_target、fast_start_mttr_target的设置的值
            最小的日志文件的大小
            Buffer Cacha中脏块的数量

    部分检查点
        表空间的脏数据写入到磁盘
        由alter tablespace tablespace_name offline 触发

5.完全检查点与增量检查点的差异
    完全检查点会将检查点的信息同时写入到控制文件及数据文件
    增量检查点则只将RBA写入到控制文件

6.查看检查点的信息,设置LOG_CHECKPOINTS_TO_ALERT参数为true
    ALTER SYSTEM SET LOG_CHECKPOINTS_TO_ALERT = TRUE ;

--查看log_checkpoints_to_alert参数
    SQL> SHOW PARAMETER log_checkpoints_to_alert

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    log_checkpoints_to_alert             boolean     FALSE

--设置log_checkpoints_to_alert参数
    SQL> ALTER SYSTEM set log_checkpoints_to_alert = TRUE;

    System altered.     
    
--清空告警日志文件的内容
    SQL> ho cat /dev/null > /u01/app/oracle/admin/orcl/bdump/alert_orcl.log

--查看数据文件头部信息中控制文件的信息为3037172
SQL> SELECT file#,status,tablespace_name ,
  2  dbms_flashback.get_system_change_number cur_scn,
  3  to_char(resetlogs_time,'yyyy-mm-dd hh24:mi:ss') rst_dt,
  4  resetlogs_change# rst_scn,
  5  to_char(checkpoint_time,'yyyy-mm-dd hh24:mi:ss') ckpt_dt,
  6  checkpoint_change# ckpt_scn,checkpoint_count ckpt_cnt
  7  FROM v$datafile_header;

     FILE# STATUS  TABLESPACE_NAME    CUR_SCN RST_DT                 RST_SCN CKPT_DT               CKPT_SCN   CKPT_CNT
---------- ------- --------------- ---------- ------------------- ---------- ------------------- ---------- ----------
         1 ONLINE  SYSTEM             3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        531
         2 ONLINE  UNDOTBS1           3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        493
         3 ONLINE  SYSAUX             3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        532
         4 ONLINE  USERS              3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        534
         5 ONLINE  EXAMPLE            3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        489
         6 ONLINE  TBS1               3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        412
         7 ONLINE  TBS1               3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        407
7 rows selected.

SQL> save /u01/app/oracle/oradata/query_1.sql;
Created file /u01/app/oracle/oradata/query_1.sql

    SQL> ALTER SYSTEM SWITCH LOGFILE;  --切换日志

    System altered.
             
    SQL> ho cat /u01/app/oracle/admin/orcl/bdump/alert_orcl.log | more  --查看告警日志
    Sun Jul 25 19:14:29 2010
    Beginning log switch checkpoint up to RBA [0xd.2.10], SCN: 3037657
    Thread 1 advanced to log sequence 13
      Current log# 3 seq# 13 mem# 0: /u01/app/oracle/oradata/orcl/redo3a.rdo
      Current log# 3 seq# 13 mem# 1: /u01/app/oracle/oradata/orcl/redo3b.rdo

SQL> @/u01/app/oracle/oradata/query_1.sql;   --数据文件头部滞后分钟后与告警日志记录的SCN相同

     FILE# STATUS  TABLESPACE_NAME    CUR_SCN RST_DT                 RST_SCN CKPT_DT               CKPT_SCN   CKPT_CNT
---------- ------- --------------- ---------- ------------------- ---------- ------------------- ---------- ----------
         1 ONLINE  SYSTEM             3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        532
         2 ONLINE  UNDOTBS1           3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        494
         3 ONLINE  SYSAUX             3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        533
         4 ONLINE  USERS              3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        535
         5 ONLINE  EXAMPLE            3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        490
         6 ONLINE  TBS1               3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        413
         7 ONLINE  TBS1               3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        408

SQL> SELECT TO_CHAR(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM dual;  --时间滞后分钟 19:19:59 - 19:14:29

TO_CHAR(SYSDATE,'YY'
-------------------
2010-07-25 19:19:59

    SQL> ALTER SYSTEM CHECKPOINT;  --产生检查点

    System altered.

    SQL> ho cat /u01/app/oracle/admin/orcl/bdump/alert_orcl.log | more  --查看告警日志中的SCN: 3037881
    Sun Jul 25 19:14:29 2010
    Beginning log switch checkpoint up to RBA [0xd.2.10], SCN: 3037657
    Thread 1 advanced to log sequence 13
      Current log# 3 seq# 13 mem# 0: /u01/app/oracle/oradata/orcl/redo3a.rdo
      Current log# 3 seq# 13 mem# 1: /u01/app/oracle/oradata/orcl/redo3b.rdo
    Sun Jul 25 19:19:34 2010
    Completed checkpoint up to RBA [0xd.2.10], SCN: 3037657
    Sun Jul 25 19:21:55 2010
    Beginning global checkpoint up to RBA [0xd.116.10], SCN: 3037881
    Completed checkpoint up to RBA [0xd.116.10], SCN: 3037881

SQL> @/u01/app/oracle/oradata/query_1.sql;  --数据文件头部同步与告警日志记录的SCN相同,为3037881

     FILE# STATUS  TABLESPACE_NAME    CUR_SCN RST_DT                 RST_SCN CKPT_DT               CKPT_SCN   CKPT_CNT
---------- ------- --------------- ---------- ------------------- ---------- ------------------- ---------- ----------
         1 ONLINE  SYSTEM             3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        533
         2 ONLINE  UNDOTBS1           3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        495
         3 ONLINE  SYSAUX             3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        534
         4 ONLINE  USERS              3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        536
         5 ONLINE  EXAMPLE            3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        491
         6 ONLINE  TBS1               3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        414
         7 ONLINE  TBS1               3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        409

--查看完全检查点            
    SQL> SELECT addr,indx ,rtckp_scn,
      2    rtckp_tim,
      3    rtckp_rba_seq,rtckp_rba_bno
      4  FROM x$kccrt;

    ADDR           INDX RTCKP_SCN        RTCKP_TIM            RTCKP_RBA_SEQ RTCKP_RBA_BNO
    -------- ---------- ---------------- -------------------- ------------- -------------
    B7D59C10          0 3037881          07/25/2010 19:21:55             13           278       

    SQL> show parameter log_check  --查看log_checkpoint_timeout的值

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    log_checkpoint_interval              integer     0
    log_checkpoint_timeout               integer     1800
    log_checkpoints_to_alert             boolean     TRUE
    
    ho cat  /u01/app/oracle/admin/orcl/bdump/alert_orcl.log --告警日志文件中Incremental checkpoint
    ----------------------------------------------------------------------------------      
    Sun Jul 25 19:22:46 2010
    Incremental checkpoint up to RBA [0xd.119.0], current log tail at RBA [0xd.119.0]
    Sun Jul 25 19:52:51 2010
    Incremental checkpoint up to RBA [0xd.37a.0], current log tail at RBA [0xd.420.0]

    ---------------------------------------------------------------------------------
    SQL> select CPDRT,CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low RBA",
      2  CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk RBA",CPODS,CPODT,CPHBT 
      3  from x$kcccp where indx = 0;  --获得控制文件中增量检查点的信息

         CPDRT Low RBA             On disk RBA   CPODS   CPODT                  CPHBT
    ---------- ------------------- ------------- ------- --------------------   --------
           97 13.5574.0            13.6391.0     3041226 07/25/2010 22:16:37    725323317
           
        --CPDRT列是检查点队列中的脏块数目.
        --CPODS列是on disk rba的scn
        --CPODT列是on disk rba的时间戳
        --CPHBT列是心跳

7.更详细的检查点介绍:针对checkpoint的概要分析
                      晶晶实验九之详细论述增量检查点篇

三、实例恢复

1.当打开非一致性关闭或shutdown abort数据库时,将导致实例恢复
2.实例恢复过程为自动
3.使用联机重做日志文件中的信息来同步数据文件
4.涉及到两类不同的操作
    前滚:数据文件被还原到实例失败之前的状态
    回滚:已修改但未提交的数据将被撤销到修改之前的状态

四、实例恢复的过程

下面的图片来自Oracle官方教材

1.首先Oracle会比较控制文件中检查点与数据文件头部信息,发现数据不一致
2.从最后检查点之后到日志文件尾部将被重新应用到数据文件,同时产生undo信息(回滚),此阶段也称为cache recovery
3.数据文件中包含已提交或未提交的数据,尽管存在未提交的数据,此时数据库已经被打开,允许用户连接
4.未提交的事务将被回滚
5.数据文件中仅包含已提交的数据

五、调整实例恢复

1.为参数文件中对恢复过程有影响的联机日志记录数量和数据块设置合适的大小
2.调整联机日志文件的大小来影响检查点发生的频率
3.使用SQL 命令发生检查点事件
4.使用Fast-start fault recovery 
5.几个恢复相关的参数
    LOG_CHECKPOINT_TIMEOUT        -->两次checkpoint之间间隔的时间(单位是秒) ,该参数现已很少使用
    LOG_CHECKPOINT_INTERVAL       -->两次checkpoint之间redo block 数据块的个数(不是db_block),
                                        --   redo block size = os block size 该参数现已很少使用
    FAST_START_MTTR_TARGET        -->指定多长时间完成实例恢复(单位是秒) (后面演示中重点讨论)
    RECOVERY_PARALLELISM          -->指定前滚时的并发度
    FAST_START_PARALLEL_ROLLBACK  -->回滚阶段时预先UNDO需要使用的块,然后增加回滚并发度
                                        -- 2路CPU建议设置为LO,四路CPU建议设置为HI,否则缺省置为false
    FAST_START_IO_TARGET          -->数据库宕机所要做的恢复所需的IO的数量,10g之后很少使用

六、实例恢复相关的视图 

V$INSTACE_RECOVERY                -->查看fast_start_mttr_target设置以及系统MTTR相关信息
V$FAST_START_SERVERS              -->事务回滚时相关并发信息
V$FAST_START_TRANSACTION          -->正在恢复的事务的相关信息
完全检查点
    select * from X$KCCRT where indx=0;
        
增量检查点
    SQL> select * from X$KCCCP where indx=0;

七、实例恢复演示   

--删除告警日志
    SQL> ho rm -f /u01/app/oracle/admin/orcl/bdump/alert_orcl.log        

    SQL> SELECT * FROM scott.emp WHERE ename = 'SCOTT';

         EMPNO ENAME                          JOB              MGR HIREDATE         SAL     DEPTNO
    ---------- ------------------------------ --------- ---------- --------- ---------- ----------
          7788 SCOTT                          ANALYST         7566 19-APR-87       7100         20
          
--更新SCOTT的薪水且提交事务
    SQL> UPDATE scott.emp SET sal = sal / 2 WHERE ename = 'SCOTT';

    1 row updated.

    SQL> COMMIT;

    Commit complete.

--插入两条新记录且不提交事务
    SQL> INSERT INTO scott.emp(empno,ename,job) SELECT '2001','Mark','Develpoer' FROM dual;

    1 row created.

    SQL> INSERT INTO scott.emp(empno,ename,job) SELECT '2002','Mary','Designer' FROM dual;

    1 row created.

    SQL> SELECT * FROM scott.emp WHERE empno IN (2001,2002);

         EMPNO ENAME                          JOB              MGR HIREDATE         SAL     DEPTNO
    ---------- ------------------------------ --------- ---------- --------- ---------- ----------
          2001 Mark                           Develpoer
          2002 Mary                           Designer

--强制关闭实例并重启实例,则实例将自动回滚
    SQL> SHUTDOWN ABORT;
    ORACLE instance shut down.
    SQL> STARTUP
    ORACLE instance started.

    Total System Global Area  251658240 bytes
    Fixed Size                  1218796 bytes
    Variable Size              88082196 bytes
    Database Buffers          159383552 bytes
    Redo Buffers                2973696 bytes
    Database mounted.
    Database opened.

--从告警日志中获得回滚的相关信息
SQL> ho ls /u01/app/oracle/admin/orcl/bdump
alert_orcl.log  orcl_arc0_4016.trc  orcl_arc1_4018.trc  orcl_lgwr_3995.trc

SQL> ho cat /u01/app/oracle/admin/orcl/bdump/alert_orcl.log

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

    ALTER DATABASE   MOUNT
    Thu Jul 22 12:44:40 2010
    Setting recovery target incarnation to 10
    Thu Jul 22 12:44:40 2010
    Successful mount of redo thread 1, with mount id 1252833332
    Thu Jul 22 12:44:40 2010
    Database mounted in Exclusive Mode
    Completed: ALTER DATABASE   MOUNT
    Thu Jul 22 12:44:41 2010
    ALTER DATABASE OPEN
    Thu Jul 22 12:44:41 2010
    Beginning crash recovery of 1 threads  --开始crash recovery
    Thu Jul 22 12:44:41 2010
    Started redo scan                      --扫描redo
    Thu Jul 22 12:44:42 2010
    Completed redo scan
     142 redo blocks read, 58 data blocks need recovery
    Thu Jul 22 12:44:42 2010
    Started redo application at
     Thread 1: logseq 4, block 3156
    Thu Jul 22 12:44:42 2010
    Recovery of Online Redo Log: Thread 1 Group 3 Seq 4 Reading mem 0
      Mem# 0 errs 0: /u01/app/oracle/oradata/orcl/redo3a.rdo
      Mem# 1 errs 0: /u01/app/oracle/oradata/orcl/redo3b.rdo
    Thu Jul 22 12:44:42 2010
    Completed redo application
    Thu Jul 22 12:44:43 2010
    Completed crash recovery at         --完成恢复
     Thread 1: logseq 4, block 3298, scn 2921577
     58 data blocks read, 58 data blocks written, 142 redo blocks read
    Thu Jul 22 12:44:43 2010
    LGWR: STARTING ARCH PROCESSES
    ARC0: Archival started
    ARC1: Archival started
    LGWR: STARTING ARCH PROCESSES COMPLETE
    ARC1 started with pid=17, OS id=4018
    ARC0 started with pid=16, OS id=4016
    Thu Jul 22 12:44:45 2010
    Thread 1 advanced to log sequence 5
    Thread 1 opened at log sequence 5
      Current log# 1 seq# 5 mem# 0: /u01/app/oracle/oradata/orcl/redo1a.rdo
      Current log# 1 seq# 5 mem# 1: /u01/app/oracle/oradata/orcl/redo1b.rdo
    Successful open of redo thread 1
    Thu Jul 22 12:44:45 2010
    MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set --FAST_START_MTTR_TARGET未设置

    --------------------------------------------------------------------------------------------------
    --对scott用户已提交,故恢复之后为已提交的状态
    SQL> SELECT * FROM scott.emp WHERE ename = 'SCOTT';

         EMPNO ENAME                          JOB              MGR HIREDATE         SAL     DEPTNO
    ---------- ------------------------------ --------- ---------- --------- ---------- ----------
          7788 SCOTT                          ANALYST         7566 19-APR-87       3550         20

    --新增加的两条记录未提交,实例恢复之后被回滚      
    SQL> SELECT * FROM scott.emp WHERE empno IN (2001,2002);

    no rows selected

八、设置FAST_START_MTTR_TARGET参数

FAST_START_MTTR_TARGET参数的作用就是减少cache recovery的恢复时间。
当设定了FAST_START_MTTR_TARGET值后,数据库管理增量检查点写入尝试达到设定的目标恢复时间
如果设定的值合理,则整个恢复过程将接近所设定的时间
注:当使用FAST_START_MTTR_TARGET参数时,应当关闭FAST_START_IO_TARGET, LOG_CHECKPOINT_INTERVAL, 
    LOG_CHECKPOINT_TIMEOUT 参数。如果设定这些参数将会妨碍cache recovery满足指定的FAST_START_MTTR_TARGET值
应当为FAST_START_MTTR_TARGET设置合理的时间值
    缺省值为0,表示关闭检查点自动调整功能
    最大值为3600,当设定值大于3600,将被自动取整为3600
    最小值为1,当设定为时1,事实上不切合实际因此,恢复时间也不能达到设定的目标值 */
    
更多关于FAST_START_MTTR_TARGET参数的优化:Instance Recovery Performance Tuning: Fast-Start Fault Recovery
      
--将fast_start_mttr_target的值置为0
SQL> alter system set fast_start_mttr_target = 0;

System altered.

SQL> CREATE TABLE tb_test AS SELECT * FROM all_objects WHERE 1=2; --新建一张表

Table created.

SQL> INSERT INTO tb_test SELECT * FROM all_objects;  --插入记录到新表

49945 rows created.

--下面的查询中可以看到ESTIMATED_MTTR为28
    SQL> SELECT recovery_estimated_ios,actual_redo_blks,target_mttr,estimated_mttr,
      2  optimal_logfile_size  FROM v$instance_recovery;

    RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR OPTIMAL_LOGFILE_SIZE
    ---------------------- ---------------- ----------- -------------- --------------------
                       762            11661           0             28

    SQL> COMMIT;   --提交事务

    Commit complete.
    
    SQL> SELECT recovery_estimated_ios,actual_redo_blks,target_mttr,estimated_mttr,
      2  optimal_logfile_size  FROM v$instance_recovery;

    RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR OPTIMAL_LOGFILE_SIZE
    ---------------------- ---------------- ----------- -------------- --------------------
                       767            11669           0             28      

--由上可知,commit仅仅是将日志缓冲区的内容更新到日志文件

    SQL> ALTER SYSTEM CHECKPOINT;  --手动更新检查点

    System altered.

    SQL> SELECT recovery_estimated_ios,actual_redo_blks,target_mttr,estimated_mttr,
      2  optimal_logfile_size  FROM v$instance_recovery;

    RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR OPTIMAL_LOGFILE_SIZE
    ---------------------- ---------------- ----------- -------------- --------------------
                         0                0           0             28      
        
--上面的查询可以看到字段RECOVERY_ESTIMATED_IOS和ACTUAL_REDO_BLKS 的值已经减少到0
--检查点的产生将database buffer中的脏内容写入到了数据文件中
--ESTIMATED_MTTR没有发生变化,因为该列为非实时更新列

  

 

原文地址:https://www.cnblogs.com/zhuntidaoren/p/8664943.html