实例启动到nomount状态以后,Oracle就可以从参数文件中获得控制文件的位置信息,然后找到控制文件,并且根据控制文件中记录的数据文件位置进行数据文件的存在性判断。
控制文件的定位
在Oracle 10g之前,通常Oracle缺省的会创建3个控制文件,这三个控制文件的内容完全一致,是Oracle为了安全而采用的镜像手段,在生产环境中,通常我们应该将控制文件存放在不同的物理硬盘上,避免因为介质故障而同时损坏三个控制文件。
控制文件信息在参数文件中记录类似如下所示:
*.control_files='/opt/oracle/oradata/conner/control01.ctl', '/opt/oracle/oradata/conner/control02.ctl', '/opt/oracle/oradata/conner/control03.ctl'
复制
从Oracle 10g开始,如果设置了闪回恢复区(Flashback Recovery Area,通常闪回区和数据区位于不同硬盘存储),则Oracle缺省的就会将控制文件分布到不同的磁盘组,至此Oracle才算完成了控制文件的真正镜像安全保护,以下是Oracle 10g中的一个输出示范:
SQL> show parameter control_files NAME TYPE VALUE --------------- ----------- ------------------------------------------------- control_files string +ORADG/smsdb/controlfile/current.256.642339925, +FLHDG/smsdb/controlfile/current.256.642339925
复制
在nomount状态,可以查询vparameter视图,获得控制文件信息,这部分信息来自启动的参数文件;当数据库mount之后,可以查询vcontrolfile视图获得关于控制文件的信息,此时,这部分信息来自控制文件:
SQL> startup nomount; SQL> select * from v$controlfile; no rows selected SQL> show parameter control_files NAME TYPE VALUE ------------------ --------------- ---------------------------------------- control_files string /opt/oracle/oradata/conner/control01.ctl, /opt/oracle/oradata/conner/control02.ctl, /opt/oracle/oradata/conner/control03.ctl SQL> alter database mount; Database altered. SQL> select * from v$controlfile; STATUS NAME ------- ---------------------------------------- /opt/oracle/oradata/conner/control01.ctl /opt/oracle/oradata/conner/control02.ctl /opt/oracle/oradata/conner/control03.ctl
复制
在mount数据库的过程中,Oracle需要找到控制文件,锁定控制文件。如果控制文件全部丢失此时就会报出如下错误:
ORA-00205: error in identifying controlfile, check alert log for more info
复制
这时候告警日志文件中通常会记录更为详细的信息:
ORA-00202: controlfile: '/opt/oracle/oradata/conner/control01.ctl' ORA-27037: unable to obtain file status Linux Error: 2: No such file or directory Additional information: 3
复制
因为Oracle的三个(缺省的)控制文件内容完全相同,如果只是损失了其中1~2个,可以复制完好的控制文件,更改为相应的名称,就可以启动数据库;如果丢失了所有的控制文件,那么就需要恢复或重建控制文件来打开数据库。
数据文件的存在性判断
在启动了实例之后,实际上数据库的后台进程已经运行,那么当进一步的Mount数据库之后,后台进程就可以根据控制文件中记录的数据文件信息来验证数据文件是否存在,如果数据文件不存在,则后台进程将在告警日志文件中记录文件缺失信息,并且在动态视图中记录这些信息。
对以下数据库进行一个简单测试:
SQL> select name from v$datafile; NAME --------------------------------------------------------------------------------- /opt/oracle/oradata/eygle/system01.dbf /opt/oracle/oradata/eygle/undotbs01.dbf /opt/oracle/oradata/eygle/eygle01.dbf /opt/oracle/oradata/eygle/users.dbf
复制
通过以下步骤,移除一个测试文件:
SQL> shutdown immediate; SQL> ! mv /opt/oracle/oradata/eygle/eygle01.dbf /opt/oracle/oradata/eygle/eygle01.dbf.b SQL> startup mount;
复制
此时检查告警日志文件,则可以发现数据文件的缺失信息:
[oracle@jumper bdump]$ tail -20 alert_eygle.log ALTER DATABASE MOUNT Mon Sep 15 21:21:01 2008 Successful mount of redo thread 1, with mount id 1484653049. Mon Sep 15 21:21:01 2008 Database mounted in Exclusive Mode. Completed: ALTER DATABASE MOUNT Mon Sep 15 21:21:31 2008 Errors in file /opt/oracle/admin/eygle/bdump/eygle_dbw0_17074.trc: ORA-01157: cannot identify/lock data file 3 - see DBWR trace file ORA-01110: data file 3: '/opt/oracle/oradata/eygle/eygle01.dbf' ORA-27037: unable to obtain file status Linux Error: 2: No such file or directory Additional information: 3 Mon Sep 15 21:21:41 2008 Errors in file /opt/oracle/admin/eygle/bdump/eygle_dbw0_17074.trc: ORA-01157: cannot identify/lock data file 3 - see DBWR trace file ORA-01110: data file 3: '/opt/oracle/oradata/eygle/eygle01.dbf' ORA-27037: unable to obtain file status Linux Error: 2: No such file or directory Additional information: 3
复制
此时查询数据的动态视图v$recover_file可以发现数据库记录了FILE NOT FOUND的错误信息:
SQL> select * from v$recover_file; FILE# ONLINE ONLINE_ ERROR CHANGE# TIME ---------- ------- ------- ------------------------------ ---------- --------- 3 ONLINE ONLINE FILE NOT FOUND 0 SQL> select name from v$datafile where file#=3; NAME ------------------------------------------------------------------------------- /opt/oracle/oradata/eygle/eygle01.dbf
复制
不过在较新版本(比如Oracle 11gR2)中,启动数据库到Mount状态时,在告警日志文件中不再提示数据文件缺失信息。
控制文件的HeartBeat
在正常Mount数据库的过程中,数据库的警报日志文件仅记录如下信息:
alter database mount Sat Apr 29 10:20:42 2006 Successful mount of redo thread 1, with mount id 1408096182. Sat Apr 29 10:20:42 2006 Database mounted in Exclusive Mode. Completed: alter database mount
复制
在这一步骤中,数据库需要计算Mount id并将其记录在控制文件中,然后开始启动心跳(heartbeat),每3秒更新一次控制文件。可以用以下命令间隔3秒转储2次控制文件信息:
alter session set events 'immediate trace name CONTROLF level 8' ;
复制
在Linux上用diff命令比较2个文件可以发现,控制文件在Mount状态下发生改变的只有这个Heartbeat:
[oracle@jumper udump]$ diff conner_ora_25542.trc conner_ora_25706.trc ... 64c63 < heartbeat: 588983634 mount id: 1408096182 --- > heartbeat: 588983636 mount id: 1408096182
复制
Heartbeat表明实例已经被特定例程所Mount,这个属性主要用于OPS/RAC环境。但是Heartbeat在单实例环境中同样存在。可以从一个内部表(需要以SYS用户登录)中查询到当前的Heartbeat值(X$KCCCP的含义为[K]ernel [C]ache [C]ontrolfile management [C]heckpoint [P]rogress):
SELECT CPHBT from X$KCCCP;
复制
从Oracle 9i开始,Oracle在数据库内部通过等待事件control file heartbeat来记录这个事件的相关等待;在Oracle 10g中,如果使用自动存储管理技术(ASM - Automatic Storage Management),那么还会增加一个ASM实例的心跳事件;以下输出来自Oracle 10g:
SQL> select event#,name 2 from v$event_name where name like '%heart%'; EVENT# NAME ---------- ---------------------------------------------------------------- 282 ASM mount : wait for heartbeat 423 control file heartbeat
复制
了解了启动的各个步骤,我们也就可以在发生问题的时候,快速定位,准确判断,从而快速解决问题。