• 通过 redo日志恢复数据库


    如果还原存档的重做日志文件和数据文件,则必须先执行介质恢复,然后才能打开数据库。归档重做日志文件中未反映在数据文件中的任何数据库事务都将应用于数据文件,从而在打开数据库之前将它们置于事务一致状态。

    介质恢复需要控制文件,数据文件(通常从备份恢复)以及包含自备份数据文件以来的更改的联机和归档重做日志文件。介质恢复通常用于从介质故障中恢复,例如丢失文件或磁盘,或用户错误,例如删除表的内容。

    媒体恢复可以是完全恢复或时间点恢复。完全恢复可以应用于单个数据文件,表空间或整个数据库。时间点恢复适用于整个数据库(有时也适用于单个表空间,具有Oracle Recover Manager(RMAN)的自动化帮助)。

    在完全恢复中,您可以还原备份数据文件,并将存档和联机重做日志文件中的所有更改应用于数据文件。数据库在发生故障时返回其状态,可以在不丢失数据的情况下打开。

    在时间点恢复中,您将数据库返回到过去用户选择的时间的内容。您可以还原在目标时间之前创建的数据文件的备份以及从备份创建到目标时间的一整套归档重做日志文件。恢复将备份时间和目标时间之间的更改应用于数据文件。目标时间之后的所有更改都将被丢弃。

    RMAN使您可以执行数据库的完整和时间点恢复。但是,本文档重点介绍完全恢复。

    执行用户定向恢复

    有关时间点恢复的更多详细信息,请参见“Oracle数据库备份和恢复用户指南

    案例分析实践

    例1:数据库正常关闭后redo丢失

    oracle在正常关闭过程中会将buffer cache中的脏块都写入数据文件,同时执行全面检查点,保证数据库一致性,所以关闭丢失redo日志,可以以resetlogs打开数据库不丢失数据。实际上reodo不丢失的话,oracle默认以noresetlogs打开数据库。

    正常关闭数据库会同步校验各文件,使得重新启动的时候文件时间点一致并且不用进行崩溃恢复(Crash Recovery)

    1. 正常关闭数据库
      SQL> shutdown immediate
      Database closed.
      Database dismounted.
      ORACLE instance shut down.
    2. 删除redo日志
      复制代码
      -rw-r----- 1 oracle oinstall   9748480 Jul 10 14:55 control01.ctl
      -rw-r----- 1 oracle oinstall  52429312 Jul 10 04:00 redo01.log
      -rw-r----- 1 oracle oinstall  52429312 Jul 10 11:00 redo02.log
      -rw-r----- 1 oracle oinstall  52429312 Jul 10 14:55 redo03.log
      -rw-r----- 1 oracle oinstall 660611072 Jul 10 14:55 sysaux01.dbf
      -rw-r----- 1 oracle oinstall 786440192 Jul 10 14:55 system01.dbf
      -rw-r----- 1 oracle oinstall  30416896 Jul 10 14:45 temp01.dbf
      -rw-r----- 1 oracle oinstall  94380032 Jul 10 14:55 undotbs01.dbf
      -rw-r----- 1 oracle oinstall   5251072 Jul 10 14:55 users01.dbf
      [oracle@zml-rhel6 orcl63]$ rm -f redo0*
      [oracle@zml-rhel6 orcl63]$ ll
      total 1523900
      -rw-r----- 1 oracle oinstall   9748480 Jul 10 14:55 control01.ctl
      -rw-r----- 1 oracle oinstall 660611072 Jul 10 14:55 sysaux01.dbf
      -rw-r----- 1 oracle oinstall 786440192 Jul 10 14:55 system01.dbf
      -rw-r----- 1 oracle oinstall  30416896 Jul 10 14:45 temp01.dbf
      -rw-r----- 1 oracle oinstall  94380032 Jul 10 14:55 undotbs01.dbf
      -rw-r----- 1 oracle oinstall   5251072 Jul 10 14:55 users01.dbf
      复制代码
    3. 启动数据库至MOUNT
      复制代码
      SQL> startup mount
      ORACLE instance started.
      
      Total System Global Area 4993982464 bytes
      Fixed Size            2261808 bytes
      Variable Size         1040190672 bytes
      Database Buffers     3942645760 bytes
      Redo Buffers            8884224 bytes
      Database mounted.
      复制代码
    4. 执行不完全恢复
      SQL> recover database until cancel;
      Media recovery complete.
    5. resetlogs打开数据库
      SQL> alter database open resetlogs;
      
      Database altered.

    启动成功。resetlogs的解释参见:oracle的resetlogs机制浅析

    linux系统中因为文件句柄的原因,即便在oracle open状态下删除redo日志,依然可以正常运行,同时也能正常关闭。如下例子说明:

    1. open状态删除redo

      复制代码
      -rw-r----- 1 oracle oinstall   9748480 Jul 10 15:05 control01.ctl
      -rw-r----- 1 oracle oinstall  52429312 Jul 10 15:05 redo01.log
      -rw-r----- 1 oracle oinstall  52429312 Jul 10 15:02 redo02.log
      -rw-r----- 1 oracle oinstall  52429312 Jul 10 15:02 redo03.log
      -rw-r----- 1 oracle oinstall 660611072 Jul 10 15:02 sysaux01.dbf
      -rw-r----- 1 oracle oinstall 786440192 Jul 10 15:02 system01.dbf
      -rw-r----- 1 oracle oinstall  30416896 Jul 10 14:45 temp01.dbf
      -rw-r----- 1 oracle oinstall  94380032 Jul 10 15:02 undotbs01.dbf
      -rw-r----- 1 oracle oinstall   5251072 Jul 10 15:02 users01.dbf
      [oracle@zml-rhel6 orcl63]$ rm -f redo0*
      复制代码
    2. 查看占用redo文件的进程
      复制代码
      [oracle@zml-rhel6 orcl63]$ lsof|grep redo
      lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /root/.gvfs
            Output information may be incomplete.
      oracle    27082    oracle  258u      REG                8,3  52429312    6684835 /u01/app/oracle/oradata/orcl63/redo01.log (deleted)
      oracle    27082    oracle  259u      REG                8,3  52429312    6684838 /u01/app/oracle/oradata/orcl63/redo02.log (deleted)
      oracle    27082    oracle  260u      REG                8,3  52429312    6684839 /u01/app/oracle/oradata/orcl63/redo03.log (deleted)
      复制代码
      [oracle@zml-rhel6 orcl63]$ ps -ef|grep 27082
      oracle   27082     1  0 14:59 ?        00:00:00 ora_lgwr_orcl63
      oracle   28808 23232  0 15:08 pts/2    00:00:00 grep 27082

      可以看到redo log文件被系统标记为deleted,但是没有真正的删除,该文件正在被进程lgwr占用。linux的文件句柄会在应用程序关闭后才会释放文件,所以此期间即便删除了也可以正常关闭数据库。此后再以resetlogs启动便可。

    例2:数据库异常关闭(kill or shutdown abort)的恢复

     数据库异常关闭kill或shutdown abort,这个时候文件状态可能不一致。若检查点信息一致,则做崩溃恢复。若检查点信息不一致(正好在更新文件头)则需要做介质恢复。

     以下演示redo不丢失和丢失的情况

    一、redo不丢失

    1. shutdown abort关闭数据库
      SQL> shutdown abort
      ORACLE instance shut down.
    2. 启动到MOUNT
      复制代码
      SQL> startup mount
      ORACLE instance started.
      
      Total System Global Area 4993982464 bytes
      Fixed Size            2261808 bytes
      Variable Size         1040190672 bytes
      Database Buffers     3942645760 bytes
      Redo Buffers            8884224 bytes
      Database mounted. 
      复制代码
    3. 查询控制文件中记录的数据文件的检查点信息以及END SCN信息
      复制代码
      SQL> select file#,checkpoint_change#,last_change# from v$datafile;
      
           FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
      ---------- ------------------ ------------
           1          1602035
           2          1602035
           3          1602035
           4          1602035
      复制代码

      可以看到END SCN为NULL,说明数据库上次是异常关闭。     

      数据库正常运行过程中,该END SCN号始终为NULL。而当数据库正常关闭时,会进行完全检查点,并将检查点SCN号更新该字段。而崩溃时,Oracle还来不及更新该字段,则该字段仍然为NULL。当SMON进程发现该字段为空时,就知道实例在上次没有正常关闭,于是由SMON进程就开始进行实例恢复了。
    4. 打开数据库
      SQL> alter database open;
      
      Database altered.

      查看此过程的告警日志:
      (从告警日志红色标注内容可知,打开过程中,数据库进行了crash recovery,应用redo日志进行前滚和回滚操作)

      复制代码
      Wed Jul 11 16:16:49 2018
      alter database open
      Beginning crash recovery of 1 threads
       parallel recovery started with 15 processes
      Started redo scan
      Completed redo scan
       read 175 KB redo, 97 data blocks need recovery
      Started redo application at
       Thread 1: logseq 9, block 782
      Recovery of Online Redo Log: Thread 1 Group 3 Seq 9 Reading mem 0
        Mem# 0: /u01/app/oracle/oradata/orcl63/redo03.log
      Completed redo application of 0.13MB
      Completed crash recovery at
       Thread 1: logseq 9, block 1133, scn 1622464
       97 data blocks read, 97 data blocks written, 175 redo k-bytes read
      Wed Jul 11 16:16:49 2018
      Thread 1 advanced to log sequence 10 (thread open)
      Thread 1 opened at log sequence 10
        Current log# 1 seq# 10 mem# 0: /u01/app/oracle/oradata/orcl63/redo01.log
      Successful open of redo thread 1
      MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set
      Wed Jul 11 16:16:49 2018
      SMON: enabling cache recovery
      [15322] Successfully onlined Undo Tablespace 2.
      Undo initialization finished serial:0 start:2869436558 end:2869436588 diff:30 (0 seconds)
      Verifying file header compatibility for 11g tablespace encryption..
      Verifying 11g file header compatibility for tablespace encryption completed
      SMON: enabling tx recovery
      Database Characterset is ZHS16GBK
      No Resource Manager plan active
      replication_dependency_tracking turned off (no async multimaster replication found)
      Starting background process QMNC
      Wed Jul 11 16:16:50 2018
      QMNC started with pid=36, OS id=16458 
      Completed: alter database open
      Wed Jul 11 16:16:50 2018
      db_recovery_file_dest_size of 41820 MB is 0.00% used. This is a
      user-specified limit on the amount of space that will be used by this
      database for recovery-related files, and does not reflect the amount of
      space available in the underlying filesystem or ASM diskgroup.
      Wed Jul 11 16:16:50 2018
      Starting background process CJQ0
      Wed Jul 11 16:16:50 2018
      CJQ0 started with pid=38, OS id=16472

      ---------------------------------------------------------------------------------------------------------
      关于应用redo日志进行前滚和回滚的说明如下:

      复制代码

    二、redo丢失(数据库处于归档模式下,归档不丢失)

    (归档没有用,数据库异常关闭,数据库未进行完全检查点,需要redo进行crash recovery,而异常关闭时,归档进行可能都没有来得及将redo日志刷到归档日志中。这种情况只能通过不完全恢复后,修改参数文件允许resetlogs启动,强制以resetlogs,即不一致启动,但是可能导致ora-00600。如果有ora-00600则要重装数据库了。)

    1. 归档模式下shutdown immediate关闭数据库
      复制代码
      SQL> archive log list
      Database log mode           Archive Mode
      Automatic archival           Enabled
      Archive destination           USE_DB_RECOVERY_FILE_DEST
      Oldest online log sequence     8
      Next log sequence to archive   10
      Current log sequence           10
      SQL> shutdown abort
      ORACLE instance shut down.
      复制代码
    2. 删除redo日志
      复制代码
      [oracle@zml-rhel6 orcl63]$ ls -rlt
      total 1698848
      -rw-r----- 1 oracle oinstall  52429312 Jul 11 16:59 redo03.log
      -rw-r----- 1 oracle oinstall  52429312 Jul 11 16:59 redo02.log
      -rw-r----- 1 oracle oinstall  94380032 Jul 11 16:59 undotbs01.dbf
      -rw-r----- 1 oracle oinstall 786440192 Jul 11 16:59 system01.dbf
      -rw-r----- 1 oracle oinstall 681582592 Jul 11 16:59 sysaux01.dbf
      -rw-r----- 1 oracle oinstall   5251072 Jul 11 16:59 users01.dbf
      -rw-r----- 1 oracle oinstall  30416896 Jul 11 16:59 temp01.dbf
      -rw-r----- 1 oracle oinstall  52429312 Jul 11 17:00 redo01.log
      -rw-r----- 1 oracle oinstall   9748480 Jul 11 17:00 control01.ctl
      [oracle@zml-rhel6 orcl63]$ rm -f redo0*
      复制代码
    3. 启动到mount
      复制代码
      SQL> startup mount
      ORACLE instance started.
      
      Total System Global Area 4993982464 bytes
      Fixed Size            2261808 bytes
      Variable Size         1040190672 bytes
      Database Buffers     3942645760 bytes
      Redo Buffers            8884224 bytes
      Database mounted.
      复制代码
    4. 查询控制文件中记录的数据文件的检查点信息以及END SCN信息
      复制代码
      SQL> select file#,checkpoint_change#,last_change# from v$datafile;
      
           FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
      ---------- ------------------ ------------
           1          1627660
           2          1627660
           3          1627660
           4          1627660
      复制代码

       LAST_CHANGE#为NULL,异常关闭

    5. 打开数据库

    参考资料

    https://blog.csdn.net/liaocongyuan1314/article/details/50847529

    总结:只有current和active状态的redo日志丢失或损坏,且数据库异常关闭,如kill或者abort,才会丢失数据!其他都可以进行恢复。

    从日志回复数据库 :自己一步一步按照说明试着看
    --创建测试数据库
    CREATE DATABASE Db
    GO
    --对数据库进行备份
    BACKUP DATABASE Db TO DISK='c:db.bak' WITH FORMAT
    GO
    --创建测试表
    CREATE TABLE Db.dbo.TB_test(ID int)
    --延时1秒钟,再进行后面的操作(这是由于SQL Server的时间精度最大为百分之三秒,不延时的话,可能会导致还原到时间点的操作失败)
    WAITFOR DELAY '00:00:01'
    GO
    --假设我们现在误操作删除了 Db.dbo.TB_test 这个表
    DROP TABLE Db.dbo.TB_test
    --保存删除表的时间
    SELECT dt=GETDATE() INTO #
    GO
    --在删除操作后,发现不应该删除表 Db.dbo.TB_test
    --下面演示了如何恢复这个误删除的表 Db.dbo.TB_test
    --首先,备份事务日志(使用事务日志才能还原到指定的时间点)
    BACKUP LOG Db TO DISK='c:db_log.bak' WITH FORMAT
    GO
    --接下来,我们要先还原完全备份(还原日志必须在还原完全备份的基础上进行)
    RESTORE DATABASE Db FROM DISK='c:db.bak' WITH REPLACE,NORECOVERY
    GO
    --将事务日志还原到删除操作前(这里的时间对应上面的删除时间,并比删除时间略早
    DECLARE @dt datetime
    SELECT @dt=DATEADD(ms,-20,dt) FROM # --获取比表被删除的时间略早的时间
    RESTORE LOG Db FROM DISK='c:db_log.bak' WITH RECOVERY,STOPAT=@dt
    GO
    --查询一下,看表是否恢复
    SELECT * FROM Db.dbo.TB_test

    /*--结果:
    ID
    -----------

    (所影响的行数为 0 行)
    --*/

    --测试成功
    GO

    --最后删除我们做的测试环境
    DROP DATABASE Db
    DROP TABLE #

  • 相关阅读:
    hdu5833----高斯消元
    高斯消元模板
    hdu4462--曼哈顿距离
    卡特兰数应用
    poj3070矩阵快速幂求斐波那契数列
    poj1042
    poj1328
    mvc 请求处理管道
    sql update 代替游标写法
    sql 表字段模糊连接
  • 原文地址:https://www.cnblogs.com/klb561/p/10962820.html
Copyright © 2020-2023  润新知