|
我的测试
测试结论:
对于一个正运行的事务,如果当前回滚段区间满了,它将寻找下一个(如果当前区间是回滚段形成的环的物理段尾,则下一个区间就是物理段头)。如果下一个区间可用,就使用该区间,否则,它就重新扩展分配一个新的区间。
对于一个新的事务,并不是
‘For a new transaction, it will search from the first one to the last one.
If an avaliable extent is found, it will use it.
If not found, it will extend a new one. ’
而是和一个正运行的事务一样,从当前的extent开始,寻找下一个区间。如果下一个区间可用,就使用该区间,否则,它就重新扩展分配一个新的区间。
准备环境
========
SQLWKS> select segment_name, status from dba_rollback_segs;
SEGMENT_NAME STATUS
------------------------------ ----------------
SYSTEM ONLINE
R01 ONLINE
R02 OFFLINE
R03 OFFLINE
R04 OFFLINE
5 rows selected.
SQLWKS> create table t1
2> ( no number(1),
3> txt char(1000)
4> ) tablespace cm_space;
Statement processed.
SQLWKS> BEGIN
2> FOR i IN 1..1000 LOOP
3> INSERT INTO t1 VALUES (1, 'abcde');
4> END LOOP;
5> END;
Statement processed.
SQLWKS> BEGIN
2> FOR i IN 1..1000 LOOP
3> INSERT INTO t1 VALUES (2, 'abcde');
4> END LOOP;
5> END;
Statement processed.
SQLWKS> COMMIT;
Statement processed.
第一个事务
==========
--rollstat.extents: 回滚段中extent总数。
--rollstat.curext : 回滚段中当前extent号。从0开始。
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 24 0
2 rows selected.
SQLWKS> commit;
Statement processed.
SQLWKS> update t1 set txt = 'XYZ' where no = 1;
1000 rows processed.
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 24 15
2 rows selected.
此时,在另一个事务中执行一个操作,不提交,看回滚段的阻塞情况。
insert into t1 values (3, 'zzz');
以下回到本事务:
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 24 15
2 rows selected.
SQLWKS> update t1 set txt = 'XYZ' where no = 2;
1000 rows processed.
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 32 31
2 rows selected.
--查看各事务在回滚段中的起始extent号。
--第二行是本事务。第一行是刚才执行的起阻塞作用的事务。
SQLWKS> SELECT s.sid, s.serial#, t.start_time, t.xidusn, t.start_uext, s.username
2> FROM V$session s, V$transaction t, V$rollstat r
3> WHERE s.saddr=t.ses_addr
4> AND t.xidusn=r.usn
SID SERIAL# START_TIME XIDUSN START_UEXT USERNAME
---------- ---------- -------------------- ---------- ---------- ------------------------------
12 1 05/09/02 11:01:49 2 15 SYS
13 8 05/09/02 11:00:33 2 0 SYS
2 rows selected.
SQLWKS> commit;
Statement processed.
第三个事务
==========
SQLWKS> commit;
Statement processed.
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
4>
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 32 31
2 rows selected.
SQLWKS> update t1 set txt = 'aaa' where no = 2;
1000 rows processed.
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 32 14
2 rows selected.
SQLWKS> update t1 set txt = 'aaa' where no = 1;
1000 rows processed.
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 48 30
2 rows selected.
--可以看到,起阻塞作用的事务的起始extent号被向后推动了。说明在它之前发生了extend。
SQLWKS> SELECT s.sid, s.serial#, t.start_time, t.xidusn, t.start_uext, s.username
2> FROM V$session s, V$transaction t, V$rollstat r
3> WHERE s.saddr=t.ses_addr
4> AND t.xidusn=r.usn
SID SERIAL# START_TIME XIDUSN START_UEXT USERNAME
---------- ---------- -------------------- ---------- ---------- ------------------------------
12 1 05/09/02 11:01:49 2 31 SYS
13 8 05/09/02 11:06:11 2 47 SYS
2 rows selected.
SQLWKS> commit;
Statement processed.
第四个事务
==========
SQLWKS> commit;
Statement processed.
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
4>
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 48 30
2 rows selected.
SQLWKS> update t1 set txt = 'bbb' where no = 1;
1000 rows processed.
--可以看到,起阻塞作用的事务的起始extent号又被向后推动了。
--说明新开始的事务会继续extend回滚段,而不是先寻找空闲的回滚段extent。
SQLWKS> SELECT a.segment_name, b.extents, b.curext
2> FROM dba_rollback_segs a, v$rollstat b
3> WHERE a.segment_id = b.usn
4>
SEGMENT_NAME EXTENTS CUREXT
------------------------------ ---------- ----------
SYSTEM 8 4
R01 63 45
2 rows selected.
使用这句来查看阻塞的事务
========================
SQLWKS> SELECT s.sid, s.serial#, t.start_time, t.xidusn,s.username
2> FROM V$session s, V$transaction t, V$rollstat r
3> WHERE s.saddr=t.ses_addr
4> AND t.xidusn=r.usn
5> AND ((r.curext=t.start_uext-1) OR
6> ((r.curext=r.extents-1) AND t.start_uext=0));
SID SERIAL# START_TIME XIDUSN USERNAME
---------- ---------- -------------------- ---------- ------------------------------
12 1 05/09/02 11:01:49 2 SYS
1 row selected. |
|