控制文件与参数文件不同步和控制文件版本不一致导致数据库mount失败及其解决办法

来源:互联网 发布:java 多线程返回结果 编辑:程序博客网 时间:2024/05/22 06:48
1.参数文件与控制文件不同步(这里我们通过修改控制文件名字,模拟控制文件丢失,造成二者之间不同步)
[oracle@redhat ~]$ ls /u01/app/oracle/oradata/jiagulun/              //控制文件1位置
control01.ctl  redo01.log  redo03.log    system01.dbf  undotbs01.dbf
example01.dbf  redo02.log  sysaux01.dbf  temp01.dbf    users01.dbf
[oracle@redhat ~]$
[oracle@redhat ~]$ ls /u01/app/oracle/flash_recovery_area/jiagulun/  //控制文件2位置
control02.ctl
[oracle@redhat ~]$
[oracle@redhat ~]$ ls /u01/app/oracle/product/11.2.0.1/db_1/dbs/     //参数文件位置
hc_DBUA0.dat     initjiagulun.ora  orapwjiagulun
hc_jiagulun.dat  lkJIAGULUN        spfilejiagulun.ora
[oracle@redhat ~]$
[oracle@redhat ~]$ cat /u01/app/oracle/product/11.2.0.1/db_1/dbs/initjiagulun.ora
processes                = 150
  nls_language             = "SIMPLIFIED CHINESE"
  nls_territory            = "CHINA"
  memory_target            = 440M          //目前参数文件里,有2个控制文件,这里我们修改第1个
  control_files            = "/u01/app/oracle/oradata/jiagulun/control01.ctl"
  control_files            = "/u01/app/oracle/flash_recovery_area/jiagulun/control02.ctl"
  db_block_size            = 8192
  compatible               = "11.2.0.0.0"
  db_recovery_file_dest    = "/u01/app/oracle/flash_recovery_area"
  db_recovery_file_dest_size= 3882M
  undo_tablespace          = "UNDOTBS1"
  remote_login_passwordfile= "EXCLUSIVE"
  db_domain                = ""
  dispatchers              = "(PROTOCOL=TCP) (SERVICE=jiagulunXDB)"
  audit_file_dest          = "/u01/app/oracle/admin/jiagulun/adump"
  audit_trail              = "DB"
  db_name                  = "jiagulun"
  open_cursors             = 300
  diagnostic_dest          = "/u01/app/oracle"
[oracle@redhat ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Sat Jun 22 17:33:41 2013

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to an idle instance.

SQL> startup nomount 
ORACLE instance started.

Total System Global Area  459304960 bytes
Fixed Size                  2214336 bytes
Variable Size             285214272 bytes
Database Buffers          167772160 bytes
Redo Buffers                4104192 bytes
SQL> alter database mount;                  //没改之前,oracle Mount正常

Database altered.

SQL> !
[oracle@redhat dbs]$ cd /u01/app/oracle/oradata/jiagulun/
[oracle@redhat jiagulun]$ ls
control01.ctl  redo01.log  redo03.log    system01.dbf  undotbs01.dbf
example01.dbf  redo02.log  sysaux01.dbf  temp01.dbf    users01.dbf
[oracle@redhat jiagulun]$ mv control01.ctl control01.ctl.bak
[oracle@redhat jiagulun]$ exit
exit

SQL> shutdown immediate
ORA-01507: database not mounted


ORACLE instance shut down.
SQL> startup nomount
ORACLE instance started.

Total System Global Area  459304960 bytes
Fixed Size                  2214336 bytes
Variable Size             285214272 bytes
Database Buffers          167772160 bytes
Redo Buffers                4104192 bytes
SQL> alter database mount;
alter database mount
*
ERROR at line 1:                             //修改完以后,mount报错
ORA-00205: error in identifying control file, check alert log for more info

[oracle@redhat ~]$ cat trace/alert_jiagulun.log    //根据上边提示,查看alert
...
Sun Jun 23 10:00:08 2013
alter database mount
ORA-00210: ???????????
ORA-00202: ????: ''/u01/app/oracle/oradata/jiagulun/control01.ctl''
ORA-27037: ????????
Linux-x86_64 Error: 2: No such file or directory   //找不到文件control01.ctl,就是我们改的那个
Additional information: 3
ORA-205 signalled during: alter database mount

现在我们修改参数文件,以反映控制文件,即与控制文件同步,要改spfile,得先改pfile,改pfile之前,先备份一下
[oracle@redhat ~]$ ls home/dbs/
hc_DBUA0.dat     initjiagulun.ora  orapwjiagulun
hc_jiagulun.dat  lkJIAGULUN        spfilejiagulun.ora
[oracle@redhat ~]$ cp home/dbs/initjiagulun.ora home/dbs/initjiagulun.ora.bak    //备份pfile
[oracle@redhat ~]$ ls home/dbs/
hc_DBUA0.dat     initjiagulun.ora      lkJIAGULUN     spfilejiagulun.ora
hc_jiagulun.dat  initjiagulun.ora.bak  orapwjiagulun
[oracle@redhat ~]$ vi home/dbs/initjiagulun.ora             //修改pfile,删除control01.ctl那一行
[oracle@redhat ~]$ exit
exit

SQL> shutdown immediate
ORA-01507: database not mounted


ORACLE instance shut down.
SQL> create spfile from pfile='/u01/app/oracle/product/11.2.0.1/db_1/dbs/initjiagulun.ora';

File created.

SQL>
SQL> startup nomount
ORACLE instance started.

Total System Global Area  459304960 bytes
Fixed Size                  2214336 bytes
Variable Size             285214272 bytes
Database Buffers          167772160 bytes
Redo Buffers                4104192 bytes
SQL> alter database mount;

Database altered.

SQL> show parameter controlfiles;

SQL> select * from v$controlfile;           //加载新的spfile以后,查看发现控制文件只有一个了,OK

STATUS  NAME                           IS_ BLOCK_SIZE FILE_SIZE_BLKS
------- ------------------------------ --- ---------- --------------
        /u01/app/oracle/flash_recovery NO       16384            594
        _area/jiagulun/control02.ctl

小结:虽然参数文件里,控制文件有2条记录,但Oracle在找不到第一个控制文件时,不会像nomout阶段那样
      依次寻找下一个可用的控制文件,导致Mount失败

2.把数据库恢复原样
a).把复制过来的控制文件1删除
b).把原来的控制文件1名字恢复
c).在pfile文件中,恢复控制文件1的记录
d).create spfile from pfile

