undo表空间手动管理

UNDO_MANAGEMENT specifies which undo space management mode the system should use. When set to AUTO, the instance starts in automatic undo management mode. In manual undo management mode, undo space is allocated externally as rollback segments.

Automatic Undo Management
自动重做管理
Oracle 服务器自动管理重做段的创建、分配、和调整
Manual Undo Management
手工管理重做
手工管理重做段的创建、分配、调整。这是Oracle9I之前的唯一方法
 
1、使用manual

 1)回滚段的分配和使用

    1>当事务产生的时候,数据库会给事务分配一个回滚段。当然我们可以指定事务使用某个回滚段。在我的测试用的数据库中,有如下回滚段

 

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

         9 RBS12

 

9 rows selected.

 

SQL>

如果我们要指定事务使用某个回滚段,如下

 

SQL>  set transaction use rollback segment rbs6;

 

Transaction set.

 

SQL>  insert into t select * from all_objects;

 

25649 rows created.

 

SQL> commit;

 

Commit complete.

       如果我们不人为的指定使用哪个回滚段,则数据库会根据回滚段中事务来权衡,以使得所有回滚段中事务压力尽可能平均。我们考虑存在非系统回滚段的情况(这 也是绝大多数系统的情况,除非因为DBA严重错误才会使得系统只存在系统回滚段),在这种情况下我们发出的事务不会去使用系统回滚段,这时系统回滚段只用 于系统级使用,比如create、drop、truncate等发生的时候的系统级的数据字典的回滚记录。数据库为我们发出的事务选择非系统回滚段,同一 个事务不能跨越回滚段,也就是说即使其他回滚段还很空闲,该大事务也只能使用被分配的回滚段即使该回滚段扩展。

接 下来我们来考究单个回滚段内的使用、扩展、回缩的问题。一个回滚段至少包含2个extent。每个回滚段有一个回滚段头,回滚段头是一个block,里面 主要记录了事务表信息。当产生一个事务的时候,就在回滚段头的事务表中记录一条信息,该信息中包含了事务标志、事务状态、使用的回滚段块数等等信息。我们 假定新创建的一个回滚段存在extent 1,2,3,4,5。当第一个事务分配到回滚段中的时候,除了事务表信息,该事务从extent 1的第二个block开始使用,该事务提交后陆续不断的事务到来并提交,假设我们已经使用到了extent 5的末尾。这时再来事务内容需要写入,则重新使用extent 1 的第二个block。这样循环使用回滚段空间。同理回滚段头的事务表也是如此循环使用。循环的次数,可以通过如下查询获得

SQL>  select usn,WRAPS from v$rollstat;

 

       USN      WRAPS

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

         0          0

         1         15

         2         15

         3         15

         4         15

         5         12

         6         15

         7         17

         9         12

       

9 rows selected.

 

SQL>

      那么我们会有一个问题,那就是既然回滚段是循环使用的,那为什么会扩展呢?注意在上面的例子中,所有的事务都是迅速提交了的。那我们现在假定这样一种情 况,存在一个事务,假设在extent 3 中有一个事务一直没有提交,然后回滚段一直循环使用到了extent 2。当extent 2使用完毕的时候发现extent 3中存在未提交事务,这是即使extent 4,5,1中的事务都已经提交,当前事务也不能越过extent 3而去使用后面的可使用的extent,这时该回滚段就扩展新的extent,假定为extent 2-1。在数据库中实际上回滚段的extent之间是通过指针连起来的一个单向循环的链表结构。扩展的时候相当于在链表中插入一个节点extent 2-1,但节点2-1的下一个extent依然是 extent 3,假如2-1使用完毕发现extent 3仍然存在未提交事务回滚段会继续扩展。

    我们做个例子,在SQLPLUS 1 中运行不提交(我们在v$rollstat 和 dba_rollback_segs中分别查询发现usn =5的回滚段对应了名字 rbs4)

 

SQL> select a.usn,b.segment_name from v$rollstat a,dba_rollback_segs b

  2  where a.usn = b.segment_id;

 

       USN SEGMENT_NAME

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

         0 SYSTEM

         1 RBS0

         2 RBS1

         3 RBS2

         4 RBS3

         5 RBS4

         6 RBS5

         7 RBS6

         9 RBS12

 

9 rows selected.

 

SQL>

SQL> select usn,rssize "rollback segment size" from v$rollstat where usn = 5;

 

USN     rollback segment size

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

5         4186112

 

SQL>  set transaction use rollback segment rbs4;

 

Transaction set.

 

SQL>  update t_small set object_id = 1;

 

100 rows updated.

 

打开SQLPLUS 2运行

begin

for i in 1..1000 loop

set transaction use rollback segment rbs4;

update t set object_id = i where rownum < 101;

commit;

end loop;

end;

SQL>  select usn,rssize "rollback segment size" from v$rollstat where usn = 5;

 

