这里先阐述一下数据库的启动过程:
1.启动实例/例程(nomount状态)时,读取参数文件(文本文件PFILE 或服务器参数文件SPFILE),分配SGA、启动后台进程、打开告警文件及后台进程跟踪文件;
2.装载数据库(mount 状态)时,根据初始化参数control_file 的值定位并打开控制文件,从中得到数据文件及重做日志的信息。
3.打开数据库(open状态)时,打开所有数据文件和重做日志文件;至此,用户可以正常访问数据库;
控制文件用来记录和维护数据库的物理结构,里面记载着数据库打开时需要已经定位的所有数据文件和重做日志文件,并且记载着同步和恢复数据库时的日志序列号、检查点及日志历史记录;如果控制文件丢失,就像是人的大脑不能用了一般,只有医生(dba)能够处理,普通用户不能正常访问,那么就失去了它作为数据库的意义,除非恢复控制文件或重建控制文件(重建控制文件的两种情况是所有控制文件损坏、改变数据库名称或数据库的永久性参数);既然它的地位如此显赫,那么我们不得不重视,重视的体现就是多元化以及定期地或数据库配置发生变化时及时备份;数据库配置发生变化的命令有:
添加日志
alter database [add|drop] logfile
添加日志成员
alter datebase [add|drop] logfile member
添加日志组
alter datebase [add|drop] logfile group
修改数据库是否归档
alter datebase [noarchivelog|archivelog]
重命名数据库文件
alter datebase rename file
创建表空间
create tablespace
添加数据文件到相应表空间
alter tablespace [add|rename]datafile
修改表空间状态
alter tablespace [read write|read only]
删除表空间
droptablespace
获取控制文件信息视图:
v$controlfile
备份控制文件(建立控制文件副本):
copy ‘E:\oracle\product\10.2.0\oradata\orcl\control01.ctl’ ‘e:\oracle\backup\control.ctl’;(冷备份|一致性备份)
或
alter database backup controlfileto ‘e:\oracle\backup\control.ctl’[reuse](热备份|非一致性备份);
该命令会将当前控制文件的所有信息存放到控制文件的副本中,通过该副本,既可以执行基于控制文件的不完全恢复,也可以生成控制文件的跟踪文件;
备份控制文件(备份到跟踪文件):
该方案主要是为了创建控制文件恢复控制文件;
alterdatabase backup controlfileto trace;
恢复控制文件:
恢复控制文件时,服务器进程和后台进程需要从控制文件中读取各种与备份相关的信息。
当数据库的控制文件出现介质失败时,会出现ORA-00205错误;
ORA-00205: error in identifying controlfile, check alert log for more info
Cause:The system could not find acontrol file of the specified name and size.
Action:Check that ALL control files areonline and that they are the same files that the system created at cold starttime.
1.控制文件组中的某个出现介质失败
因为所有的控制文件是互为镜像,所以用其他控制文件来恢复即可;如果出现介质失败的磁盘也出现损坏,那么在需要在nomount 状态时修改control_files 参数,使之去掉有问题的控制文件;
SQL> show parameter control_file
NAME TYPE VALUE
-------------------------------------------------------- ------------------------------
control_file_record_keep_time integer 7
control_files string E:\ORACLE\PRODUCT\10.2.0\ORADA
TA\ORCL\CONTROL01.CTL,E:\ORAC
LE\PRODUCT\10.2.0\ORADATA\ORCL
\CONTROL02.CTL, E:\ORACLE\PROD
UCT\10.2.0\ORADATA\ORCL\CONTRO
L03.CTL
说明当前有三个控制文件互为镜像;
SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
手工删除control03.ctl
SQL> startup nomount;
ORACLE 例程已经启动。
Total System Global Area 838860800 bytes
Fixed Size 1293384 bytes
Variable Size 729809848 bytes
Database Buffers 100663296 bytes
Redo Buffers 7094272 bytes
SQL> alter database mount;
alter database mount
*
第 1 行出现错误:
ORA-00205: ?????????, ??????, ???????
SQL> alter system setcontrol_files='E:\oracle\product\10.2.0\oradata\orcl\control01.ctl','E:\oracle\product\10.2.0\oradata\orcl\control02.ctl'scope=spfile;
系统已更改。
SQL> startup force
ORACLE 例程已经启动。
Total System Global Area 838860800 bytes
Fixed Size 1293384 bytes
Variable Size 738198456 bytes
Database Buffers 92274688 bytes
Redo Buffers 7094272 bytes
数据库装载完毕。
数据库已经打开。
SQL> show parameter control_files;
NAME TYPE VALUE
----------------------------------------------- ------------------------------
control_files string E:\ORACLE\PRODUCT\10.2.0\ORADA
TA\ORCL\CONTROL01.CTL,E:\ORAC
LE\PRODUCT\10.2.0\ORADATA\ORCL
\CONTROL02.CTL
如果感觉还是三个比较安全的话,那么就在数据库关闭的时候拷贝其中一个到其他地方,然后再在nomount 状态修改一下control_files参数,启动即可;
2.控制文件全军覆没
这个时候就需要用重建控制文件的方法来恢复控制文件了;虽说可以完全手动创建控制文件,格式格式可以参照官方文档,但是库里的数据文件及重做日志的信息一般是记不牢的,所以尽量让系统帮我们把这些信息统计出来;跟踪文件就是这样一种策略;如果已经将控制文件的信息备份到跟踪文件,那么可以少做修改在数据库关闭的情况下即可执行该跟踪文件进行控制文件的重建;如果只是把控制文件备份成了副本,那么可以根据该副本生成跟踪文件;
首先需要给控制文件做一个备份:
SQL> alter database backup controlfile to '/u01/app/oracle/online_backup/controlfile';
Database altered.
然后查看(做每一步一定要记得查看是否成功,否则,一旦出问题,恢复的时候为时已晚了)
Last login: Mon Apr 15 16:33:50 2013 from 192.168.71.1
[root@yjgocp ~]# su - oracle
[oracle@yjgocp ~]$ cd /u01/app/oracle/online_backup/
[oracle@yjgocp online_backup]$ ll
total 112048
-rw-r----- 1 oracle oinstall 9748480 Apr 15 16:48 controlfile
发出一个检查点
SQL> alter system checkpoint;
System altered.
查找控制文件所在位置,然后干掉
SQL> SELECT NAME from v$controlfile;
NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/ocpyjg/control01.ctl
/u01/app/oracle/oradata/ocpyjg/control02.ctl
[oracle@yjgocp ocpyjg]$ rm -rf control*
[oracle@yjgocp ocpyjg]$ ll
total 1854680
-rw-r----- 1 oracle oinstall 104865792 Apr 15 16:49 example01.dbf
-rw-r----- 1 oracle oinstall 20979712 Apr 15 16:49 rc_data.dbf
-rw-r----- 1 oracle oinstall 52429312 Apr 15 16:45 redo01.log
-rw-r----- 1 oracle oinstall 52429312 Apr 15 16:49 redo02.log
-rw-r----- 1 oracle oinstall 52429312 Apr 15 16:45 redo03.log
-rw-r----- 1 oracle oinstall 618668032 Apr 15 16:49 sysaux01.dbf
-rw-r----- 1 oracle oinstall 744497152 Apr 15 16:49 system01.dbf
-rw-r----- 1 oracle oinstall 30416896 Apr 15 16:20 temp01.dbf
-rw-r----- 1 oracle oinstall 104865792 Apr 15 16:49 tp1.dbf
-rw-r----- 1 oracle oinstall 10493952 Apr 15 16:49 tp7.dbf
-rw-r----- 1 oracle oinstall 110108672 Apr 15 16:49 undotbs01.dbf
-rw-r----- 1 oracle oinstall 5251072 Apr 15 16:49 users01.dbf
确定已经删除;
关闭数据库
SQL> shutdown immediate;
Database closed.
ORA-00210: cannot open the specified control file
ORA-00202: control file: '/u01/app/oracle/oradata/ocpyjg/control01.ctl'
ORA-27041: unable to open file
Linux Error: 2: No such file or directory
Additional information: 3
说明数据库在向控制文件中写数据时,发现找不到该文件,只能以abort方式关闭了
SQL> shutdown abort;
ORACLE instance shut down.
数据库在启动mount状态时需要用到控制文件,有此,我们先这样操作
SQL> startup nomount;
ORACLE instance started.
Total System Global Area 422670336 bytes
Fixed Size 1336960 bytes
Variable Size 339741056 bytes
Database Buffers 75497472 bytes
Redo Buffers 6094848 bytes
然后用刚才备份的控制文件还原到控制文件原来的位置
[oracle@yjgocp ocpyjg]$ cp /u01/app/oracle/online_backup/controlfile control01.ctl
[oracle@yjgocp ocpyjg]$ cp /u01/app/oracle/online_backup/controlfile control02.ctl
因为启动数据库时的参数文件中记录的是两个控制文件,所以这里必须生成两个控制文件,打开的时候会报错
[oracle@yjgocp ocpyjg]$ ll
total 1873752
-rw-r----- 1 oracle oinstall 9748480 Apr 15 16:53 control01.ctl
-rw-r----- 1 oracle oinstall 9748480 Apr 15 16:53 control02.ctl
-rw-r----- 1 oracle oinstall 104865792 Apr 15 16:50 example01.dbf
-rw-r----- 1 oracle oinstall 20979712 Apr 15 16:50 rc_data.dbf
-rw-r----- 1 oracle oinstall 52429312 Apr 15 16:45 redo01.log
-rw-r----- 1 oracle oinstall 52429312 Apr 15 16:50 redo02.log
-rw-r----- 1 oracle oinstall 52429312 Apr 15 16:45 redo03.log
-rw-r----- 1 oracle oinstall 618668032 Apr 15 16:50 sysaux01.dbf
-rw-r----- 1 oracle oinstall 744497152 Apr 15 16:50 system01.dbf
-rw-r----- 1 oracle oinstall 30416896 Apr 15 16:20 temp01.dbf
-rw-r----- 1 oracle oinstall 104865792 Apr 15 16:50 tp1.dbf
-rw-r----- 1 oracle oinstall 10493952 Apr 15 16:50 tp7.dbf
-rw-r----- 1 oracle oinstall 110108672 Apr 15 16:50 undotbs01.dbf
-rw-r----- 1 oracle oinstall 5251072 Apr 15 16:50 users01.dbf
Ok 说明物理上已经还原了“损坏”的控制文件,接下来查看一下数据文件头部、控制文件、数据库所记录的scn情况,
正常情况下应该是一致的,既然有了控制文件,那么先把数据库启动到mount状态;
SQL> alter database mount;
Database altered.
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
1687448
SQL> select checkpoint_change# from v$datafile_header;
CHECKPOINT_CHANGE#
------------------
1688062
1688062
1688062
1688062
1688062
1688062
1688062
1688062
8 rows selected.
SQL> select checkpoint_change# from v$datafile;
CHECKPOINT_CHANGE#
------------------
1687448
1687448
1687448
1687448
1687448
1687448
1687448
1687448
8 rows selected.
发现数据文件头部和控制文件不一致,控制文件记录的scn较小,说明在控制文件删除之后又发生了一些检查点,
这个时候肯定记录不到控制文件了,我们先尝试着打开库
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
ok,该错误说明当控制文件记录的scn和数据文件头部不一致时,需要把日志的sequence重置,下面有个地方会进一步验证此观点,
先按照该提示做一下
SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01152: file 1 was not restored from a sufficiently old backup
ORA-01110: data file 1: '/u01/app/oracle/oradata/ocpyjg/system01.dbf'
提示1号文件需要恢复(其实上面显示的当控制文件与对应的数据文件头部的scn号不一样时,就需要恢复了,必须每个对应的文件一致
才能启动数据库),发出恢复数据库的命令(这里也可以单独恢复对应的文件,由于这里所有的文件都不一致,所以恢复整个数据库)
SQL> recover database;
ORA-00283: recovery session canceled due to errors
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done
提示使用备份的控制文件,说明要去找归档日志
SQL> recover database using backup controlfile;
ORA-00279: change 1687497 generated at 04/15/2013 16:36:10 needed for thread 1
ORA-00289: suggestion : /u01/app/oracle/product/11g/dbs/arch1_41_809101738.dbf
ORA-00280: change 1687497 for thread 1 is in sequence #41
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
要用到41号归档,这里给出了建议的归档日志,我们直接回车用它给出的归档进行恢复
ORA-00308: cannot open archived log
'/u01/app/oracle/product/11g/dbs/arch1_41_809101738.dbf'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
Additional information: 3
提示找不到,那么查看在线日志和归档日志情况(归档日志默认在dbs下):
[oracle@yjgocp ~]$ cd /u01/app/oracle/product/11g/dbs/
[oracle@yjgocp dbs]$ ll
total 540560
-rw-r----- 1 oracle oinstall 9797632 Apr 14 10:11 0oo72338_1_1
-rw-r----- 1 oracle oinstall 9797632 Apr 14 10:12 0po7234g_1_1
-rw-r----- 1 oracle oinstall 41616384 Mar 31 14:37 arch1_26_809101738.dbf
-rw-r----- 1 oracle oinstall 47681024 Apr 2 20:51 arch1_27_809101738.dbf
-rw-r----- 1 oracle oinstall 42152448 Apr 2 22:02 arch1_28_809101738.dbf
-rw-r----- 1 oracle oinstall 42336256 Apr 7 12:42 arch1_29_809101738.dbf
-rw-r----- 1 oracle oinstall 47681024 Apr 7 12:49 arch1_30_809101738.dbf
-rw-r----- 1 oracle oinstall 43932160 Apr 7 12:52 arch1_31_809101738.dbf
-rw-r----- 1 oracle oinstall 31206912 Apr 8 10:18 arch1_32_809101738.dbf
-rw-r----- 1 oracle oinstall 40659968 Apr 9 09:22 arch1_33_809101738.dbf
-rw-r----- 1 oracle oinstall 43397120 Apr 13 09:24 arch1_34_809101738.dbf
-rw-r----- 1 oracle oinstall 40540160 Apr 13 10:18 arch1_35_809101738.dbf
-rw-r----- 1 oracle oinstall 41111040 Apr 14 09:23 arch1_36_809101738.dbf
-rw-r----- 1 oracle oinstall 41083392 Apr 14 21:36 arch1_37_809101738.dbf
-rw-r----- 1 oracle oinstall 16135168 Apr 14 22:34 arch1_38_809101738.dbf
-rw-r----- 1 oracle oinstall 20992 Apr 14 22:41 arch1_39_809101738.dbf
-rw-r----- 1 oracle oinstall 3937280 Apr 15 16:36 arch1_40_809101738.dbf
SQL> SELECT group#,sequence#,first_change#,next_change# from v$log;
GROUP# SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
---------- ---------- ------------- ------------
1 40 1683765 1687083
3 39 1663719 1683765
2 41 1687083 2.8147E+14
说明41号日志在当时还没有归档,估计是active状态或current状态;
所以恢复时用到关键字using backup controlfile 只找归档日志是不能完全恢复的,那么我们就在提示时输入redo日志,
经上面查询41号日志是第二组,插叙第二组日志的路径及名称:
SQL> select group#,type,member from v$logfile;
GROUP# TYPE MEMBER
---------- ------- ------------------------------------------------------------
3 ONLINE /u01/app/oracle/oradata/ocpyjg/redo03.log
2 ONLINE /u01/app/oracle/oradata/ocpyjg/redo02.log
1 ONLINE /u01/app/oracle/oradata/ocpyjg/redo01.log
ok 说明是/u01/app/oracle/oradata/ocpyjg/redo02.log,我们再执行一遍恢复操作
SQL> recover database using backup controlfile;
ORA-00279: change 1687497 generated at 04/15/2013 16:36:10 needed for thread 1
ORA-00289: suggestion : /u01/app/oracle/product/11g/dbs/arch1_41_809101738.dbf
ORA-00280: change 1687497 for thread 1 is in sequence #41
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/u01/app/oracle/oradata/ocpyjg/redo02.log
Log applied.
Media recovery complete.
果然,恢复完成;
下面我们打开数据库
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
哦,好了,这里印证了上面所说的需要把日志的sequence重置
SQL> alter database open resetlogs;
Database altered.
数据库能够正常打开,至此任务已经完成,最后我们再看一下数据文件头部、控制文件和数据库的scn的情况:
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
1688066
SQL> select checkpoint_change# from v$datafile_header;
CHECKPOINT_CHANGE#
------------------
1688066
1688066
1688066
1688066
1688066
1688066
1688066
1688066
SQL> select checkpoint_change# from v$datafile;
CHECKPOINT_CHANGE#
------------------
1688066
1688066
1688066
1688066
1688066
1688066
1688066
1688066
8 rows selected.
OK,大功告成