auto undo management是oracle推出代替manual rollback segment,oracle官方的文档上有介绍AUM的原理和实现方法,今天我们不再重复这些内容,我们来深入一些官方文档中点到为止的东西。
undo tablespace size
当创建undo tablespace时最少包含一个初始segment,最多包含十个初始segment,每个初始segment包括2个extent,在9i中的话第一个extent被保留了一个块,只有7个block可用,10g的话8个块都可以用。
SQL 9I>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1 from dba_undo_extents where SEGMENT_NAME=’_SYSSMU1$’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU1$ 7 56 EXPIRED 10 16
_SYSSMU1$ 8 64 EXPIRED 17 24
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1 from dba_undo_extents where SEGMENT_NAME=’_SYSSMU1$’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU1$ 8 64 EXPIRED 9 16
_SYSSMU1$ 8 64 EXPIRED 249 256
undo space reuse
每个undo extent可以有三种状态:
active:有活动事务在此extent上
expired:已结束的事务,undo 信息超过undo_retention时间限制
unexpired:已经结束的事务,undo 信息未达到undo_retention时间限制
当一个事务开始它将会去寻找可用的undo block来存放undo信息,它将按照以下顺序请求undo space.
1.先去搜索拥有非active extent的undo segment,如果没有发现,那么会去创建新的undo segment,如果空间不够不能创建,将返回错误。过程如下
session 1:
SQL 10G>update testundo set owner=’wanghai’ where rownum<2;
1 row updated.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU31$ 8 64 UNEXPIRED 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
session 2:
SQL 10G>update test1 set object_id=object_id where rownum<2;
1 row updated.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU31$ 8 64 ACTIVE 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
session 3:
SQL 10G>update test01 set id=id where rownum<2;
update test01 set id=id where rownum<2
*
ERROR at line 1:
ORA-01552: cannot use system rollback segment for non-system tablespace ‘USERS’
扩展数据文件:
SQL 10G>alter database datafile ‘/opt/oracle/oradata/dbtest/undo03f.dbf’ resize 320k;
Database altered.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU32$ 8 64 EXPIRED 25 32
_SYSSMU32$ 8 64 EXPIRED 33 40
_SYSSMU31$ 8 64 ACTIVE 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
SQL 10G>update test01 set id=id where rownum<2;
1 row updated.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU32$ 8 64 ACTIVE 25 32
_SYSSMU32$ 8 64 EXPIRED 33 40
_SYSSMU31$ 8 64 ACTIVE 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
2.如果有一个undo segment被选中,但是其中free的undo block并不足以存储该事务的undo 信息,那么它将尝试创建extent,如果没有空间,那么将会进入下一步。
3.如果创建新extent失败,它将会搜索其他undo segment中expired extent并重用。
4.如果其他undo segment中没有expired extent可使用,那么它会继续搜索其他undo segment中unexpired extent并重用。
5.如果经过以上尝试还没有可用空间,将会返回错误。
SQL 10G>update testundo set owner=’wanghai’;
501 rows updated.
SQL 10G>
select UNDOTSN,UNDOBLKS,UNXPSTEALCNT,UNXPBLKRELCNT,UNXPBLKREUCNT,
EXPSTEALCNT,EXPBLKRELCNT,EXPBLKREUCNT,ACTIVEBLKS,UNEXPIREDBLKS,EXPIREDBLKS,
TUNED_UNDORETENTION from V$UNDOSTAT where rownum<2;
UNDOTSN UNDOBLKS UNXPSTEALCNT UNXPBLKRELCNT UNXPBLKREUCNT EXPSTEALCNT EXPBLKRELCNT EXPBLKREUCNT ACTIVEBLKS UNEXPIREDBLKS EXPIREDBLKS TUNED_UNDORETENTION
———- ———- ———— ————- ————- ———– ———— ———— ———- ————- ———– ——————-
10 22 9 0 15 9 0 0 32 0 0 24
出现了steal,也就是reuse了unexpired extent
EXPSTEALCNT:尝试请求expired extent的次数
EXPBLKREUCNT:实际使用expired block数
UNXPSTEALCNT:尝试请求unexpired extent的次数
UNXPBLKREUCNT:实际使用unexpired block数
如果没有expired or unexpired extent可以steal,那么将会
SQL 10G>update testundo set owner=’wanghai’;
update testundo set owner=’wanghai’
*
ERROR at line 1:
ORA-30036: unable to extend segment by 8 in undo tablespace ‘UNDO_THREE’
从上面这些实验中我们也可以看出9i的undo_retention并不保证undo block一直会被保持到retention过期,不过10g已经提供了这种保证。
SQL 10G>create undo tablespace UNDO_FOUR
2 datafile ‘/opt/oracle/oradata/dbtest/undo04.dbf’ size 320K reuse RETENTION GUARANTEE;
Tablespace created.
注:以上实验blocksize全为8k
undo tablespace size
当创建undo tablespace时最少包含一个初始segment,最多包含十个初始segment,每个初始segment包括2个extent,在9i中的话第一个extent被保留了一个块,只有7个block可用,10g的话8个块都可以用。
SQL 9I>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1 from dba_undo_extents where SEGMENT_NAME=’_SYSSMU1$’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU1$ 7 56 EXPIRED 10 16
_SYSSMU1$ 8 64 EXPIRED 17 24
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1 from dba_undo_extents where SEGMENT_NAME=’_SYSSMU1$’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU1$ 8 64 EXPIRED 9 16
_SYSSMU1$ 8 64 EXPIRED 249 256
undo space reuse
每个undo extent可以有三种状态:
active:有活动事务在此extent上
expired:已结束的事务,undo 信息超过undo_retention时间限制
unexpired:已经结束的事务,undo 信息未达到undo_retention时间限制
当一个事务开始它将会去寻找可用的undo block来存放undo信息,它将按照以下顺序请求undo space.
1.先去搜索拥有非active extent的undo segment,如果没有发现,那么会去创建新的undo segment,如果空间不够不能创建,将返回错误。过程如下
session 1:
SQL 10G>update testundo set owner=’wanghai’ where rownum<2;
1 row updated.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU31$ 8 64 UNEXPIRED 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
session 2:
SQL 10G>update test1 set object_id=object_id where rownum<2;
1 row updated.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU31$ 8 64 ACTIVE 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
session 3:
SQL 10G>update test01 set id=id where rownum<2;
update test01 set id=id where rownum<2
*
ERROR at line 1:
ORA-01552: cannot use system rollback segment for non-system tablespace ‘USERS’
扩展数据文件:
SQL 10G>alter database datafile ‘/opt/oracle/oradata/dbtest/undo03f.dbf’ resize 320k;
Database altered.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU32$ 8 64 EXPIRED 25 32
_SYSSMU32$ 8 64 EXPIRED 33 40
_SYSSMU31$ 8 64 ACTIVE 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
SQL 10G>update test01 set id=id where rownum<2;
1 row updated.
SQL 10G>select segment_name, blocks, bytes/1024, status,BLOCK_ID,BLOCK_ID+blocks-1
2 from dba_undo_extents
3 where tablespace_name = ‘UNDO_THREE’;
SEGMENT_NAME BLOCKS BYTES/1024 STATUS BLOCK_ID BLOCK_ID+BLOCKS-1
—————————— ———- ———- ——— ———- —————–
_SYSSMU32$ 8 64 ACTIVE 25 32
_SYSSMU32$ 8 64 EXPIRED 33 40
_SYSSMU31$ 8 64 ACTIVE 9 16
_SYSSMU31$ 8 64 ACTIVE 17 24
2.如果有一个undo segment被选中,但是其中free的undo block并不足以存储该事务的undo 信息,那么它将尝试创建extent,如果没有空间,那么将会进入下一步。
3.如果创建新extent失败,它将会搜索其他undo segment中expired extent并重用。
4.如果其他undo segment中没有expired extent可使用,那么它会继续搜索其他undo segment中unexpired extent并重用。
5.如果经过以上尝试还没有可用空间,将会返回错误。
SQL 10G>update testundo set owner=’wanghai’;
501 rows updated.
SQL 10G>
select UNDOTSN,UNDOBLKS,UNXPSTEALCNT,UNXPBLKRELCNT,UNXPBLKREUCNT,
EXPSTEALCNT,EXPBLKRELCNT,EXPBLKREUCNT,ACTIVEBLKS,UNEXPIREDBLKS,EXPIREDBLKS,
TUNED_UNDORETENTION from V$UNDOSTAT where rownum<2;
UNDOTSN UNDOBLKS UNXPSTEALCNT UNXPBLKRELCNT UNXPBLKREUCNT EXPSTEALCNT EXPBLKRELCNT EXPBLKREUCNT ACTIVEBLKS UNEXPIREDBLKS EXPIREDBLKS TUNED_UNDORETENTION
———- ———- ———— ————- ————- ———– ———— ———— ———- ————- ———– ——————-
10 22 9 0 15 9 0 0 32 0 0 24
出现了steal,也就是reuse了unexpired extent
EXPSTEALCNT:尝试请求expired extent的次数
EXPBLKREUCNT:实际使用expired block数
UNXPSTEALCNT:尝试请求unexpired extent的次数
UNXPBLKREUCNT:实际使用unexpired block数
如果没有expired or unexpired extent可以steal,那么将会
SQL 10G>update testundo set owner=’wanghai’;
update testundo set owner=’wanghai’
*
ERROR at line 1:
ORA-30036: unable to extend segment by 8 in undo tablespace ‘UNDO_THREE’
从上面这些实验中我们也可以看出9i的undo_retention并不保证undo block一直会被保持到retention过期,不过10g已经提供了这种保证。
SQL 10G>create undo tablespace UNDO_FOUR
2 datafile ‘/opt/oracle/oradata/dbtest/undo04.dbf’ size 320K reuse RETENTION GUARANTEE;
Tablespace created.
注:以上实验blocksize全为8k