undo
undo是保存你过去数据的地方,即如果你update了一行,则原值会放在undo segment中,或者你delete了一行,原值也会放到undo中。
作用
1、rollback回退。也包括flashback。
2、consistent读。
存放位置
11g中是存放在专门的表空间,undo表空间内的,如果系统没有undo表空间,则undo segment会存放在system表空间。
创建方法
1、在create database中指定
2、使用create undo tablespace创建。
相关参数
undo_retention 即镜像保留时间,单位是秒,默认是900秒即15分钟,如果过去的镜像已经expired并被overwrite,而其他session还需要查询此镜像,则会出现ora-01555"snapshot is too old"错误。
如果expired是否被剔除,还是空间不够才被剔除,
空间不够才会被剔除。
自动调整undo_retention是在什么情况下,自动管理模式是必须的吗?
在固定undo表空间大小的情况下,所有你设置的retention将会别忽略。就是autoextend off的情况下。
这个自动调整是由一个隐含参数_undo_autotune控制的,默认是true。
如果没有expired段,还缺少空间改怎么弄?
会把标注为unexpired的段剔除掉,如果想让你的retention策略得到保证,则需要对undo表空间使用guarentee参数。
一个段怎么才回从unexpired变为expired,commit和rolback会对这些segment产生什么影响?
rentention 过了这个时间,回话没有提交或回滚,对这些extent怎么处理?
这时该segment仍旧会别剔除出去,这时若会话需要使用到undo数据,则会产生ora-1555
回话已经结束,而retention时间没到,这些extent会怎么标记?
若没有会话提出申请,则数据仍留存在segment中,直到有下个transaction需要使用该segment,才把这个segment剔除。
undo_management auot | manual。其中auto是默认的,oracle也极力推荐使用自动。
undo_tablespace 指定undo表空间。你系统中可有有多个undo表空间,指定一个在用就OK了。
retention_guarantee这个需要时undo表空间的一个设置参数,可以使用alter tablespace undotbs1 retention guarantee.| noguarantee来更改。这个参数设置就能保证你的镜像在过期之前是怎么样都不会被T出去的。但是不建议这样做,因为这样就有可能导致许多回话因为没有undo分配而失败。
确定undo表空间的大小?
有这样一个视图,v$undostat记录了undo状态的一个柱状图
它每十分钟生成一行数据,统计这十分钟的undo数据。
undo丢失
undo损坏
undo丢失和损坏都有两种,一种是有事务,一种是无事务。
无事务比较简单,基本就跟是
修改undo_management=manual
启动数据库到mount状态
离线有问题的undo表空间
alter database datafile '/data/jf01/undotbs1.dbf' offline drop;
然后更改数据库到open
alter database open;
之后创建新的undo表空间
create undo tablespace undots01 datafile '/data/jf01/undots01.dbf' size 10M autoextent on;
然后关闭数据库
修改参数文件
undo_management=auto
undo_tablespace=tndots01
启动数据库就ok了。
这上面的步骤没有做删除丢失或损坏的undo表空间的操作,如果undo为无事务丢失或损坏,那么直接在数据库open状态下
drop tablespace undotbs01 including contents and datafile;
就可以成功了。
如果在有事务的情况下,你直接drop tablespace 却可能会出现报错,比如
SQL> drop tablespace undotbs1 including contents and datafiles;
drop tablespace undotbs1 including contents and datafiles
*
ERROR at line 1:
ORA-01548: active rollback segment '_SYSSMU1_3780397527$' found, terminate
dropping tablespace
你可以查看dba_rollback_segs查看表空间中有哪些影响删除的回滚段。那些status为offliine的回滚段不影响删除,影响的时online和need recoved。
如果有回滚段为online,说明还有事务在使用该回滚段
可以查找出来使用这些回滚段的事务,并强制提交这些事务。
具体操作为
首先,找出状态为online的回滚段段号
Select
segment_id,segment_name,status,tablespace_name
2
from
dba_rollback_segs
where
status
not
in
(
'ONLINE'
,
'OFFLINE'
);
SEGMENT_ID SEGMENT_NAME STATUS TABLESPACE_NAME
---------- ------------------------------ ---------------- ------------------------------
2 _SYSSMU2$ PARTLY AVAILABLE UNDOTBS1
3 _SYSSMU3$ PARTLY AVAILABLE UNDOTBS1
6 _SYSSMU6$ PARTLY AVAILABLE UNDOTBS1
8 _SYSSMU8$ PARTLY AVAILABLE UNDOTBS1
SQL>
SELECT
KTUXEUSN, KTUXESLT, KTUXESQN,
/* Transaction ID */
KTUXESTA Status,
2 KTUXECFL Flags
FROM
x$ktuxe
WHERE
ktuxesta!=
'INACTIVE'
;
KTUXEUSN KTUXESLT KTUXESQN STATUS FLAGS
---------- ---------- ---------- ---------------- ------------------------
2 38 583286 PREPARED SCO|COL|REV|DEAD|EXTDTX
3 29 982959 PREPARED SCO|COL|REV|DEAD|EXTDTX
6 14 945326 PREPARED SCO|COL|REV|DEAD|EXTDTX
8 7 957413 PREPARED SCO|COL|REV|DEAD|EXTDTX
13 19 507098 PREPARED SCO|COL|REV|EXTDTX
SQL>
select
local_tran_id, state
from
dba_2pc_pending;
LOCAL_TRAN_ID STATE
---------------------- ----------------
14.28.100017 collecting
2.38.583286 prepared
8.7.957413 prepared
3.29.982959 prepared
6.14.945326 prepared
13.19.507098 prepared
6
rows
selected.
QL>
commit
force
'8.7.957413'
;
Commit
complete.
SQL>
commit
force
'3.29.982959'
;
Commit
complete.
SQL>
commit
force
'6.14.945326'
;
Commit
complete.
SQL>
commit
force
'13.19.507098'
;
Commit
complete.
这样就可以正常删除了。
而如果你的undo数据文件已丢失或块损坏,而
undo segment处于need recovery则可以使用隐含参数
*._allow_resetlogs_corruption=true
*._corrupted_rollback_segments=(_SYSSMU4_1152005954$,_SYSSMU5_1527469038$,_SYSSMU6_2443381498$,_SYSSMU7_3286610060$,_SYSSMU8_2012382730$,_SYSSMU9_1424341975$,_SYSSMU10_3550978943$,_SYSSMU1_3780397527$,_SYSSMU2_2232571081$,_SYSSMU3_2097677531$ )
把这两个参数加入参数文件,并启动数据库
之后执行
drop rollback segment _SYSSMU1$
把这些段一一删除后,再删除表空间就行了。
undo切换
undo查询
关于ora-01555错误
ora-1555错误就是快照过旧,undo信息别覆盖。
但分析解决这个问题的时候,不仅仅要考虑undo tablespace的情况和undo_rentention的设置。
而且,undo segment并不仅仅存在于undo表空间这一种。
1、undo tablespace
2、system rollback segment
3、LOB问题
所以要进步究竟引起1555的根在哪部分。
另外一种解决方法
使用隐含参数
_corrupted_rollback_segments
屏蔽掉有问题的rollback segment后,
open数据库
alter session set "_smu_debug_mode"=4
然后直接
drop rollback segment "_Sys"