关闭

Oracle学习笔记之undo表空间管理

标签: oracle
252人阅读 评论(0) 收藏 举报
分类:

一、undo说明

undo表空间对Oracle来说,它保存的数据的前镜像,即修改之前的内容。它是非常重要的一个表空间。

undo的作用:

(1)rollback

(2)recover

(3)一致性读

(4)Flashback

二、Undo表空间的两种管理方式

Oracle的UNDO有两种方式:一是使用undo表空间,二是使用回滚段。

我们通过undo_management参数来控制使用哪种方式,如果设置为auto,就是使用undo表空间,这时必须要指定一个undo表空间。如果设为manual,系统启动后使用rollback segment方式存储undo信息。

SQL> show parameter undo;
NAME                                 TYPE        VALUE
--------------------------------- ----------- ------------------------------
undo_management            string      AUTO
undo_retention                    integer     900
undo_tablespace                 string      UNDOTBS1

如果系统没有指定undo_management,那么系统默认以manual方式启动,即使设置了auto方式的参数,这些参数也将被忽略。

当实例启动的时候,系统自动选择一个有效的undo表空间或者是rollback segment,如果没有有效的可用的undo表空间或者回滚段,系统使用system rollback segment。这是系统不推荐的。

1、当使用rollback segment时

当undo_management被设置成menual时使用系统回滚段,即将undo records记录到system表空间下的system段。

SQL> col segment_name format a10
SQL> select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='ROLLBACK';
SEGMENT_NA TABLESPACE_NAME                     BYTES NEXT_EXTENT
---------- ------------------------------ ---------- -----------
SYSTEM     SYSTEM                             393216       57344

通过上面的这条语句,我们可以查到这个用户rollback的system segment存在于system表空间。默认情况下,只有一个segment,并且它还比较小,所以,如果使用system段来存储undo records。肯定会影响数据库的性能。所以Oracle是建议使用undo tablespace 来管理undo records。

2、使用undo表空间

当undo_management设置成AUTO时使用undo tablespace来管理回滚段。这个时候,我们将有很多个undo segment,并且这些segment是存放在undo表空间里的。

SQL> select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='TYPE2 UNDO';
SEGMENT_NAME                   TABLESPACE_NAME                     BYTES NEXT_EXTENT
------------------------------ ------------------------------ ---------- -----------
_SYSSMU1_3724004606$           UNDOTBS1                          2228224       65536
_SYSSMU2_2996391332$           UNDOTBS1                          8519680       65536
_SYSSMU3_1723003836$           UNDOTBS1                          1179648       65536
_SYSSMU4_1254879796$           UNDOTBS1                          2228224       65536
_SYSSMU5_898567397$            UNDOTBS1                          8519680       65536
_SYSSMU6_1263032392$           UNDOTBS1                          1179648       65536
_SYSSMU7_2070203016$           UNDOTBS1                          8519680       65536
_SYSSMU8_517538920$            UNDOTBS1                          8519680       65536
_SYSSMU9_1650507775$           UNDOTBS1                          2228224       65536
_SYSSMU10_1197734989$          UNDOTBS1                          1179648       65536
10 rows selected

通过以上SQL的查询结果,我们可以看出,有10个undo segment来存放undorecords。

也可以通过查看v$rollstat和v$rollname两个视图来查看信息。这2个视图会显示所有rollback段的信息。包括system段和undo段。

SQL> select s.usn,n.name,s.extents,s.hwmsize,s.status from v$rollname n,v$rollstat s where s.USN=n.usn;
       USN NAME                              EXTENTS    HWMSIZE STATUS
