Oracle 备份恢复原理
1. 完全脱机备份 - 冷备份
--
首先查看所有的文件(数据文件、控制文件、日志文件)存放路径(企业生产环境下,数据文件不一定都存放在同一个指定目录。 需要查询确认
)
-- 数据文件
SQL > select file_name , status from dba_data_files;
FILE_NAME STATUS
-- ------------------------------------------------ ---------
E:\ORACLE\WPENG\WPENG\SYSTEM01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\SYSAUX01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\UNDOTBS01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\USERS01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\SAMPLE.DBF AVAILABLE
-- 控制文件
SQL > select name, status from v$controlfile;
NAME STATUS
-- -------------------------------------- -------
E:\ORACLE\WPENG\WPENG\CONTROL01.CTL
E:\ORACLE\WPENG\WPENG\CONTROL02.CTL
E:\ORACLE\WPENG\WPENG\CONTROL03.CTL
-- 联机日志文件
SQL > select member from v$logfile;
MEMBER
-- --------------------------------------
E:\ORACLE\WPENG\WPENG\REDO01. LOG
E:\ORACLE\WPENG\WPENG\REDO02. LOG
E:\ORACLE\WPENG\WPENG\REDO03. LOG

-- 数据文件
SQL > select file_name , status from dba_data_files;
FILE_NAME STATUS
-- ------------------------------------------------ ---------
E:\ORACLE\WPENG\WPENG\SYSTEM01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\SYSAUX01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\UNDOTBS01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\USERS01.DBF AVAILABLE
E:\ORACLE\WPENG\WPENG\SAMPLE.DBF AVAILABLE
-- 控制文件
SQL > select name, status from v$controlfile;
NAME STATUS
-- -------------------------------------- -------
E:\ORACLE\WPENG\WPENG\CONTROL01.CTL
E:\ORACLE\WPENG\WPENG\CONTROL02.CTL
E:\ORACLE\WPENG\WPENG\CONTROL03.CTL
-- 联机日志文件
SQL > select member from v$logfile;
MEMBER
-- --------------------------------------
E:\ORACLE\WPENG\WPENG\REDO01. LOG
E:\ORACLE\WPENG\WPENG\REDO02. LOG
E:\ORACLE\WPENG\WPENG\REDO03. LOG
- shutdown immediate
- copy 控制文件、数据文件、联机日志文件
- startup - 创建一个数据(插入,提交,切换日志....)
- shutdown immediate (删除数据文件 - 模拟数据文件损坏 - 控制文件和联机日志文件没有损坏)
- 数据文件损坏之后,Oracle数据库只能启动到mount状态,在打开的时候,会报错(找不到数据文件):
SQL > alter database open ;
alter database open
*
ERROR at line 1 :
ORA - 01157 :
-- 根据控制文件得到第一个视图,然后查找相关的数据文件,找不到则:cannot identify/lock data file *1 - see DBWR trace file
-- 通过控制文件得到以下视图
SQL > select file #, checkpoint_change# from v$datafile;
FILE # CHECKPOINT_CHANGE#
-- -------- ------------------
1 2783842
2 2783842
3 2783842
4 2783842
5 2783842
-- 通过数据文件头 得到以下视图
SQL > select file #, checkpoint_change# from v$datafile_header;
FILE # CHECKPOINT_CHANGE#
-- -------- ------------------
1 2782605
2 2782605
3 2782605
4 2782605
5 2782605
ORA - 01110 : data file 1 : ' E:\ORACLE\WPENG\WPENG\SYSTEM01.DBF ' - 将冷备份的数据文件 - copy 到指定目录
- 再次打开database 则报错(需要介质恢复 - CHECKPOINT_CHANGE# - 控制文件和数据文件不一致 - Oracle打开的必要条件)
SQL > alter database open ;
alter database open
*
ERROR at line 1 :
ORA - 01113 : file 1 needs media recovery
ORA - 01110 : data file 1 : ' E:\ORACLE\WPENG\WPENG\SYSTEM01.DBF ' - 这样 change #2782605 就落在归档日志 sequence #118中。那么恢复的时候,只需要从这个归档日志文件开始,就OK了。
SQL > select sequence#, first_change#, next_change# from v$archived_log
2 where first_change# <= 2782605 and next_change# > 2782605 ;
SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
-- -------- ------------- ------------
118 2762472 2783591
118 2762472 2783591 - recover datafile:suggested (由系统决定使用归档日志);filename(自己指定归档日志-绝对路径);AUTO(一个个恢复太麻烦,有很多归档日志 - N个suggested)CANCEL(recover database until cancel 命令会用到)
-- 首先 recover datafile 1
SQL > recover datafile 1 ;
ORA - 00279 : change 2782605 generated at 09 / 27 / 2012 10 : 09 : 32 needed for thread 1
ORA - 00289 : suggestion : E:\APP\WPENG\PRODUCT\ 11.1 . 0 \FLASH_RECOVER_AREA\WPENG\ARCHIVELOG\2012_09_ 27 \O1_MF_1_118_867GK3OW_
.ARC
ORA - 00280 : change 2782605 for thread 1 is in sequence # 118
Specify log : { < RET >= suggested | filename | AUTO | CANCEL}
- recover一次,就会增加datafile_header的checkpoint_change#
SQL > select file #, checkpoint_change# from v$datafile;
FILE # CHECKPOINT_CHANGE#
-- -------- ------------------
1 2783842
2 2783842
3 2783842
4 2783842
5 2783842
SQL > select file #, checkpoint_change# from v$datafile_header;
FILE # CHECKPOINT_CHANGE#
-- -------- ------------------
1 2783591
2 2782605
3 2782605
4 2782605
5 2782605 - 由于联机日志文件没有损坏,所以最后的归档日志文件只使用到 sequence #124
ORA - 00279 : change 2783707 generated at 09 / 27 / 2012 10 : 34 : 49 needed for thread 1
ORA - 00289 : suggestion : E:\APP\WPENG\PRODUCT\ 11.1 . 0 \FLASH_RECOVER_AREA\WPENG\ARCHIVELOG\2012_09_ 27 \O1_MF_1_124_867GX8P4_
.ARC
ORA - 00280 : change 2783707 for thread 1 is in sequence # 124
Log applied.
Media recovery complete.
-- 但是当前归档日志最新的sequence #126
SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
-- -------- ------------- ------------
122 2783672 2783699
123 2783699 2783707
124 2783707 2783741
125 2783741 2783747
126 2783747 2783754
-- 在恢复的时候,同是还用到了3组联机日志文件,有上面日志可以得知,只用到sequence #124。否则最多只能恢复到check_point #2783741
SQL > select * from v$ log ;
GROUP # THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME
-- -------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ------------
1 1 127 52428800 1 NO CURRENT 2783754 27 - SEP - 12
3 1 126 52428800 1 YES INACTIVE 2783747 27 - SEP - 12
2 1 125 52428800 1 YES INACTIVE 2783741 27 - SEP - 12
- 最后的结果:
SQL > select file #, checkpoint_change# from v$datafile;
FILE # CHECKPOINT_CHANGE#
-- -------- ------------------
1 2783842
2 2783842
3 2783842
4 2783842
5 2783842
SQL > select file #, checkpoint_change# from v$datafile_header;
FILE # CHECKPOINT_CHANGE#
-- -------- ------------------
1 2783841
2 2783841
3 2783841
4 2783841
5 2783841 - 如果数据文件损坏的较多,可以直接
recover database ; - 为什么不着归档日志seqence #125 and #126,而是,直接找连接日志文件? 因为我们知道恢复的起点(datafile header)和终点(控制文件中的终点) - 横向比较。如果发出以下命令,则会直接找归档日志文件,不着联机日志文件:
-- 不完全恢复,恢复到那个点,Oracle是不清楚的 - 只要文件都在,都可以恢复(不完全恢复,不代表会丢失数据)
recover database until cancel;
-- 在open database的时候需要resetlog
-- 会导致一个新的version database,则所有的联机日志,都是从1开始
alter database open resetlog;
- 打开数据库
alter database open ; -
-- 如果不完全恢复,使用resetlog open database,则会有一个新的resetlogs_id
SQL > select resetlogs_id from v$archived_log;
SCN:System Change Number
- Oracle内部逻辑时钟
- 查询:
-- Oracle 内部取出
SQL > select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
-- ----------------------
2782870
-- 每次取出的时候,都会发生变化
SQL > select current_scn from v$ database ;
CURRENT_SCN
-- ---------
2782964 - 大约每隔三秒,会变化(递增)