ORA-00314和ORA-00312错误解决方法
之前BI的一个数据库磁盘故障,修复后由于没有足够空间的服务器和存储,使用了一台I/O很慢的存储临时搭建了DG,昨天新采购的服务器到货,要把备库迁移到新的服务器上。
备库迁移有很多种方案可以选择,我选择了一种比较方便比较简单的方案,直接拷贝备库,因为这个备库只起到一个容灾的作用,并没有承载任何的业务。
我的操作步骤是,停止备库的MRP进程(或者将数据库启动到MOUNT状态,不要启动MRP进程),这样数据文件就会静止,不会发生变化,并且备库还可以继续结束主库的日志,一旦下班之前完不成,还可以启动原备库的MRP进程,继续同步,因为原备库的磁盘I/O很慢,并不确定下班之前是否能传输完毕,而且这个活并不着急。
然后把备库的数据文件、控制文件、参数文件、密码文件、日志文件(redo log、standby redo log)传输到新的服务器。
传输完成后,关闭原备库,这样主库的日志就不会再发送到原备库,将缺少的归档日志从原备库传输到新服务器。因为数据文件传输的时候,原备库一直在接受主库的日志,原备库的控制文件一直在变化,所以原备库关闭后,还需要再把原备库的控制文件传输到新服务器。
因为原备库和新服务器的路径信息都一致,并不需要调整,修改主库和新服务器的tnsnames.ora文件里相应的IP地址信息,启动新服务器上的数据库。
在MOUNT的时候,告警日志报出ORA-00314错误,但是数据库mount成功。
alter database mount ARCH: STARTING ARCH PROCESSES Thu Mar 22 17:41:38 2018 ARC0 started with pid=29, OS id=140161 ARC0: Archival started ARCH: STARTING ARCH PROCESSES COMPLETE ARC0: STARTING ARCH PROCESSES Thu Mar 22 17:41:39 2018 Successful mount of redo thread 1, with mount id 735403022 Physical Standby Database mounted. Lost write protection disabled Thu Mar 22 17:41:40 2018 ARC1 started with pid=30, OS id=140163 Thu Mar 22 17:41:40 2018 ARC2 started with pid=31, OS id=140165 Thu Mar 22 17:41:40 2018 ARC3 started with pid=32, OS id=140167 ARC1: Archival started ARC2: Archival started ARC1: Becoming the 'no FAL' ARCH ARC2: Becoming the heartbeat ARCH ARC2: Becoming the active heartbeat ARCH Errors in file /u01/app/oracle/diag/rdbms/huimaibi/huimaibi/trace/huimaibi_arc2_140165.trc: ORA-00314: log 10 of thread 1, expected sequence# 68673 doesn't match 68625 ORA-00312: online log 10 thread 1: '/u01/app/oracle/oradata/huimaibi/redo_std01.log' Create Relation IPS_PACKAGE_UNPACK_HISTORY Completed: alter database mount
错误提示第10组redo文件损坏,这个数据库的第10组redo是第一个standby redo文件,在新服务上的备库启动到mount状态后,就可以接收主库的日志了,这时候又一次报出这个错误。
ARC3: Archival started ARC0: STARTING ARCH PROCESSES COMPLETE Thu Mar 22 17:52:19 2018 Using STANDBY_ARCHIVE_DEST parameter default value as /u01/app/oracle/archivelog Thu Mar 22 17:52:19 2018 Errors in file /u01/app/oracle/diag/rdbms/huimaibi/huimaibi/trace/huimaibi_rfs_140379.trc: ORA-00314: log 10 of thread 1, expected sequence# 68673 doesn't match 68625 ORA-00312: online log 10 thread 1: '/u01/app/oracle/oradata/huimaibi/redo_std01.log' Errors in file /u01/app/oracle/diag/rdbms/huimaibi/huimaibi/trace/huimaibi_rfs_140379.trc: ORA-00314: log 10 of thread 1, expected sequence# 68673 doesn't match 68625 ORA-00312: online log 10 thread 1: '/u01/app/oracle/oradata/huimaibi/redo_std01.log'
看到这个错误,我就知道是什么原因了,因为原备库在传输数据文件的时候,原备库一直在接受主库的日志,会使用到standby redo文件,不止控制文件会被更新,standby redo也会被更新,而之前我只考虑到控制文件被更新,重新传了一次控制文件,却忽略了standby redo也发生变化的问题。
这时,查询V$STANDBY_LOG视图已经查询不了,也报这个错误。
SQL> SELECT GROUP#,SEQUENCE#,ARCHIVED,STATUS FROM v$standby_log; ORA-00314: log 10 of thread 1, expected sequence# 68673 doesn't match 68625 ORA-00312: online log 10 thread 1: '/u01/app/oracle/oradata/huimaibi/redo_std01.log'
在启动MRP进程,应用日志的时候,也遇到了这个错误。
Thu Mar 22 17:56:37 2018 Media Recovery Log /u01/app/oracle/archivelog/1_68656_966557443.dbf Thu Mar 22 17:56:40 2018 Errors in file /u01/app/oracle/diag/rdbms/huimaibi/huimaibi/trace/huimaibi_arc2_140165.trc: ORA-00314: log 10 of thread 1, expected sequence# 68673 doesn't match 68625 ORA-00312: online log 10 thread 1: '/u01/app/oracle/oradata/huimaibi/redo_std01.log'
但是并不影响备库接收主库的日志,从下面的日志可以看到,这里使用了redo_std02.log这个standby redo来时时接受主库的日志了。
Thu Mar 22 17:57:23 2018 Media Recovery Log /u01/app/oracle/archivelog/1_68675_966557443.dbf Media Recovery Log /u01/app/oracle/archivelog/1_68676_966557443.dbf Media Recovery Log /u01/app/oracle/archivelog/1_68677_966557443.dbf Media Recovery Waiting for thread 1 sequence 68678 (in transit) Recovery of Online Redo Log: Thread 1 Group 11 Seq 68678 Reading mem 0 Mem# 0: /u01/app/oracle/oradata/huimaibi/redo_std02.log
这个问题解决起来也非常的简单,因为原先的备库已经停掉了,直接把这个文件拷过来就行了。
把报错的standby redo拷过来之后,在告警日志就可以看到,这个standby redo文件已经可以正常接收主库的日志了。
Thu Mar 22 17:58:06 2018 RFS[6]: Selected log 10 for thread 1 sequence 68679 dbid 730497987 branch 966557443 Thu Mar 22 17:58:06 2018 Media Recovery Waiting for thread 1 sequence 68679 (in transit) Recovery of Online Redo Log: Thread 1 Group 10 Seq 68679 Reading mem 0 Mem# 0: /u01/app/oracle/oradata/huimaibi/redo_std01.log
在查看V$STANDBY_LOG视图,可以查看到,redo_std01.log和redo_std02.log都在接受主库的日志信息,平时只能看到一组standby redo在工作,基本看不到两组standby redo工作的情况,这是一种例外。
SQL> SELECT GROUP#,SEQUENCE#,ARCHIVED,STATUS FROM v$standby_log; GROUP# SEQUENCE# ARC STATUS ---------- ---------- --- ---------- 10 68679 YES ACTIVE 11 68678 YES ACTIVE 12 0 NO UNASSIGNED 13 0 NO UNASSIGNED
既然是例外情况,就不会长久,在过一段时间,日志切换几次后,状态就会变成正常情况了。
SQL> SELECT GROUP#,SEQUENCE#,ARCHIVED,STATUS FROM v$standby_log; GROUP# SEQUENCE# ARC STATUS ---------- ---------- --- ---------- 10 69076 YES ACTIVE 11 0 NO UNASSIGNED 12 0 NO UNASSIGNED 13 0 NO UNASSIGNED
我这个故障出现在standby redo log上,所以恢复起来比较简单,如果故障发生在online redo log上面,就要看online redo log是什么状态了。
如果损坏的是INACTIVE状态或者UNUSED状态,说明这个online redo log已经是检查点之前的了或者还没被使用到,恢复不会用到,可以直接使用alter database clear logfile group number命令重建;
如果是ACTIVE状态,说明这个online redo log还没归档完成,检查点可能还没有完成,恢复可能还会使用到,直接clear是不允许的,可以使用alter database clear unarchived logfile group number命令重建;
如果损坏的是CURRENT状态的日志,就比较麻烦了,可能会需要使用recover database until cancel做不完全恢复,还要设置隐含参数_allow_resetlogs_corruption=TRUE,最后还得是resetlogs的方式打开数据库,这就意味着,可能会丢失数据了,而且数据库还是不一致打开的,可能还会遇到ORA-00600错误,这样做之后最好是逻辑迁移一下数据,以免遇到其他问题。