---------- ------------------------------ ---------- ---------- ---------------
         0 SYSTEM                                  6     385024 ONLINE
         1 _SYSSMU1_3724004606$                    4  396812288 ONLINE
         2 _SYSSMU2_2996391332$                    3   75882496 ONLINE
         3 _SYSSMU3_1723003836$                    3   19128320 ONLINE
         4 _SYSSMU4_1254879796$                    4   35774464 ONLINE
         5 _SYSSMU5_898567397$                     3  175235072 ONLINE
         6 _SYSSMU6_1263032392$                    3   16900096 ONLINE
         7 _SYSSMU7_2070203016$                    3   76668928 ONLINE
         8 _SYSSMU8_517538920$                     3  339533824 ONLINE
         9 _SYSSMU9_1650507775$                    4   10608640 ONLINE
        10 _SYSSMU10_1197734989$                   3   51503104 ONLINE
11 rows selected

3、undo_retention和retention guarantee参数

统计undo表空间的空闲和非空闲比例:

SQL> select tablespace_name,status,SUM(bytes)/1024/1024 "Bytes(M)" from dba_undo_extents group by tablespace_name,status;
TABLESPACE_NAME                STATUS      Bytes(M)
------------------------------ --------- ----------
UNDOTBS1                       UNEXPIRED    38.0625
UNDOTBS1                       EXPIRED       4.1875

我们看到查询的结果,unexpected和expired是已使用的undo表空间,其中expired说明是已经过期的数据,也就是15分钟(默认情况)以外的数据,以被覆盖,可以认为是空闲的。

这里就关系到一个参数:undo_retention,该参数用来指定undo记录保存的最长事件,一秒为单位,是个动态参数,完全可以再实例运行时随时修改,通常默认是900秒,也就是15分钟。

undo_retention只是指定undo数据的过期时间,并不是说,undo中的数据一定会在undo表空间中保存15分钟,比如说刚一个新事物开始的时候,如果undo表空间已经被写满,则新事务的数据就会自动覆盖已提交的数据,而不管这些数据是否已经过期,因此,再创建undo表空间的时候一定要有足够的空间。

undo_retention中指定的时间一过,以提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被flashback特性引用。如果undo表空间足够大,而数据库又不是特别繁忙,那么其实undo_retention参数的值并不会影响到你,哪怕你设置成1,只要没有事务去覆盖undo数据,它就会持续有效。总之,要注意undo表空间的大小,保证有足够的空间。

只有在一种情况下,undo表空间能确保undo中的数据在undo_retention指定时间过期前一定有效,就是为undo表空间指定Retention Guarantee,指定之后,oracle对于undo表空间中未过期的undo数据不会覆盖,例如:

SQL> alter tablespace undotbs1 retention guarantee;
表空间已更改。
禁止undo表空间retention guarantee.
SQL> alter tablespace undotbs1 retention noguarantee;
表空间已更改。

undo表空间是会被重用的,只有当事务没有结束,或者开了retention guarantee,或在undo_retention时间内不能被重用。

在undo_retention规定的时间内,数据都是有效的,过期后都会设为无效,状态被改为expired,这些回滚段将会被看做Free Space。但是只要数据没有被覆盖就可以使用。如果空间已满,新事务的数据会自动覆盖掉已经提交的事务数据,即使在undo_retention的时间内。除非指定Retention Guarantee模式,才能保证在undo_retention内不被覆盖。

4、undo表空间满时的处理方法

默认情况下的Undo_retention只有15分钟,这个默认值,一般都无法满足系统的要求,一般建议改成3个小时。

SQL> alter system set undo_retention=10800;

undo_retention设置的越大,所需要的undo tablespace也就越大。

4.1、先模拟UNDO表空间满的情况

SQL> create undo tablespace undotbs2 datafile '/u01/app/oracle/oradata/orcl/undotbs02.dbf' size 1M;

Tablespace created.

SQL> alter tablespace undotbs2 retention guarantee;

Tablespace altered.

SQL> alter system set undo_tablespace=undotbs2;

System altered.

SQL> create table dba(id number);

Table created.

SQL> begin
  2  for i in 1 .. 100000 loop
  3  insert into dba values(i);
  4  commit;
  5  end loop;
  6  end;
  7  /
begin
*
ERROR at line 1:
ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS2'
ORA-06512: at line 3

4.2处理方法

1)增加undo表空间的数据文件

