一看就會一做就廢系列:說說 RECOVER UNTIL CANCEL


這里是:一看就會,一做就廢系列

數據庫演示版本為 19.3 (12.2.0.3

該系列涉及恢復過程中使用的 個語句:

1. recover database

2. recover database until cancel

3. recover database using backup controlfile

4. recover database until cancel using backup controlfile

5. recover database using backup controlfile until cancel

繼續之前,你得知道什么叫還原 ?什么叫恢復 ?以及備份與恢復的基礎 點我查看己亥清爽系列

恢復級別一共三個:recover database > recover tablespace > recover datafile 本系列目的是為了演示上面 5 條命令的區別與聯系,所以不探討恢復級別以及數據庫狀態對應所使用的恢復級別問題。最高級別 database 已經包含了 tablespace 和 datafile 兩個級別。

版權聲明:博客園 AskScuti 版權所有,未經允許,禁止轉載!

目錄

1. 概念解釋

  1.1 基於數據庫時間點恢復(Database Point-in-Time Recovery)- RMAN

  1.2 基於取消的不完全恢復(Cancel-Based Incomplete Recovery)- SQL命令行

  1.3 基於時間 / SCN 的不完全恢復(Time-Based or Change-Based Incomplete Recovery)- SQL命令行

2. 情況說明

3. 實驗過程

  3.1 備份 CDB

  3.2 創建測試數據

  3.3 刪除所有數據文件

  3.4 破壞歸檔日志文件 

  3.5 重啟數據庫並進行還原操作

  3.6 恢復數據庫

  3.7 打開數據庫

  3.8 驗證數據

 

1. 概念解釋

先理解什么是 until :直到...時候,到...為止,只要見到 until 就知道是不完全恢復(注意:歸檔日志和在線日志都完整的情況下,如果你願意,也可以使用 until 不完全恢復子句進行數據的完全恢復

until 子句的類型分為以下三大類:

1.1 基於數據庫時間點恢復(Database Point-in-Time Recovery)- RMAN

  • until time '2019-01-01 12:00:00' 告訴數據庫,給我(恢復)應用歸檔直到 12 點整為止
  • until scn 1234567 本條命令和上面命令一致,只不過 scn 是用在 RMAN 的,而 change 是用在 SQL 命令行的
  • until sequence 123 也可以在 RMAN 的 run 代碼塊里指定恢復到的日志序列號

1.2 基於取消的不完全恢復(Cancel-Based Incomplete Recovery)- SQL命令行

  • until cancel 僅在 SQL 命令行中有效

1.3 基於時間 / SCN 的不完全恢復(Time-Based or Change-Based Incomplete Recovery)- SQL命令行

  • until time '2019-01-01 12:00:00' 
  • until change 1234567 

其中 1.1 主要用於 RMAN 中的 run 代碼塊,在進行不完全恢復的時候,可以提前進行 set ,例如:

RUN
{
SET UNTIL SCN 1000;
RESTORE DATABASE;
RECOVER DATABASE;
}

你還可以將第一句替換為:

SET UNTIL TIME '2019-01-01 12:00:00';
SET UNTIL SEQUENCE 123;

1.2 和 1.3 小節指的是基於用戶管理(手工)恢復,直接在 SQL 命令行中進行的恢復。這里分類,是為了單獨講解 1.2 小節。個人認為,1.1 小節中基於數據庫時間點恢復其實包括了(Cancle-Based / Time-Based / Change-Based)這些,只不過是為了區分哪些是在 RMAN 里面做,哪些是在 SQL 命令行里面做。

recover database until cancel 這個命令只能在 SQL 命令行進行,它可以通過提示歸檔日志文件的建議名稱進行主動恢復。也就是恢復應用到哪個歸檔,由你自己把控,如果在歸檔和聯機日志都完整的情況下,你甚至可以通過不完全恢復的語句來實現數據的完全恢復

recover database until cancel 命令默認只會應用歸檔日志,而不會自動應用在線日志,這是和 recover database 的區別,后者自動應用所有歸檔和在線日志進行前滾操作

 

2. 情況說明

當前系統中,所有數據文件損壞、歸檔日志不連續、聯機日志完好無損,刪除 CDB 及 PDB 所有數據文件,並采用 RMAN 對所有數據文件進行還原,使用 recover database until cancel 進行不完全恢復。

通過 recover database until cancel 不完全恢復命令,進行完全恢復(條件是什么?如何操作?參考番外:recover database until cancel 的補充說明)

 

3. 實驗過程

3.1 備份 CDB

RMAN> backup database format '/u02/backup/%d_%s_%U.full' tag='full';

3.2 創建測試數據

創建表,插入數據

SQL> create table henry(id number);

Table created.

SQL> insert into henry values(1);

1 row created.

SQL> insert into henry values(2);

1 row created.

SQL> insert into henry values(3);

1 row created.

SQL> commit;

Commit complete.

查看當前使用的日志組狀態

SQL> select group#,sequence#,status from v$log;

    GROUP#  SEQUENCE# STATUS
---------- ---------- -------
     1        1     CURRENT
     2        0     UNUSED
     3        0     UNUSED

當前表數據 1,2,3 在 SEQUENCE 為 1 的日志組中

將表數據 1,2,3 進行歸檔操作

SQL> alter system switch logfile;

System altered.

SQL> alter system checkpoint;

System altered.

SQL> select group#,sequence#,status from v$log;

    GROUP#  SEQUENCE# STATUS
---------- ---------- --------
     1        1     INACTIVE
     2        2     CURRENT
     3        0     UNUSED

 

繼續插入 4,5,6

SQL> insert into henry values(4);

1 row created.

SQL> insert into henry values(5);

1 row created.

SQL> insert into henry values(6);

1 row created.

SQL> commit;

Commit complete.

將表數據 4,5,6 切換日志進行歸檔操作

SQL> alter system switch logfile;

System altered.

SQL> alter system checkpoint;

System altered.

查看當前日志組狀態

SQL> select group#,sequence#,status from v$log;

    GROUP#  SEQUENCE# STATUS
---------- ---------- --------
     1        1     INACTIVE
     2        2     INACTIVE
     3        3     CURRENT

表數據 1,2,3 在 1 號歸檔,4,5,6 在 2 號歸檔,現在數據庫正在使用 sequence 為 3 的在線日志。

 

繼續插入 7,8,9,不生成歸檔,數據 7,8,9 保留至 sequence 為 3 的在線日志里面

SQL> insert into henry values(7);

1 row created.

SQL> insert into henry values(8);

1 row created.

SQL> insert into henry values(9);

1 row created.

SQL> commit;

Commit complete.

SQL> select group#,sequence#,status from v$log;

    GROUP#  SEQUENCE# STATUS
---------- ---------- --------
     1        1     INACTIVE
     2        2     INACTIVE
     3        3     CURRENT

3.3 刪除所有數據文件

SQL> select name from v$datafile;

NAME
-------------------------------------------------
/u01/app/oracle/oradata/CDB1/system01.dbf
/u01/app/oracle/oradata/CDB1/sysaux01.dbf
/u01/app/oracle/oradata/CDB1/undotbs01.dbf
/u01/app/oracle/oradata/CDB1/pdbseed/system01.dbf
/u01/app/oracle/oradata/CDB1/pdbseed/sysaux01.dbf
/u01/app/oracle/oradata/CDB1/users01.dbf
/u01/app/oracle/oradata/CDB1/pdbseed/undotbs01.dbf
/u01/app/oracle/oradata/CDB1/pdb1/system01.dbf
/u01/app/oracle/oradata/CDB1/pdb1/sysaux01.dbf
/u01/app/oracle/oradata/CDB1/pdb1/undotbs01.dbf
/u01/app/oracle/oradata/CDB1/pdb1/users01.dbf
/u01/app/oracle/oradata/CDB1/pdb1/henry01.dbf

刪除

SQL> !rm -rf /u01/app/oracle/oradata/CDB1/pdb1/*

SQL> !rm -rf /u01/app/oracle/oradata/CDB1/pdbseed/*

SQL> !rm -rf /u01/app/oracle/oradata/CDB1/system01.dbf

SQL> !rm -rf /u01/app/oracle/oradata/CDB1/sysaux01.dbf

SQL> !rm -rf /u01/app/oracle/oradata/CDB1/undotbs01.dbf

SQL> !rm -rf /u01/app/oracle/oradata/CDB1/users01.dbf

3.4 破壞歸檔日志文件 

SQL> select name from v$archived_log;

NAME
----------------------------------------------------------------
/u02/oradata/CDB1/archivelog/2019_06_07/o1_mf_1_7_gho256t7_.arc
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_8_gj3c1t2j_.arc
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_9_gj3c1ttr_.arc
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_10_gj3c1z2n_.arc
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_11_gj3c4dvl_.arc
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_12_gj3crh2d_.arc
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_2_gj3gpf1h_.arc

將 2 號歸檔進行重命名,使其不連續(該歸檔保存着 4,5,6)

SQL> !mv /u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_2_gj3gpf1h_.arc /u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_2_gj3gpf1h_.arc.bak

3.5 重啟數據庫並進行還原操作

SQL> startup force;
ORACLE instance started.

Total System Global Area 1241510120 bytes
Fixed Size                9134312 bytes
Variable Size            855638016 bytes
Database Buffers        369098752 bytes
Redo Buffers              7639040 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 1 - see DBWR trace file
ORA-01110: data file 1: '/u01/app/oracle/oradata/CDB1/system01.dbf'

通過 RMAN 進行還原

[oracle@henry ~]$ rman target /

Recovery Manager: Release 19.0.0.0.0 - Production on Thu Jun 13 11:14:11 2019
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

connected to target database: CDB1 (DBID=983951798, not open)

RMAN> restore database from tag='full';

Starting restore at 13-JUN-19
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=11 device type=DISK

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00001 to /u01/app/oracle/oradata/CDB1/system01.dbf
channel ORA_DISK_1: restoring datafile 00003 to /u01/app/oracle/oradata/CDB1/sysaux01.dbf
channel ORA_DISK_1: restoring datafile 00004 to /u01/app/oracle/oradata/CDB1/undotbs01.dbf
channel ORA_DISK_1: restoring datafile 00007 to /u01/app/oracle/oradata/CDB1/users01.dbf
channel ORA_DISK_1: reading from backup piece /u02/backup/CDB1_8_08u40523_1_1.full
channel ORA_DISK_1: piece handle=/u02/backup/CDB1_8_08u40523_1_1.full tag=FULL
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:01:05
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00009 to /u01/app/oracle/oradata/CDB1/pdb1/system01.dbf
channel ORA_DISK_1: restoring datafile 00010 to /u01/app/oracle/oradata/CDB1/pdb1/sysaux01.dbf
channel ORA_DISK_1: restoring datafile 00011 to /u01/app/oracle/oradata/CDB1/pdb1/undotbs01.dbf
channel ORA_DISK_1: restoring datafile 00012 to /u01/app/oracle/oradata/CDB1/pdb1/users01.dbf
channel ORA_DISK_1: restoring datafile 00013 to /u01/app/oracle/oradata/CDB1/pdb1/henry01.dbf
channel ORA_DISK_1: reading from backup piece /u02/backup/CDB1_9_09u4053r_1_1.full
channel ORA_DISK_1: piece handle=/u02/backup/CDB1_9_09u4053r_1_1.full tag=FULL
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:35
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00005 to /u01/app/oracle/oradata/CDB1/pdbseed/system01.dbf
channel ORA_DISK_1: restoring datafile 00006 to /u01/app/oracle/oradata/CDB1/pdbseed/sysaux01.dbf
channel ORA_DISK_1: restoring datafile 00008 to /u01/app/oracle/oradata/CDB1/pdbseed/undotbs01.dbf
channel ORA_DISK_1: reading from backup piece /u02/backup/CDB1_10_0au4054l_1_1.full
channel ORA_DISK_1: piece handle=/u02/backup/CDB1_10_0au4054l_1_1.full tag=FULL
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:36
Finished restore at 13-JUN-19
restore

3.6 恢復數據庫

SQL> recover database until cancel;
ORA-00279: change 2255708 generated at 06/13/2019 10:47:31 needed for thread 1
ORA-00289: suggestion :
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc
ORA-00280: change 2255708 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

程序建議讓我們應用 1 號歸檔  :/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc 

這里有三個選項:filename  AUTO  CANCEL

filename 可以進行手工指定歸檔日志文件名,主動進行,可以隨時停止進行 CANCEL(如果最后指定的歸檔不存在,則報錯,在線日志完整情況下,應該嘗試手工輸入在線日志名稱,以達到完全恢復的效果)

AUTO 指定 AUTO 關鍵字后,會自動應用歸檔日志,直到最后一個可用歸檔(如果最后指定的歸檔不存在,則報錯,在線日志完整情況下,應該嘗試手工輸入在線日志名稱,以達到完全恢復的效果)

CANCEL 指定該關鍵字后,取消當前恢復(這個取消不是回滾所有操作的意思,而是當前取消,恢復到當前這個點)

注意:我們之前將歸檔 2 進行更名,故意讓歸檔日志不連續。歸檔 2 里面保存着(4,5,6)

手工指定(filename)建議歸檔名稱

SQL> recover database until cancel;
ORA-00279: change 2255708 generated at 06/13/2019 10:47:31 needed for thread 1
ORA-00289: suggestion :
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc
ORA-00280: change 2255708 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc
ORA-00279: change 2255918 generated at 06/13/2019 10:53:23 needed for thread 1
ORA-00289: suggestion :
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_2_gj3gpf1h_.arc
ORA-00280: change 2255918 for thread 1 is in sequence #2
ORA-00278: log file
'/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc' no longer
needed for this recovery


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

這時,1 號歸檔恢復完畢,不再需要,建議給出繼續應用 2 號歸檔:/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_2_gj3gpf1h_.arc

可是我們當前系統沒有這個歸檔(被重命名),意味着歸檔無法繼續前滾,因此數據將丟失,這時候輸入 CANCEL 取消恢復即可。

SQL> recover database until cancel;
ORA-00279: change 2255708 generated at 06/13/2019 10:47:31 needed for thread 1
ORA-00289: suggestion :
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc
ORA-00280: change 2255708 for thread 1 is in sequence #1


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc
ORA-00279: change 2255918 generated at 06/13/2019 10:53:23 needed for thread 1
ORA-00289: suggestion :
/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_2_gj3gpf1h_.arc
ORA-00280: change 2255918 for thread 1 is in sequence #2
ORA-00278: log file
'/u02/oradata/CDB1/archivelog/2019_06_13/o1_mf_1_1_gj3go3on_.arc' no longer
needed for this recovery


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
CANCEL
Media recovery cancelled.

完成恢復后,表中數據只有(1,2,3),(4,5,6)歸檔被重命名,因此無法應用,所以數據丟失,包括在線日志里面的(7,8,9)

3.7 打開數據庫

因着執行了不完全恢復(即使某種情況下通過不完全恢復語句完成了數據的完全恢復),必須以 resetlogs 打開數據庫。重置日志組 sequence 號,從 1 開始,新化身出現。

SQL> alter database open resetlogs;

Database altered.

3.8 驗證數據

SQL> select * from henry;

    ID
----------
     1
     2
     3

因為只應用了 1 號歸檔(1,2,3),2 號歸檔被模擬損壞(4,5,6)無法應用,后面在線日志也無法應用(7,8,9),因為日志前滾必須連續,所以最終數據為 1,2,3


免責聲明!

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



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