ORA-08176 错误

http://blog.itpub.net/17203031/viewspace-774498/


OracleUndo机制中,参数Undo_Retention扮演了“混淆者”的角色。论坛里面也有很多朋友对这个参数含义不是非常清楚。本篇我们就来讨论一下这个这个参数的含义和作用。

 

1、从Undo说起

 

Undo或者说rollback segment机制是Oracle早期奠定行业地位的核心技术之一。Undo机制的提出,源自于Oracle提出的“多版本一致读”特性。在Oracle中,select操作不会阻塞任何操作,也不会被任何操作所阻塞。

 

这就意味着,当我们对一个数据表进行DML操作,比如插入、修改和删除数据的时候,其他会话连接的select操作是可以随意进行的,而且访问的数据都是DML操作之前提交的数据。

 

Oracle数据是保存在“表空间、段对象、分区和数据块”的组织结构体系中。对数据的修改就是在数据块中直接的修改。如果需要同时支持对之前数据的访问,比如在系统中有一个地方需要保存数据的“前镜像pre-image,同时一旦DML进行回滚rollback动作,恢复数据也需要这部分前镜像内容。这就衍生出了rollback segement和之后的Undo表空间。

 

那么,是不是当一个事务Transaction结束commit之后,Undo前镜像就没有用途了呢?我们说不是的。commit之后的undo段数据镜像至少要支持两种操作,其一是一致读(consistent read),另一个是利用undo数据的flash back闪回技术。

 

严格的说,多版本一致读是两个Oracle特性。一致读所说的是:当一个查询读操作select数据的时候,只能读取到小于等于启动查询操作时候SCN的数据。比如:我们启动查询的时候,数据表A中包括10亿条数据,。之后另一个会话启动删除了1亿条数据并且提交。提交之后,第一个读会话才检索到原来1亿条数据的位置,并且最后结束。从结果看,第一个会话读取到的是10亿条数据。

 

一致读特性的关键就在于保证了读操作的一致性,读取数据在时间层面的一致性。细想一下,第二个会话commit之后,源数据1亿条的前镜像在Undo空间中是失效Expired状态。一致读过程中,一定是进行过失效Undo镜像数据的读取。

 

失效Undo数据的最终归宿是被覆盖重用。想想一种情况,如果系统中Undo管理比较不合理,事务Undo数据量比较大而且频繁,有失效的Undo前镜像被覆盖之后,恰恰有一个长时间查询需要访问这个前镜像。这个时候,Oracle就只能说“抱歉”了,这也就是经典的ora-1555 snapshot too old的起源。

 

Undo失效数据的另一种用途就是Flashback闪回。Flashback QueryFlashback Archive都是建立在对前镜像数据再利用处理上。

 

Undo_RetentionOracle提供出的用于控制Undo过期数据保留的“调节Tune”参数。注意:这里不是控制参数Oracle中的控制参数起到强制作用,比如目录空间位置,归档文件存储等。但是另一部分参数起到的是目标调节的作用,比如检查点间隔控制、SGA_TARGET

 

 

SQL> show parameter undo_ret

 

NAME                                 TYPE        VALUE

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

undo_retention                       integer     900

SQL>

 

 

undo_retention从直接看就是设置Oracle Undo过期数据的保存期限,单位是秒。如果参数设置为900秒,那么Undo段数据在非Active状态之后,会保留900秒。

 

如果根据这个守则,我们进行一致读和Flashback的时间就是通过这个参数来进行控制的。但是事实上,这个是有问题的。Undo的覆盖动作是一个必然的过程,覆盖与否是要和系统事务Undo消耗速率、Undo Tablespace大小乃至Undo数据文件可拓展性密切相关。

 

事实上,Undo_retention是一个“目标期望值”。用户设置出这个值之后,Oracle内部会尽量保证将Undo数据保留超过undo_retention设置的时间。在这个过程中,Oracle会涉及到比如尝试拓展Undo表空间数据文件、Undo Segment管理等内容。但是,如果“现实比较残酷”,比如说Undo使用紧张、没有额外的方法,那么这个时间段也是不能保证的。

 

下面我们通过一系列的实验来验证。

 

2、环境准备

 

我们选择Oracle 11gR2进行测试实验。

 

 

SQL> select * from v$version;

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production

PL/SQL Release 11.2.0.3.0 - Production

CORE        11.2.0.3.0         Production

 

 

当前采用自动的undo管理机制,默认retention900秒。注意:这个取值Oracle是有所选择的。早期版本中曾经设置过1800秒。

 

 

SQL> show parameter undo

 

NAME                                 TYPE        VALUE

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

undo_management                      string      AUTO

undo_retention                       integer     900

undo_tablespac                       string      UNDOTBS1

 

 

当前undo tablespace的数据文件拓展情况为支持拓展,容量为105M

 

 

SQL> col file_name for a40

SQL> select file_name, AUTOEXTENSIBLE, BYTES/1024/1024 MB from dba_data_files where tablespace_name='UNDOTBS1';

 

FILE_NAME                                AUTOEXTENSIBLE         MB

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

/u01/app/oradata/ORA11G/datafile/o1_mf_u YES                   105

ndotbs1_92t6zl6d_.dbf                                  

 

 

3、超过undo_retention情况数据读取

 

在没有强制的Undo数据覆盖情况下,Oracle默认会一直保留前镜像的数据。在实际中,虽然undo_retention设置的保留值比较小,但是我们依然可以flash back query出几个小时乃至几天前的数据。

 

为了便于实验过程,我们调节了一下参数。

 

 

SQL> alter system set undo_retention=300 ;

System altered

 

SQL> show parameter undo

 

NAME                                 TYPE        VALUE

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

undo_management                      string      AUTO

undo_retention                       integer     300