完成以上步骤,出现一个问题:

SQL> alter database mount;
alter database mount
*
ERROR at line 1:
ORA-00214: control file
'/u01/app/oracle/flash_recovery_area/jiagulun/control02.ctl' version 864
inconsistent with file '/u01/app/oracle/oradata/jiagulun/control01.ctl' version 858

       //两个控制文件,版本不一样,而且闪回区的版本要高一些(864 > 858)
       //也说明在mount阶段,oracle会检查多个控制文件之间版本的一致性
       //问题就出在这,为了控制文件版本一致,有两个办法:1.以高版本为准;2.以代版本为准

a).我们先以高版本为准,即以闪回区的控制文件为准
[oracle@redhat ~]$ ll base/oradata/jiagulun/
total 1609644
-rw-r----- 1 oracle oinstall   9748480 Jun 23 08:41 control01.ctl
-rw-r----- 1 oracle oinstall 104865792 Jun 22 21:45 example01.dbf
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo01.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:45 redo02.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo03.log
-rw-r----- 1 oracle oinstall 545267712 Jun 22 21:45 sysaux01.dbf
-rw-r----- 1 oracle oinstall 713039872 Jun 22 21:45 system01.dbf
-rw-r----- 1 oracle oinstall  30416896 Jun 22 21:45 temp01.dbf
-rw-r----- 1 oracle oinstall  89137152 Jun 22 21:45 undotbs01.dbf
-rw-r----- 1 oracle oinstall   5251072 Jun 22 21:45 users01.dbf
[oracle@redhat ~]$ ll base/flash_recovery_area/jiagulun/
total 9540
-rw-r----- 1 oracle oinstall 9748480 Jun 23 10:29 control02.ctl

           //比较ll的结果,发现两个文件完全一样,【除了最后修改时间】
           //我们以高版本准,即以修改时间最新的控制文件为准,所以control01.ctl改名
           //经过下面实验证明,通过时间来判断version新旧是不准确的

[oracle@redhat ~]$ mv base/oradata/jiagulun/control01.ctl base/oradata/jiagulun/control01.ctl.bak

           //然后再把高版本的复制过来
[oracle@redhat ~]$ cp base/flash_recovery_area/jiagulun/control02.ctl base/oradata/jiagulun/control01.ctl
[oracle@redhat ~]$ ll base/oradata/jiagulun/
total 1619184
-rw-r----- 1 oracle oinstall   9748480 Jun 23 10:41 control01.ctl
-rw-r----- 1 oracle oinstall   9748480 Jun 23 08:41 control01.ctl.bak
-rw-r----- 1 oracle oinstall 104865792 Jun 22 21:45 example01.dbf
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo01.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:45 redo02.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo03.log
-rw-r----- 1 oracle oinstall 545267712 Jun 22 21:45 sysaux01.dbf
-rw-r----- 1 oracle oinstall 713039872 Jun 22 21:45 system01.dbf
-rw-r----- 1 oracle oinstall  30416896 Jun 22 21:45 temp01.dbf
-rw-r----- 1 oracle oinstall  89137152 Jun 22 21:45 undotbs01.dbf
-rw-r----- 1 oracle oinstall   5251072 Jun 22 21:45 users01.dbf
[oracle@redhat ~]$ exit
exit

SQL> alter database mount;         //版本一致后,Mount 没问题

Database altered.

b).现在我们再试一下,以低版本控制文件为准会怎么样
先把数据库关了
SQL> shutdown immediate
ORA-01109: database not open


