开发过程中,执行一个大事务时,会发现可能存在性能问题,这里我们一起来关注下回滚段的变化情况,看看AUM(Auto Undo Management)是如何工作的。
查看回滚段的信息:
SELECT a.USN,--ID号
b.segment_name, --回滚段名
a.RSSIZE, --回滚段大小
a.SHRINKS, --回滚段收缩次数
a.WRAPS --回滚段跳转次数
FROM v$rollstat a,Dba_Rollback_Segs b
WHERE a.USN=b.segment_id;
查询session对应的回滚段:
SELECT S.SID,
S.USERNAME,
U.NAME,
R.RSSIZE,
R.WAITS, --大于1,回滚段争用
R.XACTS, --大于1,活动事务争用回滚段
r.WRITES --已经用了多少回滚段
FROM V$TRANSACTION T, V$ROLLSTAT R, V$ROLLNAME U, V$SESSION S
WHERE S.TADDR = T.ADDR
AND T.XIDUSN = R.USN
AND R.USN = U.USN
AND S.SID IN (159, 158)
---undo_management设置为auto,不能指定使用回滚段
1. 事务是不能跨回滚段的,commit或rollback后不能立即回收回滚段
--查询sid
SQL> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
159 0 1
--查询所使用的回滚段的情况,注意必须要DML操作后才能查询到sid使用的回滚段
SQL> set heading off
SELECT S.SID,
S.USERNAME,
U.NAME,
R.RSSIZE,
r.WRITES
FROM V$TRANSACTION T, V$ROLLSTAT R, V$ROLLNAME U, V$SESSION S
WHERE S.TADDR = T.ADDR
AND T.XIDUSN = R.USN
AND R.USN = U.USN AND S.SID IN (159);
159 ORACLE _SYSSMU5$ 10608640(回滚段大小) 2293172(用了多少)
--回滚段对应的区情况
SELECT t.SEGMENT_NAME,t.EXTENT_ID,t.STATUS
FROM Dba_Undo_Extents t WHERE t.segment_name='_SYSSMU7$' ORDER BY t.EXTENT_ID;
_SYSSMU7$ 0 ACTIVE
_SYSSMU7$ 1 ACTIVE
_SYSSMU7$ 2 ACTIVE
_SYSSMU7$ 3 EXPIRED
_SYSSMU7$ 4 EXPIRED
_SYSSMU7$ 5 EXPIRED
_SYSSMU7$ 6 EXPIRED
_SYSSMU7$ 7 EXPIRED
_SYSSMU7$ 8 EXPIRED
_SYSSMU7$ 9 EXPIRED
_SYSSMU7$ 10 ACTIVE
_SYSSMU7$ 11 ACTIVE
--执行删除操作,观察回滚段的变化
SELECT t.SEGMENT_NAME,t.EXTENT_ID,t.STATUS
FROM Dba_Undo_Extents t WHERE t.segment_name='_SYSSMU7$' ORDER BY t.EXTENT_ID DESC;
SEGMENT_NAME EXTENT_ID STATUS
------------------------------ ---------- ---------
_SYSSMU7$ 72 ACTIVE ---区不断扩展,状态变为active,这是一个性能的问题点,回滚段的扩展是很耗性能的
_SYSSMU7$ 71 ACTIVE
_SYSSMU7$ 70 ACTIVE
_SYSSMU7$ 69 ACTIVE
_SYSSMU7$ 68 ACTIVE
_SYSSMU7$ 67 ACTIVE
_SYSSMU7$ 66 ACTIVE
_SYSSMU7$ 65 ACTIVE
_SYSSMU7$ 64 ACTIVE
_SYSSMU7$ 63 ACTIVE
_SYSSMU7$ 62 ACTIVE
SELECT S.SID,
S.USERNAME,
U.NAME,
R.RSSIZE,
R.WRAPS
r.WRITES
FROM V$TRANSACTION T, V$ROLLSTAT R, V$ROLLNAME U, V$SESSION S
WHERE S.TADDR = T.ADDR
AND T.XIDUSN = R.USN
AND R.USN = U.USN AND S.SID IN (159);
SID USERNAME NAME RSSIZE WRAPS WRITES
---------- ------------------------------ -------------------------------------------------------------------------
159 ORACLE _SYSSMU7$ 438034432 228 430175292
--回滚大小和写大小不断扩展,区间的跳转次数也增加
--commit,再看回滚段的变化
SQL> commit;
SELECT a.USN,
b.segment_name,
a.RSSIZE,
a.SHRINKS,
a.WRAPS
FROM v$rollstat a,Dba_Rollback_Segs b
WHERE a.USN=b.segment_id;
0 SYSTEM 385024 0 0
1 _SYSSMU1$ 188416 1 5
2 _SYSSMU2$ 122880 1 2
3 _SYSSMU3$ 1171456 1 0
4 _SYSSMU4$ 1171456 2 1
5 _SYSSMU5$ 235003904 11 139
6 _SYSSMU6$ 1171456 2 17
7 _SYSSMU7$ 580640768 0 228 ----回滚段并没有马上就回收,SHRINKS值为0,表示没有压缩
8 _SYSSMU8$ 1171456 1 0
9 _SYSSMU9$ 1171456 1 1
10 _SYSSMU10$ 1171456 1 1
SELECT t.SEGMENT_NAME,t.EXTENT_ID,t.STATUS
FROM Dba_Undo_Extents t WHERE t.segment_name='_SYSSMU7$' ORDER BY t.EXTENT_ID DESC;
_SYSSMU7$ 227 EXPIRED ---看到提交后,区的状态的变化,但是区的数量还没有变化
_SYSSMU7$ 226 EXPIRED
_SYSSMU7$ 225 EXPIRED
_SYSSMU7$ 224 EXPIRED
_SYSSMU7$ 223 EXPIRED
_SYSSMU7$ 222 EXPIRED
_SYSSMU7$ 221 EXPIRED
_SYSSMU7$ 220 EXPIRED
_SYSSMU7$ 219 EXPIRED
_SYSSMU7$ 218 EXPIRED
_SYSSMU7$ 217 EXPIRED
_SYSSMU7$ 216 EXPIRED
_SYSSMU7$ 215 EXPIRED
这里我其实还是搞不明白oracle回收回滚段的机制,有时候事务执行完毕后,再去看 v$rollstat和 Dba_Undo_Extents t会发现回滚段已经收缩,有时候很久都没有回收,搞不懂,要是哪位大虾看到小弟的苦恼后,麻烦指点一二,我现在只能看到这些表象。。。。。。