undo_tablespace                      string      UNDOTBS1

 

 

此处我们使用的是较大的Undo表空间105M,而且支持自动拓展文件。实验数据表情况如下:

 

 

SQL> create table t as select * from dba_objects;

Table created

 

SQL> select bytes/1024/1024 MB from dba_segments where wner='SYS' and segment_name='T';

        MB

----------

         9

 

SQL> select count(*) from t;

  COUNT(*)

----------

     75255

 

--注意:当前时点上,数据量为7万。

SQL> select sysdate from dual;

SYSDATE

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

2013-10-16 8:46:57

 

 

删除数据。

 

 

SQL> delete t;

75255 rows deleted

 

SQL> commit;

Commit complete

 

 

经过十五分钟左右,注意这个时间已经远远超过900秒设置值。

 

 

SQL> select sysdate from dual;

 

SYSDATE

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

2013-10-16 9:00:34

 

SQL> select count(*) from t;

 

  COUNT(*)

----------

         0

 

SQL> select count(*) from t as of timestamp to_timestamp('2013-10-16 8:46:57','yyyy-mm-dd hh24:mi:ss');

 

  COUNT(*)

----------

     75255

 

 

超过了900秒,Undo前镜像依然保留而且可以访问到。到此我们可以得出结论,即使commit后超过了undo_retention设置的时间范围,前镜像数据依然可以读取到。

 

4、小Undo空间非拓展试验

 

下面我们看一下undo时间小于retention的情况。向实验数据表中插入实验数据。

 

 

SQL> insert into t select * from dba_objects;

75255 rows inserted

 

SQL> commit;

Commit complete

 

 

创建一个全新的undo tablespace注意设置文件大小比较小,而且不支持自动拓展。

 

 

SQL> create undo tablespace undotbs2 datafile size 20m autoextend off;

Tablespace created

 

SQL> select tablespace_name, contents from dba_tablespaces;

 

TABLESPACE_NAME                CONTENTS

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

SYSTEM                         PERMANENT

SYSAUX                         PERMANENT

UNDOTBS1                       UNDO

TEMP                           TEMPORARY

USERS                          PERMANENT

UNDOTBS2                       UNDO

EXAMPLE                        PERMANENT

 

7 rows selected

 

SQL> select file_name, AUTOEXTENSIBLE, BYTES/1024/1024 MB from dba_data_files where tablespace_name in ('UNDOTBS1','UNDOTBS2');

 

FILE_NAME                                AUTOEXTENSIBLE         MB

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

/u01/app/oradata/ORA11G/datafile/o1_mf_u YES                   105

ndotbs1_92t6zl6d_.dbf                                  

 

/u01/app/oradata/ORA11G/datafile/o1_mf_u NO                     20

ndotbs2_95vsgpn7_.dbf                                   

 

 

更换系统使用的undo tablespace参数。

 

 

SQL> alter system set undo_tablespace=undotbs2

  2  ;

 

System altered

 

SQL> show parameter undo;

 

NAME                                 TYPE        VALUE

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

undo_management                      string      AUTO

undo_retention                       integer     300

undo_tablespace                      string      UNDOTBS2

 

 

删除数据,形成镜像。

 

 

SQL> select sysdate from dual;

 

SYSDATE

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

2013-10-16 9:18:57

 

SQL> select count(*) from t;

 

  COUNT(*)

----------

     75255

 

SQL> delete t;

55256 rows deleted

 

SQL> commit;

Commit complete

 

 

下面我们试图去消耗大量的undo空间,DML操作中,delete是消耗最大的。

 

 

SQL> delete mmm where rownum<10000;

9999 rows deleted

 

SQL> commit;

Commit complete

 

SQL> delete mmm;

delete mmm

 

ORA-30036: 无法按 8 扩展段 (在还原表空间 'UNDOTBS2' )

 

 

SQL> delete mmm where rownum<10000;

9999 rows deleted

 

SQL> commit;

Commit complete

 

 

删除动作中,很多时候都是禁止的。因为Undo空间过小,不能容纳需要保存的前镜像数据。

 

 

SQL> select count(*) from t as of timestamp to_timestamp('2013-10-16 9:15:09','yyyy-mm-dd hh24:mi:ss');

 

select count(*) from t as of timestamp to_timestamp('2013-10-16 9:15:09','yyyy-mm-dd hh24:mi:ss')

 

ORA-01555: 快照过旧回退段号 12 (名称为 "_SYSSMU12_550256870$") 过小

 

SQL> select sysdate from dual;

 

SYSDATE

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

2013-10-16 9:20:38

 

SQL> select count(*) from t as of timestamp to_timestamp('2013-10-16 9:17:09','yyyy-mm-dd hh24:mi:ss');

 

select count(*) from t as of timestamp to_timestamp('2013-10-16 9:17:09','yyyy-mm-dd hh24:mi:ss')

 

ORA-01555: 快照过旧回退段号 12 (名称为 "_SYSSMU12_550256870$") 过小

 

 

由此我们可以看到,虽然设置了undo_retention的参数,但是如果系统undo表空间容量不够大,而且undo生成总量很大的时候,系统还是会将undo进行覆盖。

 

那么,所谓的调节作用怎么体现呢?undo文件拓展是一种非常直接的手段。


阅读更多
文章标签: 数据库
个人分类: 数据库
想对作者说点什么? 我来说一句

CAPIHook类代码

2013年06月20日 6KB 下载

MTK开放错误总结.txt

2010年09月07日 7KB 下载

MQ错误代码表

2011年09月07日 18KB 下载

anywhere错误

2011年10月15日 280B 下载

Oracle 约束错误约束错误

2009年11月25日 28KB 下载

DNS解析错误解决办法

2010年06月13日 17KB 下载

sql错误

2009年01月02日 20KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