Database dismounted.
ORACLE instance shut down.
SQL>
SQL> !
[oracle@redhat ~]$ ll base/oradata/jiagulun/
total 1619184
-rw-r----- 1 oracle oinstall   9748480 Jun 23 10:53 control01.ctl
-rw-r----- 1 oracle oinstall   9748480 Jun 23 08:41 control01.ctl.bak
-rw-r----- 1 oracle oinstall 104865792 Jun 22 21:45 example01.dbf
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo01.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:45 redo02.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo03.log
-rw-r----- 1 oracle oinstall 545267712 Jun 22 21:45 sysaux01.dbf
-rw-r----- 1 oracle oinstall 713039872 Jun 22 21:45 system01.dbf
-rw-r----- 1 oracle oinstall  30416896 Jun 22 21:45 temp01.dbf
-rw-r----- 1 oracle oinstall  89137152 Jun 22 21:45 undotbs01.dbf
-rw-r----- 1 oracle oinstall   5251072 Jun 22 21:45 users01.dbf
[oracle@redhat ~]$ rm base/oradata/jiagulun/control01.ctl     //把复制过来的高版本给删了
[oracle@redhat ~]$ mv base/oradata/jiagulun/control01.ctl.bak base/oradata/jiagulun/control01.ctl
                                 //再把控制文件1的名字复原了,等于把oracle恢复成原状(版本不一致)
[oracle@redhat ~]$ ll base/oradata/jiagulun/
total 1609644
-rw-r----- 1 oracle oinstall   9748480 Jun 23 08:41 control01.ctl   //改名字不影响文件修改时间
-rw-r----- 1 oracle oinstall 104865792 Jun 22 21:45 example01.dbf
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo01.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:45 redo02.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo03.log
-rw-r----- 1 oracle oinstall 545267712 Jun 22 21:45 sysaux01.dbf
-rw-r----- 1 oracle oinstall 713039872 Jun 22 21:45 system01.dbf
-rw-r----- 1 oracle oinstall  30416896 Jun 22 21:45 temp01.dbf
-rw-r----- 1 oracle oinstall  89137152 Jun 22 21:45 undotbs01.dbf
-rw-r----- 1 oracle oinstall   5251072 Jun 22 21:45 users01.dbf
[oracle@redhat ~]$ exit
exit

SQL> startup nomount
ORACLE instance started.

Total System Global Area  459304960 bytes
Fixed Size                  2214336 bytes
Variable Size             285214272 bytes
Database Buffers          167772160 bytes
Redo Buffers                4104192 bytes

SQL> alter database mount;
alter database mount
*
ERROR at line 1:
ORA-00214: control file
'/u01/app/oracle/flash_recovery_area/jiagulun/control02.ctl' version 870
inconsistent with file '/u01/app/oracle/oradata/jiagulun/control01.ctl' version
858
          //原状恢复成功
          //mount时,依旧报错,只是闪回区版本号由原来的"864"变成现在的"870"
          //把版本号看成SCN号,变大,表明闪回区控制文件更新了,而control01.ctl还是原地踏步
          //一个870,一个858,两者还不一致,所以mount报错

现在我们以低版本为准,更改过后,查看
[oracle@redhat ~]$ ll base/flash_recovery_area/jiagulun/
total 19080
-rw-r----- 1 oracle oinstall 9748480 Jun 23 11:12 control02.ctl      //复制文件,会影响文件时间
-rw-r----- 1 oracle oinstall 9748480 Jun 23 10:53 control02.ctl.bak  //证明之前以时间看版本不准
[oracle@redhat ~]$ ll base/oradata/jiagulun/
total 1609644
-rw-r----- 1 oracle oinstall   9748480 Jun 23 08:41 control01.ctl
-rw-r----- 1 oracle oinstall 104865792 Jun 22 21:45 example01.dbf
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo01.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:45 redo02.log
-rw-r----- 1 oracle oinstall  52429312 Jun 22 21:44 redo03.log
-rw-r----- 1 oracle oinstall 545267712 Jun 22 21:45 sysaux01.dbf
-rw-r----- 1 oracle oinstall 713039872 Jun 22 21:45 system01.dbf
-rw-r----- 1 oracle oinstall  30416896 Jun 22 21:45 temp01.dbf
-rw-r----- 1 oracle oinstall  89137152 Jun 22 21:45 undotbs01.dbf
-rw-r----- 1 oracle oinstall   5251072 Jun 22 21:45 users01.dbf
[oracle@redhat ~]$ exit
exit

SQL> alter database mount;                 //以低版本为准,mount也OK

Database altered.

SQL> column name format a30               //查看控制文件,两个都出来了
SQL> select * from v$controlfile;

STATUS  NAME                           IS_ BLOCK_SIZE FILE_SIZE_BLKS
------- ------------------------------ --- ---------- --------------
        /u01/app/oracle/oradata/jiagul NO       16384            594
        un/control01.ctl

        /u01/app/oracle/flash_recovery NO       16384            594
        _area/jiagulun/control02.ctl

小结:oracle对控制文件的更新是并行的,正常情况下,多个控制文件之间版本应该是一致的
      如果因为各种原因,造成版本不一致,那Oralce在mount阶段就会报错
      解决办法,就是通过复制让其版本保持一致,至于是向高版本看齐,还是向低版本看齐,就无所谓了