下载丨9月数据库技术通讯:Redo日志丢失,重建遭遇ORA-16433处理

时间:2022-07-26
本文章向大家介绍下载丨9月数据库技术通讯:Redo日志丢失,重建遭遇ORA-16433处理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

这里推荐一个常见的问题,希望对大家有借鉴作用。

故障: Redo日志丢失,重建遭遇ORA-16433处理

在Oracle中,Redo日志文件包含所有的数据库变化历史记录,例如所有的DML变化(INSERT、UPDATE、DELETE和SELECT FOR UPDATE)和所有DDL语句造成的数据字典对象的更改及递归语句的更改等,所以redo文件可以最大限度地保证数据的一致性与安全性。万一数据库出现故障可以启用数据恢复。但是redo日志被误删了怎么办呢?本文通过一个案例来了解一下redo日志被误删,强制开库遭遇ORA-16433,供大家参考。

问题描述:客户的一套开发环境,版本为11.2.0.4, redo在清理空间时被运维人员当作log误删除,在恢复的过程中已经做过resetlogs的操作,并且将“_allow_resetlogs_corruption"这个隐藏参数设置成了true,但是在mount状态打开数据库时会提示需要恢复,重新进行resetlogs时报错ORA-600 [2662]。根据以往经验,推进SCN就好了,但是推进之后还是无法打开数据库,最后通过重建控制文件得以解决。

问题分析

1、强行打开数据库报错 当redo日志不存在的时候,强制打开数据库会报错,然后根据报错提示进行恢复,再次进行resetlogs启动的时候报错

SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1:
'/oradata/ODSDB/datafile/data_D-ODSDB_I-3532120983_TS-SYSTEM_FNO-1_1bujd4ob.dbf'

SQL> recover database ;
***
ORA-00312: online log 5 thread 1: '/oradata/ODSDB/datafile/redo05.log'

SQL> recover datafile 1;
***
ORA-00312: online log 5 thread 1: '/oradata/xxxx/datafile/redo05.log'

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01139: RESETLOGS option only valid after an incomplete database recovery

SQL> recover database using backup controlfile until cancel;
ORA-00279: change 32581427072 generated at  needed for thread 1
***
ORA-01110: data file 1:
'/oradata/ODSDB/datafile/data_D-ODSDB_I-3532120983_TS-SYSTEM_FNO-1_1bujd4ob.dbf'

SQL>  alter database open resetlogs;
 alter database open resetlogs
*
ERROR at line 1:
ORA-00603: ORACLE server session terminated by fatal error
***
[2516660859], [327174016], [], [], [], [], [], []
Process ID: 3997864
Session ID: 580 Serial number: 5

2、根据报错推进SCN

重新启动到mount状态,根据上面报错计算要推进的SCN值

SQL> select open_mode from v$database;
OPEN_MODE
--------------------
MOUNTED
SQL> select current_scn from v$database;
SQL> set num 30
30217546463
select 7*power(2,32) + 2516660859 from dual;

select 7*power(2,32) + 2516661000 from dual;
32581432072

使用oradebug poke进行SCN推进:

SQL> oradebug setmypid
Statement processed.
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [700000000019B70, 700000000019BA0) = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 07000000 00019850
SQL> oradebug poke 0x700000000019B70 8 32581432072
BEFORE: [700000000019B70, 700000000019B78) = 00000000 00000000
AFTER:  [700000000019B70, 700000000019B78) = 00000007 96013308
SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [700000000019B70, 700000000019BA0) = 00000007 96013308 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 07000000 00019850

推进之后,打开数据库依然报错

SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-00399: corrupt change description in redo log
ORA-00353: log corruption near block 3 change 32581427074 time 08/25/2020
11:39:04
ORA-00312: online log 5 thread 1: '/oradata/ODSDB/datafile/redo05.log'

这时候看起来有些麻烦,根据报错推断之前的resetlogs其实都没有完全成功。此时查询各个checkpoint_change#都是一致的,正常应该可以open成功。但是即使尝试read only开库都会报错ORA-16433

SQL> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-16433: The database must be opened in read/write mode.

查了下这个错误,看起来控制文件有些问题,于是想重建下控制文件,结果发现命令同样报错ORA-16433,而正常mount下,是可以执行此命令的。

没办法,只能根据控制文件的语法,查询必要信息,然后手工构建控制文件的创建脚本

重建控制文件之后,再次推进SCN,就可以打开数据库了

select 7*power(2,32)+2616661492 from dual;
32681432564

--recover again..
conn /as sysdba
SQL>startup nomount;
SQL>@create_controlfile.sql
SQL>oradebug setmypid
SQL>oradebug dumpvar sga kcsgscn_
SQL>oradebug poke 0x700000000019B70 8 32681432564
SQL>oradebug dumpvar sga kcsgscn_

SQL>recover database using backup controlfile until cancel;
SQL>alter database open resetlogs;

最后将隐藏参数"_allow_resetlogs_corruption"设置为false,正常重启数据库正常:

SQL>alter system set "_allow_resetlogs_corruption" = false scope=spfile;
SQL>shut immediate
SQL>startup

问题总结

总结:主要还是推进SCN,只是这次遇到报错ORA-16433需要重建控制文件。