问题描述

Oracle 突然断电后,无法启动,错误信息

  • end-of-file on communication channel
  • instance terminated by user , pid = <pid>
  • control filesequence number mismatch
  • file 1 needs more recovery to be consistent

问题排查

尝试启动 Oracle

1
2
3
4
5
6
7
8
9
10
# 使用dba登录
sqlplus / as sysdba;

# 查看当前实例状态 (状态分几步 nomount未挂载文件 mount已挂载数据文件 open已挂载并打开数据文件 shutdown 关闭状态)
select status from v$instance;

# 尝试启动(完整启动)
startup;
# 出现错误end-of-file on communication channel

查看 Oracle 启动日志

启动日志路径 $ORACLE_BASE/diag/rdbms/<db_name>/<instance_name>/trace/alert_<instance_name>.log

日志出现instance terminated by user , pid = <pid>, log 文件只有最初级的错误日志,下一步查看 trc 日志文件,在 log 文件的同目录下,会有一个<pid>.trc 文件,这里是更详细的 trace 日志,找到详细错误日志kccpb_sanity_check_2 control filesequence number mismatch

分析问题

  1. 问题根源是 kccpb_sanity_check_2 control filesequence number mismatch
  2. Oracle 在启动时会检查控制文件(*.ctl)的序列号
  3. 控制文件的作用是管理归档文件和数据文件(dbf)
  4. 由于强制断电,导致 Oracle 在写入控制文件过程中断开,出现控制文件与数据文件不对应的问题

问题处理

启动到数据库未挂载前

1
2
sqlplus / as sysdba;
startup nomount;

开始重建控制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   -- db_name 一般为orcl
CREATE CONTROLFILE REUSE DATABASE "<db_name>"
-- 注意,这里是归档日志未备份的情况,如果可以不重建日志文件
RESETLOGS -- 重建日志文件
NOARCHIVELOG -- 无归档日志
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 1
MAXLOGHISTORY 292
LOGFILE
-- 所有的REDO文件!!!!
GROUP 1 '/PATH/REDO01.LOG' SIZE 50M,
GROUP 2 '/PATH/REDO02.log' SIZE 50M,
GROUP 3 '/PATH/REDO03.log' SIZE 50M
DATAFILE
-- 这里一定要是所有的数据文件!!!!
'/PATH/SYSTEM01.DBF',
'/PATH/SYSTEM02.DBF',
'/PATH/USERS01.DBF',
'/PATH/UNDOTBS01.DBF',
'/PATH/SYSAUX01.DBF'
-- 按照数据库实际的字符集
CHARACTER SET ZHS16GBK;

-- 重建成功结果为 Control file created.

检查当前实例状态

1
2
select status from v$instance;
-- 此刻应该转为 mounted

启动数据库

这里我们已经将数据从无法挂载状态修复到了已挂载数据文件阶段

尝试启动alter database open resetlogs (这里要根据上面重建时选项)

数据文件损坏

恢复之前要慎重,慎重,一定要确保构建控制文件时的数据文件是完整的

  • 上一步启动,出现文件损坏file 1 needs more recovery to be consistent
  • 修复数据库recover database using backup controlfile;
  • 出现提示specify log (suggested filename auto cancel),这里是 recover 未找到归档文件,如果有归档文件可以填入归档文件,没有的话填写 REDO 文件

再次尝试启动数据库

alter database open resetlogs;

这里应该可以启动成功

检查数据文件状态

select * from dba_data_files;

此处文件应该都是 ONLINE 状态,如果出现 MISSING000*文件则说明在修复控制文件时,你的数据文件没有完全传入,通常情况下数据文件的后缀是 DBF,如果创建数据库表空间数据文件时没有按照规范,也可能是其他的后缀,一定一定要确认清楚

问题总结

  1. 查看alert_启动日志
  2. 查看更详细的.trc日志
  3. 找到问题control filesequence number mismatch
  4. 重建控制文件create controlfile reuse database "<db_name>"
  5. 修复数据库recover database using backup controlfile
  6. 启动数据库 alter database open resetlogs

附加

REDO 文件与归档日志文件对比

特性 REDO 日志文件 归档日志文件
用途 数据恢复、回滚、重做日志记录 数据恢复、时间点恢复和备份支持
存储形式 循环使用,可能被覆盖 不被覆盖,需手动清理
写入方式 LGWR后台进程实时写入 ARCn后台进程异步生成
模式依赖 无需归档模式 必须启用归档模式
数据内容 数据库事务的实时更改 REDO 日志文件的副本