undo表空间保存的是数据的前镜像,即修改之前的内容。
undo记录用来:
1.当发出一条rollback命令时,回滚事务。
2.恢复数据库
3.提供读一致性
4.当使用闪回查询时,分析某个早期时间点的数据。
5.使用闪回特性,从逻辑中断中恢复。
1.2表空间管理方式
一种是使用undo表空间,一种是使用回滚段。通过undo_management参数来控制使用哪种方式。如果设置为AUTO,则使用UNDO表空间。
这时需要指定一个UNDO表空间。如果设置为manul,系统启动后使用rollback segment存储UNDO信息。
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
1.3如果没有使用undo_management,则默认以manual启动,即使设置了auto方式下的其他参数,也会被忽略。
当实例启动时,系统选择第一个有效的UNDO表空间或者ROLLBACK segment,如果没有有效的可用的undo表空间或者回滚段,系统使用system rollback segment,这时会在alert.log记录一条警告信息。
此种情况不推荐使用。
当undo_management设置成manul时,使用系统回滚段,即将undo records记录到SYSTEM表空间的SYSTEM段。
SQL> col segment_name format a10;
SQL> select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='ROLLBACK';
SEGMENT_NA TABLESPACE_NAME BYTES NEXT_EXTENT
---------- ------------------------------ ---------- -----------
SYSTEM SYSTEM 393216 57344
1.4以上用于ROLLBACK 的system segment存在于system表空间。默认只有一个segment,并且比较小,如果来存储undo记录,则影响性能,因此ORACLE建议使用undo tablespace管理undo records.
当undo_management设置成auto时使用undo tablespace 来管理回滚段。这时,我们有多个undo segment并且这些segment存放在undo表空间里面。这里性能会提高。
SQL> select segment_name,tablespace_name,bytes,next_extent from dba_segments d where d.segment_type='TYPE2 UNDO';
SEGMENT_NA TABLESPACE_NAME BYTES NEXT_EXTENT
---------- ------------------------------ ---------- -----------
_SYSSMU1_5 UNDOTBS1 16908288 65536
92353410$
_SYSSMU2_9 UNDOTBS1 4325376 65536
67517682$
_SYSSMU3_1 UNDOTBS1 4325376 65536
204390606$
_SYSSMU4_1 UNDOTBS1 9568256 65536
003442803$
_SYSSMU5_5 UNDOTBS1 10616832 65536
38557934$
_SYSSMU6_2 UNDOTBS1 7471104 65536
897970769$
_SYSSMU7_3 UNDOTBS1 6422528 65536
517345427$
_SYSSMU8_3 UNDOTBS1 13762560 65536
901294357$
_SYSSMU9_1 UNDOTBS1 6488064 65536
735643689$
_SYSSMU10_ UNDOTBS1 14811136 65536
4131489474
$
10 rows selected
1.5也可以通过v$rollstat 和v$rollname两个视图来查看信息,这两个视图会显示所有rollback段信息,包括system 和undo段。
SQL> select a.usn,b.name,a.extents,a.hwmsize,a.status from v$rollstat a ,v$rollname b where a.usn = b.usn;
USN NAME EXTENTS HWMSIZE STATUS
---------- ------------------------------ ---------- ---------- ---------------
0 SYSTEM 6 385024 ONLINE
1 _SYSSMU1_592353410$ 18 16900096 ONLINE
2 _SYSSMU2_967517682$ 6 4317184 ONLINE
3 _SYSSMU3_1204390606$ 6 4317184 ONLINE
4 _SYSSMU4_1003442803$ 11 9560064 ONLINE
5 _SYSSMU5_538557934$ 12 10608640 ONLINE
6 _SYSSMU6_2897970769$ 9 7462912 ONLINE
7 _SYSSMU7_3517345427$ 8 6414336 ONLINE
8 _SYSSMU8_3901294357$ 15 13754368 ONLINE
9 _SYSSMU9_1735643689$ 9 6479872 ONLINE
10 _SYSSMU10_4131489474$ 16 14802944 ONLINE
11 rows selected
1.5 undo_retention 和retention guarantee
查看undo表空间的空闲和非空闲比例
SQL> select tablespace_name, status ,sum(bytes)/1024/1024 from dba_undo_extents d group by d.tablespace_name,d.status;
TABLESPACE_NAME STATUS SUM(BYTES)/1024/1024
------------------------------ --------- --------------------
UNDOTBS1 UNEXPIRED 19.375
UNDOTBS1 EXPIRED 70.9375
这里UNEXPIRED 和EXPIRED是已经使用的UNDO表空间,其中expired说明是已经过期的数据,可以被覆盖。
这里关系到一个参数:UNDO_RETENTION,此参数用来指定undo记录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修改,通常默认是900秒。
undo_retention只是指定undo的过期时间,并不是说,undo中的数据一定会在undo表空间中保留15分钟,比如一个事务刚开始的时候,如果undo表空间已经写满,则新事务会自动
覆盖已提交的事务的数据,而不写这些数据是否已经过期。因此,当创建一个自动管理的undo表空间时,要注意其空间大小,尽可能保证undo表空间有足够的存储空间。
undo_retention中指定的时间一过,已经提交的事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会依然存在,并随时可以被flashback特性引用。如果
undo表空间足够大,而数据库并不是太繁忙,那么undo_retention参数并不会有实质的影响。
如果保证undo表空间确保undo中的数据在undo_retention指定时间过期前一定有效,就要为undo表空间指定retention guarantee,指定之后,ORacle对于undo表空间中未过期的undo
数据不会覆盖。
SQL> alter tablespace UNDOTBS1 retention guarantee;
Tablespace altered
如果禁用,则如下:
SQL> alter tablespace UNDOTBS1 retention noguarantee;
Tablespace altered
UNDO表空间会被重用,只有当事务没结束,或开了retention guarantee或在undo_retention时间内不能被重用。
在undo_retention规定的时间内,数据都是有效的,过期后都会设置为无效,状态被改为Expired,这些回滚段将会被看作是Free Space,但是只是数据没有
覆盖就可以被使用。如果空间已满,则新事务的数据会自动覆盖掉已经提交的事务数据,即使是在undo_retention时间内。除非指定Retention Guarantee模式,
才能保证在undo_retention所规定的时间内不被覆盖。
1.6 undo表空间满时的处理
默认情况下undo_retention只有15分钟,这个默认值,一般情况下无法满足系统要求,建议改为3小时。
SQL> alter system set undo_retention=10800;
System altered
当然,此参数越大,需要的undo_tablespace也越大,这个是结合实际情况设置。
1.7 模拟undo表空间已满的情况
1.7.1创建UNDO表空间
SQL> create undo tablespace undotest datafile '/u01/app/oracle/oradata/orcl/undotest.dbf' size 1m;
Tablespace created
1.7.2设置数据不被覆盖
SQL> alter tablespace undotest retention guarantee;
Tablespace altered
1.7.3设置系统UNDO表空间,到新建的表空间
SQL> alter system set undo_tablespace=undotest;
System altered
1.7.4 模拟插入实验,jerry.bigtab为以前建的表。
SQL> insert into jerry.bigtab select rownum,a.* from dba_objects a;
insert into jerry.bigtab select rownum,a.* from dba_objects a
ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTEST'
1.7.5解决方法
1.7.5.1 添加undo表空间的数据文件。
SQL> alter tablespace undotest add datafile '/u01/app/oracle/oradata/orcl/undotest01.dbf' size 100m reuse;
Tablespace altered
SQL> insert into jerry.bigtab select rownum,a.* from dba_objects a;
72849 rows inserted
SQL> commit;
Commit complete
1.7.5.2 切换UNDO TABLESPACE。
建立新的UNDO表空间
SQL> create undo tablespace undotbs2 datafile '/u01/app/oracle/oradata/orcl/undotbs02.dbf' size 100m reuse;
Tablespace created
设置系统默认表空间到新的表空间
SQL> alter system set undo_tablespace=undotbs2 scope=both;
System altered
使原来的表空间脱机
SQL> alter tablespace undotest offline;
Tablespace altered
删除表空间及数据文件
SQL> drop tablespace undotest including contents and datafiles;
Tablespace dropped
如果只是drop tablespace undotest,则只会在控制文件中删除记录,并不会物理的删除文件。
drop undo 表空间的时间必须在未使用的情况下才能进行,如果undo表空间正在使用(例如事务失败,但是还没有恢复成功),那么
drop 表空间命令将失败。
1.8 undo表空间损坏的处理方法
出现UNDO损坏的情况,大多数是宕机,启动的时候报错。
比如出现ORA_00600: internal error code ,arguments :[4194]。对于undo损坏的情况,能用备份恢复最好,如果不能,
就只能通过一些特殊的方法来恢复。
1.8.1 先用system segment启动DB,启动之后,重新创建UNDO表空间,再用UNDO启动。
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='/u01/app/oracle/initorcl.ora';
3.删除原来的表空间,创建新的UNDO表空间
SQL>drop tablespace undotbs;
SQL> create undo tablespace undotbsq datafile '/u01/app/oracle/oradata/orcl/undotbs01.dbf' size 100m;
4.关闭数据库,修改pfile参数,用新的pfile创建spfile,再正常启动数据库。
#*.undo_tablespace='UNDOTBS1'
#*.undo_management='AUTO'
1.8.2 方法二:跳过损坏的segment
1.通过alert log 来查看正在使用的哪些segment ,这些段有可能损坏了,我们跳过损坏的段,再正常启动DB,再创建新的UNDO表空间,再切换。
*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'
这些字段值,可能通过alert log查看,也可以通过下面命令
#strings system01.dbf | grep _SYSSMU|cut -d $ -f l |sort -u
2.用修改之后的pfile启动DB
跳过了损坏的segment,DB可以正常启动
3.创建新的UNDO表空间,并切换回来
SQL>create tablespace undotbsq datafile '/u01/app/oracle/oradata/orcl/undotbs01.dbf' size 100m;
SQL> alter system set undo_tablespace=undotbs1
DROP掉原来的表空间
SQL>drop tablespace undotbs
4.修改pfile,创建spfile,并正常启动
删除:
*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'