【internal】undo内部机制

undo表空间管理方式

SQL> show parameter undo

 

NAME                     TYPE   VALUE

------------------------------------ -----------------------------------------

undo_management              string AUTO

undo_retention              integer    10800

undo_tablespace              string UNDOTBS1

 

关于undo_retention参数

在固定undo表空间大小的方式下,自动undo管理方式会根据一定算法动态调整这个参数,所以,大部分情况下会发现undo表空间使用率持续很高,通过如下语句查询所得结果

SELECTtotal.tablespace_name,

       Round(total.MB, 2) AS Total_MB,

       Round(total.MB - free.MB, 2) AS Used_MB,

       Round((1 - free.MB / total.MB) * 100, 2) || '%' AS Used_Pct

  FROM (SELECT tablespace_name, Sum(bytes) / 1024 / 1024 AS MB

          FROM dba_free_space

         GROUP BYtablespace_name) free,

       (SELECTtablespace_name, Sum(bytes) / 1024 / 1024 AS MB

          FROM dba_data_files

         GROUP BYtablespace_name) total

 WHERE free.tablespace_name =total.tablespace_name;

    

         以通过设置_undo_autotune=FALSE显示的关闭Automatic UNDO Retention功能。

         或者通过开启undo表空间的自动扩展并设置扩展的最大值的方式也可以缓解使用率过高的问题。

 

  自动undo表空间管理方式及内部实现。

        自动管理空间方式是指oracle自动控制undo segment的创建、删除和分配操作。

         初始化时候创建的undosegment个数跟undo 表空间的大小有关,若表空间大于一定值,则初始化分配10个segment。

        select * fromdba_rollback_segs

 

     一般情况下,oracle倾向于让每个事务独占一个undo segment。比如初始化库中有超过11个事务,则oracle会创建11个undosegment。可以通过v$transaction中的XIDUSN字段对应dba_rollback_segs中的segment_id找出其对应关系。

 

     在undo空间已经不够的情况下,oracle才允许多个transaction使用同一个segment。对于多个transaction使用同一个segment的情况下,其对segment的使用规则如下:

 如下一个undo segment中包含了3个extent。

 

Extent 1

Extent 2

Extent 3

6

6

6

7

  4

4

5

5

5

 

每个extent中的block有一个序列号(seq)用来标识版本顺序,同一个extend的所有block的seq是相同的。

选择第一个可用块的时候,寻找seq号最大的区间里第一个小于当前seq号的块。如上图中的标黄块。

 

1、循环使用

  

     跟online redo log file的机制一样,3用完之后继续用1。

 每次区间的切换叫做WRAP,对应v$rollstat中的WRAP值+1.

2、若在区间WRAP过程中,后置的区间中存在不可覆盖块(块中事务未提交或者提交后块的保留时间没有达到undo_retention阈值),

此时回滚段需要扩展。

3、扩展首先寻找表空间中未free的区(属于该undo表空间,但没有分配给任何undo segmnet),若找到,则插入到不可覆盖区前面。

4、若找不到free的区,则开始steal其他undosegment可以被偷的区。此时(无论是否成功)v$undostat中的EXPSTEALCNT值+1.

其他segment可以被偷的区是指在含当前使用区间后面的,可以被覆盖的区间。

若偷窃成功,则v$undostat中的EXPBLKRELCNT字段+偷到的块数。

5、若偷窃不到可用块,则需要检查undo表空间是否可扩展,若可扩展,此时会扩展undo对应的datafile,从而分配新区间。

6、若表空间不可扩展,则需要检查guarantee参数,若guarantee参数设置为noguarantee。则寻找该类extent进行覆盖。

7、不论通过什么方式,若区间扩展成功,则v$rollstat中的extend列+1.

8、若各种渠道都走不通,则报错。

 

 

猜你喜欢

转载自blog.csdn.net/wang1016612067/article/details/78766324