Oracle Redo日志与Undo回滚段损坏恢复实战
没有RMAN备份的情况下,分别针对Redo日志损坏和Undo回滚段损坏的恢复方法。
场景一:Redo日志损坏恢复
数据库redo日志损坏,无法打开,没有备份。
恢复步骤
1. 设置隐藏参数允许损坏恢复
sql
alter system set "_allow_resetlogs_corruption"=true scope=spfile;
alter system set "_allow_terminal_recovery_corruption"=true scope=spfile;
两个参数必须同时设置。第一个允许在resetlogs时容忍数据文件中的不一致数据,第二个允许终端恢复时容忍损坏。
2. 关闭数据库
shutdown immediate;
如果immediate关不了,用shutdown abort。
3. 启动到mount状态
startup mount;
4. 使用备份控制文件恢复
sql
recover database using backup controlfile until cancel;
提示输入日志文件时输入cancel------因为日志文件已经损坏了,无法应用。
5. 清理损坏的日志文件组
sql
alter database clear logfile group <group_number>;
把损坏的redo日志组清理掉。<group_number>替换为实际的组号,可以通过select * from v$log;查看。
6. 用resetlogs方式打开数据库
sql
alter database open resetlogs;
这是关键一步。resetlogs会重置日志序列号,相当于给数据库一个新的开始。
7. 切换日志
sql
alter system switch logfile;
打开后立刻切换一次日志,确保新的redo日志正常工作。
8. 重置隐藏参数为false
sql
alter system set "_allow_resetlogs_corruption"=false scope=spfile;
alter system set "_allow_terminal_recovery_corruption"=false scope=spfile;
恢复完成后必须把参数改回false,否则数据库长期运行在容忍损坏的状态下,后续问题会被掩盖。
9. 重启数据库
shutdown immediate;
startup;
重启确认参数生效,数据库正常运行。
Redo恢复流程图
设置 _allow_resetlogs_corruption=true
↓
关闭数据库
↓
startup mount
↓
recover database using backup controlfile until cancel → cancel
↓
alter database clear logfile group <n>
↓
alter database open resetlogs
↓
alter system switch logfile
↓
设置 _allow_resetlogs_corruption=false
↓
重启数据库
场景二:Undo回滚段损坏修复
数据库undo表空间损坏,同时可能有其他无关表空间也损坏。
修复步骤
1. 启动到mount状态
sql
startup mount;
2. 从spfile创建pfile
sql
create pfile from spfile;
pfile会生成在$ORACLE_HOME/dbs/目录下,文件名格式为init<SID>.ora。
3. 关闭数据库
sql
shutdown immediate;
4. 修改pfile文件
编辑$ORACLE_HOME/dbs/init<SID>.ora,修改以下两个参数:
undo_management=MANUAL
undo_tablespace=SYSTEM
关键:把undo管理模式从AUTO改为MANUAL,把undo表空间从损坏的用户undo表空间改为系统表空间SYSTEM。这样Oracle启动时就不会去读损坏的undo表空间。
5. 用修改后的pfile启动到mount
sql
startup mount pfile=$ORACLE_HOME/dbs/init<SID>.ora;
6. 查看数据文件列表
sql
select file#, name from v$datafile;
记录所有数据文件的编号和路径。
7. 尝试打开数据库
sql
alter database open;
如果提示某个数据文件需要恢复(那是损坏的表空间对应的文件),执行下一步。
8. 将损坏的数据文件offline并drop
sql
alter database datafile <文件号> offline drop;
把损坏的表空间对应的数据文件offline掉,然后重新执行步骤7:
sql
alter database open;
如果有多个损坏的文件,逐个offline drop后再open。
Undo恢复流程图
startup mount
↓
create pfile from spfile
↓
shutdown immediate
↓
修改pfile: undo_management=MANUAL, undo_tablespace=SYSTEM
↓
startup mount pfile=...
↓
select file#, name from v$datafile (记录文件号)
↓
alter database open
↓
如果报错 → alter database datafile <n> offline drop → 重新open
↓
数据库打开成功
Undo恢复后要做的事
-
创建新的undo表空间:
sqlcreate undo tablespace undotbs2 datafile '/path/to/undotbs2.dbf' size 500M; -
修改spfile指向新的undo表空间:
sqlalter system set undo_tablespace=undotbs2 scope=spfile; alter system set undo_management=AUTO scope=spfile; -
重启数据库,确认使用新的undo表空间
-
删除旧的损坏的undo表空间(如果还能删的话)
注意事项
- 这是最后手段,有备份就不要用这些方法
- resetlogs后之前的备份全部失效,必须重新做全库备份
- 隐藏参数以
_开头,Oracle不公开支持,生产环境慎用 - open resetlogs后建议立刻导出数据,重建数据库更安全