通過 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 #


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM