问题背景:
客户数据库环境遭遇断电宕机,启动数据库失败,协助查看。
报错如下:
1 Total System Global Area 6442450944 bytes 2 Fixed Size 8807168 bytes 3 Variable Size 1375735040 bytes 4 Database Buffers 5049942016 bytes 5 Redo Buffers 7966720 bytes 6 Database mounted. 7 ORA-00742: Log read detects lost write in thread 1 sequence 1202 block 137840 8 ORA-00312: online log 18 thread 1: '/u01/app/oracle/oradata/orcl/redo18.log' 9 10 11 alter pluggable database all open 12 * 13 ERROR at line 1: 14 ORA-01109: database not open
问题解决:
宕机过程中redolog丢失
1 SQL> RECOVER DATABASE UNTIL CANCEL; //尝试recover 2 ORA-01547: 警告: RECOVER 成功但 OPEN RESETLOGS 将出现如下错误 ORA-01152: 3 文件 1 没有从过旧的备份中还原 ORA-01110: 4 数据文件 1: '/oracle/oradata/orcl/system01.dbf' 5 6 SQL> alter database open resetlogs; 7 alter database open resetlogs 8 *
第 1 行出现错误:
ORA-01152: 文件 1 没有从过旧的备份中还原 ORA-01110:
数据文件 1: '/oracle/oradata/orcl/system01.dbf'
alert.log中记录如下:
1 Errors in file /oracle/diag/rdbms/sem/SEM/trace/SEM_pr00_3546.trc: 2 ORA-01547: 警告: RECOVER 成功但 OPEN RESETLOGS 将出现如下错误 3 ORA-01152: 文件 1 没有从过旧的备份中还原 4 ORA-01110: 数据文件 1: '/oracle/oradata/SEM/system01.dbf' 5 ORA-1547 signalled during: ALTER DATABASE RECOVER DATABASE UNTIL CANCEL ... 6 Tue Sep 03 03:29:40 2013 7 Checker run found 15 new persistent data failures
很明显控制文件中的scn没赶上数据文件和数据头文件中的变化 然后尝试不玩全恢复
1 SQL> recover database using backup controlfile until cancel; 2 ORA-00279: 更改 6530705 (在 09/01/2013 02:59:56 生成) 对于线程 1 是必需的 ORA-00289: 3 建议: /oracle/archivelog/1_20_824696280.dbf 4 ORA-00280: 更改 6530705 (用于线程 1) 在序列 #20 中
指定日志: {<RET>=suggested | filename | AUTO | CANCEL}
cancel
介质恢复已取消。
SQL> alter database open resetlogs; --一般情况下到这里就能启动
数据库已更改。
此客户依然报错,尝试强制启动。
报错如下:
1 ERROR at line 1: 2 ORA-01194: file 1 needs more recovery to be consistent 3 ORA-01110: data file 1: '/opt/oracle/oradata/chf/system01.dbf'
修改隐含参数强制启动
1 SQL> create pfile='/tmp/pfile' from spfile; 2 3 File created. 4 5 -------/tmp/pfile中加上---------- 6 _allow_resetlogs_corruption= TRUE 7 --------------------------------- 8 9 SQL> startup mount pfile='/tmp/pfile' force 10 ORACLE instance started. 11 12 Total System Global Area 622149632 bytes 13 Fixed Size 2230912 bytes 14 Variable Size 419431808 bytes 15 Database Buffers 192937984 bytes 16 Redo Buffers 7548928 bytes 17 Database mounted.
依然报错:
添加参数
*.undo_management='MANUAL'
启动成功,怀疑为undo表空间损坏
启动成功后重建undo表空间
1.先把数据文件offline,在mount状态下执行:
SQL>alter database datafile '/software/oradata/JLPROJCT/undotbs01.dbf' offline drop ;
2,打开数据库
SQL>alter database open;
3.我们知道一个数据文件对应n个undo段,所有现在已经有好多undo 段已经 offline了,我们先不对他做任何操作,先查看不是offline的undo段,你会发现他们是不是offline的这些undo段是需要恢复(need recover)
SQL> select status,count(*) from dba_rollback_segs group by status; STATUS COUNT(*) ---------------- ---------- ONLINE 23 need recovery 5 OFFLINE 143
1 SQL>select segment_name,status from dba_rollback_segs where status<>'offline'; 就会发现所有用户回滚段是需要恢复的,状态是need recovery.,这个语句不会显示由于数据文件损坏而出现offline的回滚段。 2 3 SEGMENT_NAME STATUS 4 5 ------------------------------ ---------------- 6 7 SYSTEM ONLINE ###这是系统回滚段。 8 9 _SYSSMU154_3691636531$ need recovery 10 11 _SYSSMU155_3686385895$ need recovery 12 13 _SYSSMU156_3796802683$ need recovery 14 15 _SYSSMU157_2723916652$ need recovery 16 17 _SYSSMU158_1435464080$ need recovery
4.新建一个回滚表空间,
1 SQL>create undo tablespace undo2 datafile '/software/oradata/JLPROJCT/undotbs02.dbf' size 100m ; 2 tablespace created
5,把回滚段设置成人工管理,然后删除损坏的回滚段。
1 SQL>alter system set undo_tablespace= 'undo2' scope=spfile; ##指定成新建的undo表空间。 2 system altered 3 4 SQL>alter system set undo_management='manual' scope=spfile; 5 6 system altered
6,创建pfile
1 SQL>create pfile='/Oracle/app/pfile.ora from spfile; 2 file created
7,一致性关闭数据库,
1 SQL>shu immediate
8,在pfile 文件中添加一个隐藏参数,把这些回滚段都列在这个参数值里,
*._offline_rollback_segment=('_SYSSMU154_3691636531$','_SYSSMU155_3686385895$','_SYSSMU156_3796802683$','_SYSSMU157_2723916652$','_SYSSMU158_1435464080$')
9,创建成spfile 然后启动数据库。
SQL>create spfile from pfile; spfile created SQL>startup
10,这时候回滚段数量并没有发生改变,
1 SQL>select segment_name,status from dba_rollback_segs where status<>'offline'; 2 3 SEGMENT_NAME STATUS 4 5 ------------------------------ ---------------- 6 7 SYSTEM ONLINE 8 9 _SYSSMU154_3691636531$ need recovery 10 11 _SYSSMU155_3686385895$ need recovery 12 13 _SYSSMU156_3796802683$ need recovery 14 15 _SYSSMU157_2723916652$ need recovery 16 17 _SYSSMU158_1435464080$ need recovery
11,因为是手工管理,可以直接删除掉那些回滚段。
1 SQL> drop rollback segment “_SYSSMU154_3691636531$”; 2 3 rollback segment droped
12,然后删掉原来的undo表空间。
1 SQL>drop tablespace undo1 including contents;
13,然后重启数据库,
1 shu immediate 2 3 startup
14,注意这时候你的undo 管理还是手工的,所以要把之前的修改改正会自动管理。并且把添加的隐含参数*._offline_rollback_segment删掉。
1 SQL>alter system set undo_management='auto' scope=spfile;
第二种情况:当损坏的undo 表空间的回滚段上还有活动的事务,这种情况就要强行提交这些事务,就会造成一些数据的丢失。
1,启动数据库到mount状态,只能启动到这里,
2,把有问题的回滚段offline
1 SQL>alter database datafile '/software/oradata/JLPROJCT/undotbs01.dbf' offline drop ;
3,查看回滚段状态,和第一种情况略有不同,她没有offline的回滚段。
1 SQL>select usn,xacts from v$rollstat; 2 3 SQL> select status,count(*) from dba_rollback_segs group by status; 4 5 STATUS COUNT(*) 6 7 ---------------- ---------- 8 9 ONLINE 23 10 11 need recovery 5 12 13 QL>select segment_name,status from dba_rollback_segs where status<>'offline'; 14 15 SEGMENT_NAME STATUS 16 17 ------------------------------ ---------------- 18 19 _SYSSMU154_3691636531$ need recovery 20 21 _SYSSMU155_3686385895$ need recovery 22 23 _SYSSMU156_3796802683$ need recovery 24 25 _SYSSMU157_2723916652$ need recovery 26 27 _SYSSMU158_1435464080$ need recovery
4,试图创建发现报错,真正工作中可以从这里来判断到底是那种情况,第一种情况是可以重新建立的。
必须先禁止继续使用旧的回滚段和回滚空间:
1 SQL>create pfile=/oracle/app/pfile.ora from spfile 2 file created 3 4 SQL>shutdown immediate ;
在pfile中添加并修改以下内容:
1 *.undo_management='manual' ###手动管理,才可以删除回滚段 2 3 *._offline_rollback_segments=('_SYSSMU154_3691636531$','_SYSSMU155_3686385895$','_SYSSMU156_3796802683$','_SYSSMU157_2723916652$','_SYSSMU158_1435464080$') ###这样才能删除这些回滚段 4 5 *.undo_tablespace='undo2' ###这样就会让以后的事务不在用旧的回滚段和undo表空间,
5.创建成spfile 然后启动数据库。
1 SQL>create spfile from pfile; 2 spfile created 3 4 SQL>startup
6,删除旧的回滚段和回滚表空间:
1 SQL>drop rollbackup segment '_SYSSMU154_3691636531$' ;
把need recovery 的回滚段全部删除后,
SQL>drop undo tablespace undo1 including contents; ###因为已经丢失,就不必要添加数据文件了(and datafiles 选项了)
7,创建一个新的undo表空间,然后启动数据库,再修改undo_management 为自动。
注意这样后,所有未提交的事务都当做提交处理了。
更多内容请关注微信公众号:数据与人
来源:https://www.cnblogs.com/sunkang-dba/p/12508587.html