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

本文介绍Oracle数据库中控制文件与参数文件不同步的问题处理过程。包括模拟控制文件丢失、修改参数文件使其与控制文件同步,以及解决控制文件版本不一致导致的mount错误。
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阶段就会报错
      解决办法,就是通过复制让其版本保持一致,至于是向高版本看齐,还是向低版本看齐,就无所谓了
### DG服务器日志SCN控制文件一致导致数据库无法启动的解决方案 当DG(Data Guard)服务器的日志SCN(System Change Number)控制文件一致时,可能会导致数据库无法正常启动。这种情况通常发生在主库备库之间的同步出现问题时。以下是一个详细的解决方案: #### 1. 确认问题 首先需要确认当前的问题是否确实是由日志SCN控制文件一致引起的。可以通过检查告警日志或使用以下SQL语句来验证: ```sql SELECT checkpoint_change# FROM v$database; SELECT thread#, max(sequence#) AS applied_sequence FROM v$log_history GROUP BY thread#; ``` 如果 `checkpoint_change#` `v$log_history` 中的最大序列号匹配,则表明存在一致的情况[^1]。 #### 2. 强制挂载数据库 在确认问题后,可以尝试强制挂载数据库以进一步分析问题。执行以下命令: ```sql STARTUP MOUNT; ``` 此操作将数据库挂载但会打开它,从而允许进行进一步的修复工作。 #### 3. 使用RESETLOGS选项重新打开数据库 如果日志SCN控制文件一致,通常可以通过 `RESETLOGS` 选项重新打开数据库。这会重置归档日志序列号并生成新的重做日志文件。需要注意的是,此操作会导致备库丢失部分未应用的日志数据。执行以下命令: ```sql ALTER DATABASE OPEN RESETLOGS; ``` 此命令会清除所有未应用的归档日志,并重新开始记录重做日志[^3]。 #### 4. 恢复丢失的数据 为了尽量减少数据丢失,可以在执行 `RESETLOGS` 前尝试恢复丢失的日志文件。通过以下步骤实现: - 确认丢失的日志文件编号: ```sql SELECT sequence#, first_change#, next_change# FROM v$archived_log WHERE applied='NO'; ``` - 将丢失的日志文件手动复制到备库并应用: ```bash cp /path/to/archived_log/standby_logfile.dbf $ORACLE_HOME/dbs/ ``` - 手动应用日志文件: ```sql RECOVER DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL; ``` #### 5. 配置MRP进程重新同步 完成上述步骤后,需要重新启动MRP(Managed Recovery Process)进程以确保备库能够继续接收应用主库的归档日志: ```sql ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION; ``` 此命令将启动MRP进程,并自动从主库获取最新的归档日志进行应用。 #### 6. 验证同步状态 最后,验证主库备库之间的同步状态是否恢复正常。可以通过以下查询检查: ```sql SELECT process, status, sequence# FROM v$managed_standby; ``` 如果 `MRP0` 的状态为 `WAIT_FOR_LOG` 或 `APPLYING_LOG`,则表示同步已恢复正常[^3]。 ### 注意事项 - 在执行 `RESETLOGS` 操作前,务必备份当前的控制文件归档日志。 - 如果主库仍然可用,建议优先从主库重新传输缺失的日志文件,以尽量减少数据丢失。 ```python # 示例代码:检查主备库同步状态的Python脚本 import cx_Oracle def check_dg_status(connection_string): connection = cx_Oracle.connect(connection_string) cursor = connection.cursor() cursor.execute("SELECT process, status, sequence# FROM v$managed_standby") rows = cursor.fetchall() for row in rows: print(f"Process: {row[0]}, Status: {row[1]}, Sequence#: {row[2]}") cursor.close() connection.close() check_dg_status("user/password@standby_db") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值