ITPub博客

首页 > Linux操作系统 > Linux操作系统 > ORA-01555 snapshot too old的错误测试

ORA-01555 snapshot too old的错误测试

原创 Linux操作系统 作者:oracle_ace 时间:2008-01-25 18:12:13 0 删除 编辑

C:\>set ORACLE_SID=irmdb

C:\>sqlplus /nolog

SQL*Plus: Release 10.2.0.3.0 - Production on 星期五 1月 25 15:12:15 2008

Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.

SQL> conn / as sysdba;
已连接。
SQL> show parameter undo;

NAME                                 TYPE        VALUE
------------------------------------ ----------- -----------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

SQL> select file_name from dba_data_files;

FILE_NAME
------------------------------------------------------------
D:\ORACLE\PRODUCT\10.2.0\ORADATA\IRMDB\USERS01.DBF
D:\ORACLE\PRODUCT\10.2.0\ORADATA\IRMDB\SYSAUX01.DBF
D:\ORACLE\PRODUCT\10.2.0\ORADATA\IRMDB\UNDOTBS01.DBF
D:\ORACLE\PRODUCT\10.2.0\ORADATA\IRMDB\SYSTEM01.DBF
D:\ORACLE\PRODUCT\10.2.0\ORADATA\IRMDB\EXAMPLE01.DBF
D:\ORACLE\PRODUCT\10.2.0\ORADATA\IRMDB\TEST.DBF

---这里我们创建一个小的undo表空间,并设为默认.注意这里我们不允许undo_small增长。

SQL> create undo tablespace undo_small
  2  datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\IRMDB\undo_small.dbf' size 2m
  3  autoextend off;

表空间已创建。

SQL> alter system set undo_tablespace=undo_small;

系统已更改。

SQL> select usn,status from v$rollstat;

       USN STATUS
---------- ---------------
         0 ONLINE
        11 ONLINE
        12 ONLINE
        13 ONLINE
        14 ONLINE
        15 ONLINE
        16 ONLINE
        17 ONLINE
        18 ONLINE
        19 ONLINE
        20 ONLINE

已选择11行。


---建立一个表用来按照index对行进行随机分布
SQL> create table t
  2  as
  3  select * from all_objects
  4  order by dbms_random.random;

表已创建。

SQL> alter table t add constraint t_pk primary key (object_id);

表已更改。

SQL> exec dbms_stats.gather_table_stats(user,'T',cascade=>TRUE);

PL/SQL 过程已成功完成。

---之后我们在sess 1开始进行update
SQL> begin
  2     for x in (select rowid rid from t)
  3     loop
  4                     update t set object_name = lower(object_name) where rowid=x.rid;
  5                     commit;
  6     end loop;
  7  end;
  8  /

---update的同时我们在sess 2进行select
SQL> declare
  2     cursor c is
  3             select /*+ first_rows */ object_name from t order by
  4
  5     l_object_name t.object_name%type;
  6     l_rowcnt number := 0;
  7  begin
  8     open c;
  9     loop
 10             fetch c into l_object_name;
 11             exit when c%notfound;
 12             dbms_lock.sleep(0.02);
 13             l_rowcnt := l_rowcnt + 1;
 14     end loop;
 15     close c;
 16  exception
 17     when others then
 18             dbms_output.put_line('rows fetched = ' || l_rowcnt);
 19             raise;
 20  end;
 21  /
declare
*
第 1 行出现错误:
ORA-01555: 快照过旧: 回退段号 15 (名称为 "_SYSSMU15$") 过小
ORA-06512: 在 line 19

这样我们就把ora-01555错误给重现了;
那么如何避免这样的错误呢?我们需要做到两点:

undo_retention:这个参数要设置的足够长,一般来说最好大于我们最长query的时间,那么在undo不足的情况下,可以通过扩展undo来使我们能够完成我们的工作。

undo表空间需要可以auto增长,或者我们设置一个足够大的undo表空间

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12361284/viewspace-160128/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2007-12-10

  • 博文量
    284
  • 访问量
    788997