USN      rollback segment size

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

5          55042048

 

    现在我们来看在一个独立的session中运行下面的查询并对比查询前后的回滚段变化。

 

 

SQL> select  usn,rssize "rollback segment size" from v$rollstat where usn= 4;

 

USN     rollback segment size

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

4        4186112

 

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.

 

SQL>  select  usn,rssize "rollback segment size" from v$rollstat where usn= 4;

 

USN     rollback segment size

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

4         4186112

 

SQL>

 

     在这两个例子中我们很明显地看到了回滚段是否扩展的对比。那么,做完第二个例子后,我再回过头来查询原来扩展的比较大的回滚段,发现又变成4M了

 

SQL>  select  usn,rssize "rollback segment size" from v$rollstat where usn= 5;

 

       USN rollback segment size

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

         5               4186112

 

SQL>

      回滚段在扩展后,是要回缩的。假设回滚段当前extent n,使用完毕将准备使用extent n+1 的时候(extent n+1 无活动事务),如果设置了optimal并且回滚段大于 optimal设置的大小,检查extent n+2 中是否有未提交事务,如果没有,则回收extent n+2,本质上,就是在回滚段的链表上摘去extent n+2 ,然后继续检查extent n+3 决定是否回收,由此重复该动作。Optimal设置决定了回滚段最终回收后的大小,回滚段回缩后大小尽可能的接近optimal设置,如上面例子是4M, 可通过下面查询(shrinks表示回滚段回缩的次数,实际上v$rollstat提供了很多的回滚段信息,大家可以参考oracle document)

SQL> select  USN,OPTSIZE,SHRINKS  from  v$rollstat;

 

       USN    OPTSIZE    SHRINKS

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

         0                     0

         1    4194304          0

         2    4194304          0

         3    4194304          0

         4    4194304          0

         5    4194304         10

         6    4194304          0

         7    4194304          0

         9                     0

 

9 rows selected.

 

   2> 系统回滚段、非系统的回滚段与延迟回滚段

 SYSTEM  Undo Segment
SYSTEM 回滚段是创建在系统表空间中,主要是用于系统级的事务和分配普通事务于其他回滚段上。当手工创建数据库后需要创建普通回滚段之前必须首先创建系统回滚段。 按照oracle文档说明,当普通事务异常多的事情可能会出现使用系统回滚段的情况。但正常情况下,系统回滚段主要用于两个方面。一是系统事务,比如针对 数据字典的操作的truncate table 和 drop table 。如果truncate table or  drop table 的过程中没有成功,则系统会根据系统回滚段中的数据字典操作信息对该DDL操作进行回退。另一个方面,就是延迟回滚段(Deferred Rollback Segment)。延迟回滚段表示的是,当我们使一个表空间OFFLINE(exeample: alter tablespace users offline)之后,由于表空间不可用(不能进行读写),这个时候若有事务数据位于该表空间并且执行了回滚命令,回滚完成将显示给client,对于 client看起来该事务已经回滚,但是对于数据库来说该回滚并没有真正完成,这个时候数据库将该回滚信息写入系统回滚段(这就是延迟回滚段),等表空间 重新ONLINE的时候,数据库从系统回滚段中将回滚信息写入表空间。
Non-SYSTEM Undo Segments
非系统重做段
数据库拥有多个表空间时需要至少一个非系统的手工模式重做段或者自动模式的重做表空间
 

 2)回滚段的设置和管理

     事实上,对于作为个人意见来说,回滚段的管理本不应该是作为DBA的复杂的任务来对待的,因为回滚段的管理本来就可以使其很简单。几乎所有的系统出现回 滚段问题,不外乎都是回滚段大小不足、回滚段个数太少。9i以前的版本因为对于我们来说,无非也就是这两个问题。

关于回滚段表空间大小、回滚段数据文件的扩展、回滚段的扩展等创建时指定的参数问题,我想参考创建语法就足够了,没有必要在这上去纠缠max extents是100还是200,你会发现去考虑这些参数没有实质上的意义了。所有的一切设置,我只需要问几个问题就足够了:

1:系统并发事务数有多少?

2:系统是否存在大查询或者大是事务?频繁么?

3:能提供给系统的回滚段表空间的磁盘空间是多少?

 

    在初始化参数文件中存在参数transactions_per_rollback_segment和transactions,共同决定了实例启动的时候 将尝试联机的最大回滚段个数,transactions决定了同时存在的最大事务数。在这里顺便提及的2个初始化参数

max_rollback_segments   系统允许的最大回滚段个数

rollback_segments  该参数是一个参数列表,假如创建回滚段的时候是PUBLIC类型,则跟该参数无关,假如是PRIVATE类型的,则必须使得回滚段出现在该参数列表里面, 否则数据库启动之后这些回滚段不会自动联机(可手动)。在OPS/RAC中,PUBLIC类型的回滚段表示所有的INSTANCE都可以联机这些回滚段 (但同一时刻只能有一个实例联机),相当于是一个公共回滚段池。

