楼主: biti_rainy

关于回滚段使用的一点讨论

[复制链接]
论坛徽章:
0
41#
发表于 2002-4-26 14:30 | 只看该作者
当指针到达rollback segment尾部后,就会继续前进到rollback segment头部,因为它是个环。如果第一个extent 有活动事务,那么就会从尾部扩展一个extent.

使用道具 举报

回复
论坛徽章:
0
42#
发表于 2002-4-28 11:00 | 只看该作者
看来biti_rainy是对的。我也找到了依据:

    Growth of Rollback Segments
The pointer or the head of the rollback segment moves to the next extent when all
blocks of the current extent are used and a transaction needs another block for more
space. When the last extent is full, the pointer moves to the front of the first extent.
The pointer can only move to the next extent if that extent has no active transactions.
The pointer cannot skip over an extent. If the next extent is being used, the transaction
will allocate an additional extent for the rollback segment. This is called an extend.

感谢biti_rainy提供了这个讨论主题。纠正了我的错误理解。

使用道具 举报

回复
论坛徽章:
0
43#
发表于 2002-4-28 14:40 | 只看该作者
franking2000说的第一种情况恐怕值得商榷。
    我认为不管是新事务还是老事务,对一个回滚段只有一个pointer指向当前位置,当新事务可以写入时,应该从当前位置开始写,而不会查找整个回滚段。也没听说过按 LRU 分配 extent.

使用道具 举报

回复
论坛徽章:
0
44#
发表于 2002-4-26 11:15 | 只看该作者
我觉得情况1有可能会产生一些不必要的extent automatically extension,从而影响ORACLE的性能

使用道具 举报

回复
论坛徽章:
0
45#
发表于 2002-4-28 11:30 | 只看该作者
其实笨笨熊和biti_rainy说的都对,对于ROLLBACK的使用应分为两种情况:
       1、一个新TRANSACTION需要一个分配EXTENT时,SERVER会查找一个ROLLBACK SEGMENT中所有EXTENT,然后利用将一个LRU的EXTENT分配给它,如果未找到则EXTEND AUTOMATICALLY;
       2、对于一个已分配的TRANSACTION来说,如果它写满当前EXTENT,它必须使用下一个连续的EXTENT,如果下一个EXTENT是ACTIVE的,那么EXTEND就会发生。

使用道具 举报

回复
论坛徽章:
3
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-10-30 17:05:33会员2006贡献徽章
日期:2006-04-17 13:46:34
46#
发表于 2002-4-26 10:27 | 只看该作者
我个人感觉两种的确是都可能存在的。这也是为什么Oracle要使用那么多回滚段的原先
A不能用就用B。
如果真出现这种情况,就只能查找是那个会话占用此回退段,然后去提交或者回滚,
否则就六亲不认,Kill Session来解决问题。

使用道具 举报

回复
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
47#
发表于 2002-5-9 12:04 | 只看该作者

我的测试

测试结论:
对于一个正运行的事务,如果当前回滚段区间满了,它将寻找下一个(如果当前区间是回滚段形成的环的物理段尾,则下一个区间就是物理段头)。如果下一个区间可用,就使用该区间,否则,它就重新扩展分配一个新的区间。
对于一个新的事务,并不是
‘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.

使用道具 举报

回复
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
48#
发表于 2002-4-26 19:24 | 只看该作者

我的做法。

对到小的交易事务来说,我觉得ORACLE的机制是可以应付得来的,但如果要处理一些大事务的时候,回滚段就往往不能及时释放,对性能有一定的影响,所以我一般在处理完大事务后都把所用的回滚段shrink掉!

使用道具 举报

回复
论坛徽章:
4
授权会员
日期:2005-10-30 17:05:33ITPUB9周年纪念徽章
日期:2010-10-08 09:32:262011新春纪念徽章
日期:2011-01-04 10:35:172011新春纪念徽章
日期:2011-02-18 11:43:35
49#
发表于 2002-5-3 22:14 | 只看该作者
extent扩展只能在回滚段的头和尾之间进行吗?
我认为只要current extent已经没有空间,而下一个extent是active extent就会有扩展。

使用道具 举报

回复
论坛徽章:
4
授权会员
日期:2005-10-30 17:05:33ITPUB9周年纪念徽章
日期:2010-10-08 09:32:262011新春纪念徽章
日期:2011-01-04 10:35:172011新春纪念徽章
日期:2011-02-18 11:43:35
50#
发表于 2002-5-6 19:54 | 只看该作者
斑竹能否把这个讨论整理一下,以下期的杂志上发表?

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表