2)切换undo tablespace,这种情况下多用在undo表空间已经非常大的情况。

1)增加数据文件

SQL> alter tablespace undotbs2 add datafile '/u01/app/oracle/oradata/orcl/undotbs02a.dbf' size 100M reuse;


Tablespace altered.


SQL> begin
  2  for i in 1 .. 100000 loop
  3  insert into dba values(i);
  4  commit;
  5  end loop;
  6  end;
  7  /

PL/SQL procedure successfully completed.

2)切换UNDO表空间

1、建立新的表空间undotbs3

SQL> create undo tablespace undotbs3 datafile '/u01/app/oracle/oradata/orcl/undotbs03a.dbf' size 100M reuse;

Tablespace created.

2、切换到新建的undo表空间

SQL> alter system set undo_tablespace=undotbs3 scope=both;

3、将原来的undo表空间脱机

SQL> alter tablespace undotbs2 offline;

4、删除原来的undo表空间:

SQL> drop tablespace undotbs2 including contents and datafiles cascade constraints;

如果只是drop tablespace undo,则只会在删除控制文件中的记录,并不会删除物理文件。

Drop undo表空间时必须在未使用的情况下才能进行,如果undo表空间爱你正在使用,那么drop表空间命令将失败,在drop表空间的时候可以使用including contents。

4.3、undo表空间损坏的处理方法

出现undo损坏的情况,大都是因为异常宕机,在启动的时候报错,DB不能启动。

比如:ORA-00600:internal error code,arguments:[4194]

当alert log中出现ORA-600+[4194]时,基本就可以断定,是undo表空间出现了损坏。对于undo表空间的损坏,能备份恢复最好,不能的话建议使用如下方法

方法一:使用system segment

当我们使用undo表空间出现损坏时,可以先用system segmet启动DB,启动之后,在重新创建undo表空间,再用undo启动,步骤如下:

(1)用spfile创建spfile,然后修改参数:

#*.undo_tablespace='UNDOTBS3'
undo_management='MANUAL'
rollback_segments='SYSTEM'

(2)用修改后的pfile,重启DB

SQL> startup pfile='/u01/app/oracle/product/11.2.0/db_1/dbs/initPROD.ora'

SQL> show parameter undo;


NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management     stringMANUAL
undo_retention     integer10800
undo_tablespace     string

(3)删除原来的表空间,创建新的undo表空间

SQL> drop tablespace undotbs3;

SQL> create undo tablespace undotbs03 datafile '/u01/app/oracle/oradata/orcl/undotbs03b.dbf' size 10M;

(4)关闭数据库,修改pfile参数,然后用心的pfile创建spfile,在正常启动数据库。

*.undo_retention=10800
*.undo_tablespace='UNDOTBS03'

方法二、跳过损坏的segment

通过alter log来查看正在使用的哪些segment,这些段有可能损坏。我们需要把这些损坏的segment跳过,先正常启动DB,在创建新的undo表空间,在切换一下。

(1)修改pfile,添加参数:

*._corrupted_rollback_segments='_SYSSMU11$','_SYSMU12$','_SYSSMU13$'

这些字段的值,我们可以通过alert log查看。 

#strings system01.dbf | grep _SYSSMU | cut -d $ -f l | sort -u

(2)用修改之后的pfile启动DB

因为跳过了那些损坏的segment,所以DB可以正常启动。

(3)创建新的UNDO表空间,并切换过来

SQL>create undo tablespace undotbs1 datafile '/u01/app/oracle/oradata/orcl/undotbs1.dbf' size 10M;

SQL>alter system set undo_tablespace=undotbs1;

SQL>drop tablespace undotbs;

(4)修改pfile,创建spfile,并正常启动

删除:

*._corrupted_rollback_segments='_SYSSMU11$','_SYSMU12$','_SYSSMU13$'

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:32707次
    • 积分:814
    • 等级:
    • 排名:千里之外
    • 原创:44篇
    • 转载:46篇
    • 译文:0篇
    • 评论:0条
    文章分类