一、概述

SQL> show parameter undo

NAME TYPE VALUE

----------------------------------------------- ------------------------------

undo_management string AUTO

undo_retention integer 900

undo_tablespace string UNDOTBS1

1.1 当undo_management被设置成MENUAL时使用系统回滚段,即将undo records记录到SYSTEM表空间下的SYSTEM段。

SQL> col segment_name formata25

SQL> selectsegment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='ROLLBACK';

SEGMENT_NAME TABLESPACE_NAME BYTES NEXT_EXTENT

------------------------------------------------------- ---------- -----------

SYSTEM SYSTEM 393216 57344

通过上面的这条语句,我们查到了这个用于rollback的system segment存在于system表空间。默认情况下,只有一个segment,并且它还比较小,所以,如果使用system段来存储undo records。肯定会影响数据库的性能。所以Oracle是建议使用Undo tablespace来管理undo records。

1.2 当undo_management设置成AUTO时使用UNDO tablespace来管理回滚段。这个时候,我们将有多个undo segment,并且这些segment是存放在UNDO表空间里的。这样对DB的性能就会提高。

SQL> selectsegment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='TYPE2 UNDO';

SEGMENT_NAME TABLESPACE_NAME BYTES NEXT_EXTENT

------------------------------------------------------- ---------- -----------

_SYSSMU1_3724004606$ UNDOTBS1 8519680 65536

_SYSSMU2_2996391332$ UNDOTBS1 8519680 65536

_SYSSMU3_1723003836$ UNDOTBS1 2228224 65536

_SYSSMU4_1254879796$ UNDOTBS1 3276800 65536

_SYSSMU5_898567397$ UNDOTBS1 8519680 65536

_SYSSMU6_1263032392$ UNDOTBS1 8519680 65536

_SYSSMU7_2070203016$ UNDOTBS1 8519680 65536

_SYSSMU8_517538920$ UNDOTBS1 1179648 65536

_SYSSMU9_1650507775$ UNDOTBS1 8519680 65536

_SYSSMU10_1197734989$ UNDOTBS1 8519680 65536

10 rows selected.

SQL>

通过以上SQL的查询结果,我们可以看出,有10个undosegment来存放undo records。

以上我们是通过dba_segment视图查看的结果。而也可以通过v$rollstat和v$rollname两个视图来查看信息,这2个视图会显示所有rollback段的信息,包括system段和undo段。

SQL> col name format a25

SQL> selects.usn,n.name,s.extents,s.hwmsize,s.status from v$rollstat s, v$rollname n wheres.usn=n.usn;

USN NAME EXTENTS HWMSIZE STATUS

----------------------------------- ---------- ---------- ----------

0 SYSTEM 6 385024 ONLINE

1 _SYSSMU1_3724004606$ 3 8511488 ONLINE

2 _SYSSMU2_2996391332$ 3 8511488 ONLINE

3 _SYSSMU3_1723003836$ 4 2220032 ONLINE

4 _SYSSMU4_1254879796$ 4 3268608 ONLINE

5 _SYSSMU5_898567397$ 3 8511488 ONLINE

6 _SYSSMU6_1263032392$ 3 8511488 ONLINE

7 _SYSSMU7_2070203016$ 3 8511488 ONLINE

8 _SYSSMU8_517538920$ 3 1171456 ONLINE

9 _SYSSMU9_1650507775$ 3 8511488 ONLINE

10 _SYSSMU10_1197734989$ 3 8511488 ONLINE

11 rows selected.

SQL>

二、UNDO损坏的处理2.1方法一,使用system segment

提到了一种方法,就是使用SYSTEM的回滚段,步骤如下:

(1)用spfile创建pfile,然后修改参数:

#*.undo_tablespace='UNDOTBS1'

#*.undo_management='AUTO'

#*.undo_tablespace

#*.undo_retention

undo_management='MANUAL'

rollback_segments='SYSTEM'

(2)用修改之后的pfile,重启DB

SQL>STARTUP MOUNT pfile='F:/initorcl.ora' ;

(3)删除原来的表空间,创建新的UNDO表空间

SQL>drop tablespace undotbs;

SQL>create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M;

(4)关闭数据库,修改pfile参数,然后用新的pfile创建spfile,在正常启动数据库。

*.undo_tablespace='UNDOTBS1'

*.undo_management='AUTO'

#undo_management='MANUAL'

#rollback_segments='SYSTEM'

2.2.方法二:跳过损坏的segment

在方法一中,我们使用了system segment。通过第一部分我们了解到,undo segment有多个,我们可以通过alert log来查看正在使用的是哪些segment,这些段有可能损坏了。我们只需要把这些损坏的segment跳过,先正常启动DB,在创建新的UNDO表空间,在切换一下。

(1)修改pfile,添加参数:

*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'

这些字段的值,我们通过alert log查看。也可以通过如下命令查看:

#stringssystem01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort -u

(2)用修改之后的pfile启动DB

因为跳过了哪些损坏的segment,所以DB可以正常启动。

(3)创建新的UNDO表空间,并切换过来

SQL>create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M;

SQL>alter system set undo_tablespace=undotbs1;

SQL>drop tablespace undotbs;

(4)修改pfile,创建spfile,并正常启动

删除如下:

*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'

2.3 方法三:使用rman备份恢复

startup mount

--检验备份是否有坏块

RMAN> backup validate datafile 22;

--查询坏块信息

RMAN> select * from v$database_block_corruption wherefile#=22;

FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO CON_ID

---------- ---------- ---------- ------------------ -------------------

22 32120 1 0 CORRUPT 1


--修复坏块

RMAN> blockrecover datafile 22 block 32120 from backupset;

--打开数据库

alter database open;

注:其它文件(system/sysaux/用户数据文件)坏块也可用这种方式修复

2.4 方法四:使用参数_offline_rollback_segments和_corrupted_rollback_segments

在没有备份的情况下,

使用_offline_rollback_segments和_corrupted_rollback_segments

1.先把数据文件offline,在mount状态下执行:

alter database datafile'/oracle/app/oracle/oradata/cus/undotbs01.dbf' offline;

alter database open;

2.查询哪些undo段是需要恢复(need recover)

select segment_name,status from dba_rollback_segs where status ='NEEDS RECOVERY';

3. 新建一个回滚表空间,生成pfile

create undo tablespace undotbs2 datafile'/oracle/app/oracle/oradata/cus/undotbs02.dbf' size 300m;

alter system set undo_tablespace='undotbs2';

create pfile='/home/oracle/pfile.txt' from spfile;

4.编辑pfile,添加隐含参数

--根据第2步查询需要恢复的undo段

?*._offline_rollback_segments=('_SYSSMU3_1499641855$','_SYSSMU4_3564003469$',......)

*._corrupted_rollback_segments=('_SYSSMU3_1499641855$',_SYSSMU4_3564003469$',......)

5.重新启动,删除旧的undo

startup pfile='/home/oracle/ pfile.txt';

drop tablespace undotbs1including contents and datafiles;

?selectsegment_name,status from dba_rollback_segs where status = 'NEEDS RECOVERY';


6. 去掉隐含参数,重新启动数据库

将pfile.txt文件去掉前面两个隐含参数_offline_rollback_segments和_corrupted_rollback_segments,然后重新启动数据库

shutdown immediate;

startup pfile='/home/oracle/pfile.txt';

create spfile frompfile='/home/oracle/pfile.txt';

shutown immediate;

startup;

总结

以上就是UNDO出现故障的几种处理方法,其中方法二和方法四类似,都是采用参数进行恢复。