如果還原存檔的重做日志文件和數據文件,則必須先執行介質恢復,然后才能打開數據庫。歸檔重做日志文件中未反映在數據文件中的任何數據庫事務都將應用於數據文件,從而在打開數據庫之前將它們置於事務一致狀態。
介質恢復需要控制文件,數據文件(通常從備份恢復)以及包含自備份數據文件以來的更改的聯機和歸檔重做日志文件。介質恢復通常用於從介質故障中恢復,例如丟失文件或磁盤,或用戶錯誤,例如刪除表的內容。
媒體恢復可以是完全恢復或時間點恢復。完全恢復可以應用於單個數據文件,表空間或整個數據庫。時間點恢復適用於整個數據庫(有時也適用於單個表空間,具有Oracle Recover Manager(RMAN)的自動化幫助)。
在完全恢復中,您可以還原備份數據文件,並將存檔和聯機重做日志文件中的所有更改應用於數據文件。數據庫在發生故障時返回其狀態,可以在不丟失數據的情況下打開。
在時間點恢復中,您將數據庫返回到過去用戶選擇的時間的內容。您可以還原在目標時間之前創建的數據文件的備份以及從備份創建到目標時間的一整套歸檔重做日志文件。恢復將備份時間和目標時間之間的更改應用於數據文件。目標時間之后的所有更改都將被丟棄。
RMAN使您可以執行數據庫的完整和時間點恢復。但是,本文檔重點介紹完全恢復。
“執行用戶定向恢復”
有關時間點恢復的更多詳細信息,請參見“Oracle數據庫備份和恢復用戶指南”
案例分析實踐
例1:數據庫正常關閉后redo丟失
oracle在正常關閉過程中會將buffer cache中的臟塊都寫入數據文件,同時執行全面檢查點,保證數據庫一致性,所以關閉丟失redo日志,可以以resetlogs打開數據庫不丟失數據。實際上reodo不丟失的話,oracle默認以noresetlogs打開數據庫。
正常關閉數據庫會同步校驗各文件,使得重新啟動的時候文件時間點一致並且不用進行崩潰恢復(Crash Recovery)
- 正常關閉數據庫
SQL> shutdown immediate Database closed. Database dismounted. ORACLE instance shut down.
- 刪除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
- 啟動數據庫至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.
- 執行不完全恢復
SQL> recover database until cancel; Media recovery complete.
- resetlogs打開數據庫
SQL> alter database open resetlogs; Database altered.
啟動成功。resetlogs的解釋參見:oracle的resetlogs機制淺析
linux系統中因為文件句柄的原因,即便在oracle open狀態下刪除redo日志,依然可以正常運行,同時也能正常關閉。如下例子說明:
-
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*
- 查看占用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不丟失
- shutdown abort關閉數據庫
SQL> shutdown abort ORACLE instance shut down.
- 啟動到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.
- 查詢控制文件中記錄的數據文件的檢查點信息以及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進程就開始進行實例恢復了。
- 打開數據庫
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則要重裝數據庫了。)
- 歸檔模式下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.
- 刪除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*
- 啟動到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.
- 查詢控制文件中記錄的數據文件的檢查點信息以及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,異常關閉
- 打開數據庫
參考資料
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 #