SQL> conn internal
Connected.
---回滚段usn,回滚段头class为11+2n,回滚段块class为12+2n,---
SQL> select class,count(*) from x$bh where class>10 group by class;
CLASS COUNT(*)
---------- ----------
11 1
12 2
13 1
14 14
15 1
16 1
17 1
18 1
19 1
20 1
21 1
CLASS COUNT(*)
---------- ----------
22 1
23 1
24 3
25 1
26 1
16 rows selected.
SQL> select segment_id,segment_name from dba_rollback_segs;
SEGMENT_ID SEGMENT_NAME
---------- ------------------------------
0 SYSTEM
1 RBS0
2 RBS1
3 RBS2
4 RBS3
5 RBS4
6 RBS5
7 RBS6
8 rows selected.
---指定这个transaction使用rollback segment rbs3---
SQL> set transaction use rollback segment rbs3;
Transaction set.
---打开一个游标,但是暂不获取数据---
SQL> variable x refcursor
SQL> begin
2 open :x for select * from t where rownum=1;
3 end;
4 /
PL/SQL procedure successfully completed.
---update游标中查询的第一条记录,并且commit---
SQL> update t set object_id=1 where OBJECT_ID=7781;
1 row updated.
SQL> commit;
Commit complete.
---同样指定使用rollback segment rbs3,进行大量的update操作,
使得上面update操作在回滚段中的前影被覆盖(因为回滚段是循环使用的)。---
SQL> begin
2 for i in 1..1000 loop
3 set transaction use rollback segment rbs3;
4 update t set object_id=i where rownum<101;
5 commit;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
---此时输出游标的输出结果。yeah,ORA-01555!从来没有因为报错这么高兴过---
SQL> print x
ERROR:
ORA-01555: snapshot too old: rollback segment number 4 with name "RBS3" too
small
no rows selected
SQL> select class,count(*) from x$bh where class>10 group by class;
CLASS COUNT(*)
---------- ----------
11 1
12 2
13 1
14 14
15 1
16 1
17 1
18 1
19 2
20 511 -- RBS3使用的块
21 1
CLASS COUNT(*)
---------- ----------
22 1
23 1
24 3
25 1
26 1
16 rows selected.
SQL>
9i 中回滚端的改进是引入了UNDO_RETENTION 参数,用来限定回滚段中数据在多长时间内不得被覆盖,以避免1555。
所以这个参数通常取决于系统中运行的大查询的时间。
参考:一致读( consistent read )的步骤
http://blog.itpub.net/post/26/2507
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30075367/viewspace-1446112/ ,如需转载,请注明出处,否则将追究法律责任。