在 实例启动的时候,实例尝试联机rollback_segments中设置的回滚段,直到达到个数为 min(CEIL(transactions/transactions_per_rollback_segment), max_rollback_segments)。若没有达到这个值,则实例尝试在PUBLIC类型的回滚段池中尝试联机回滚段,直到达到该值或者不再有回 滚段可联机。

当一个实例启动后其联机回滚段的个数是否足够,跟并发事务数有关,若每个回滚段上活动事务过多可能导致严重的回滚段争用。

这 里说了问题一相关内容,我们再看后面两个问题。由于回滚段的扩展和回收是昂贵代价的操作,通常我们是要避免的。如果存在大的查询,就算不会去写回滚段,但 是由于一致读,我们也可以参照前面内容,知道如果这期间事务繁忙回滚段被循环使用覆盖过,可能出现著名的ORA-01555错误。又由于事务产生的时候除 非人为指定使用哪个回滚段,否则事务使用哪个回滚段对于我们应用来说是透明的,同时我们能指定事务使用哪个回滚段但并不能阻止别的事务不使用某个回滚段, 这样我们就必须认识到,回滚段设置成大小不一致是不合适的,几乎是没有意义的,因为瓶颈总是决定于最小的一个回滚段(这类似于木桶原理,决定装水量的多少 是由最短的片所决定的)。所以我们应该统一回滚段的大小。那通常对于一个系统来说,几百M的磁盘空间甚至几G的磁盘空间根本不是问题,所以我们没有理由在 这里研究回滚段到底是使用4M大小还是10M大小,我们根据能提供的磁盘空间的估计,完全可以设置回滚段为50M/100M甚至更大的大小,这主要决定于 在大查询运行期间每个回滚段上可能的事务生成量,以及单个事务可能产生的回滚数据的大小。假如系统偶尔存在批量作业的时候可能使得某个回滚段扩展到1G, 但平常我们的回滚段大小在50M就不会出现回缩现象。那这个特定的时候如果数据库不繁忙只有大作业我们可以创建几个很大的回滚段,然后是其他回滚段 offline,等批作业完成然后再online其他回滚段,使大回滚段offline。当然可能的话也可以指定批作业使用大的回滚段。或者,我们可以为 所有回滚段设置optimal为50M,任其特定时刻扩展然后回缩(注意所有回滚段的optimal必须设置一样大小)。

 

    对于回滚段除了按照我们对系统状况估计进行创建、删除外,还有使回滚段联机和脱机,我们要注意的是如果回滚段处于联机并且里面有活动事务的时候,若想使回 滚段脱机(offline),则这时回滚段处于一种悬置的状态,也就是新的事务将不能使用该回滚段,而原有的事务继续存在,等待回滚段中所有事务完毕后, 回滚段成为脱机状态。

使用manual时,涉及使用的一初始化些参数:

【undo_namanement=manual;】

【rollback_segments=(segment_name[, segment_name]……)

ROLLBACK_SEGMENTS allocates one or more rollback segments by name to this instance. If you set this parameter, the instance acquires all of the rollback segments named in this parameter, even if the number of rollback segments exceeds the minimum number required by the instance (calculated as TRANSACTIONS / TRANSACTIONS_PER_ROLLBACK_SEGMENT).

You cannot change the value of this parameter dynamically, but you can change its value and then restart the instance. Although this parameter usually specifies private rollback segments, it can also specify public rollback segments if they are not already in use.

To find the name, segment ID number, and status of each rollback segment in the database, query the data dictionary view DBA_ROLLBACK_SEGS.

When UNDO_MANAGEMENT is set to AUTO, ROLLBACK_SEGMENTS is ignored.】

3)创建rollback segment

Creating a Rollback Segment: Example The following statement creates a rollback segment with default storage values in an appropriately configured tablespace:

CREATE TABLESPACE rbs_ts
   DATAFILE 'rbs01.dbf' SIZE 10M
   EXTENT MANAGEMENT LOCAL UNIFORM. SIZE 100K;

/* This example and the next will fail if your database is in 
   automatic undo mode.
*/
CREATE ROLLBACK SEGMENT rbs_one
   TABLESPACE rbs_ts;

The preceding statement is equivalent to the following:

CREATE ROLLBACK SEGMENT rbs_one
   TABLESPACE rbs_ts
   STORAGE
   ( INITIAL 10K
     NEXT 10K
     MAXEXTENTS UNLIMITED );

参考至:http://blog.itpub.net/27425054/viewspace-750216/

如有错误,欢迎指正

邮箱:[email protected]

猜你喜欢

转载自czmmiao.iteye.com/blog/2036665