Oracle的ORA-01555

什么是ORA-01555

 首先解释下Ora-01555。

[oracle@rhel_lky02 ~]$ oerr ora 01555
01555, 00000, "snapshot too old: rollback segment number %s with name \"%s\" too small"
// *Cause: rollback records needed by a reader for consistent read are
//         overwritten by other writers
// *Action: If in Automatic Undo Management mode, increase undo_retention
//          setting. Otherwise, use larger rollback segments

 ORA-01555错误代码,字面意思就是快照过旧。这是Oracle数据库中很常见的一个错误,当我们的事务需要使用undo来构建CR块的时候,而此时对应的undo 已经不存在了, 这个时候就会报ORA-01555的错误。

场景模拟

 接下来用一个简单的例子模拟下这个ora-01555错误代码的出现。

 首先创建一个较小的undo表空间,且不能自动扩展,并将undo_retention设置为1秒

SQL> create undo tablespace undo_2 datafile '/u01/app/oracle/oradata/standby/undo_2.dbf' size 3M autoextend off;
Tablespace created.

SQL> alter system set undo_retention=1 scope=spfile;
System altered.

SQL> alter system set undo_tablespace=undo_2 scope=spfile;
System altered.

接下来.重启数据库。然后我们查看到undo参数如下,

SQL> show parameter undo;

NAME TYPE VALUE
------------------------------------ -------------------------------- ------------------------------
undo_management string AUTO
undo_retention integer 1
undo_tablespace string TEST_UNDO

然后我们开始这个错误场景的模拟。首先进行如下的准备工作,

#使用liu用户登录
SQL> connect liu/liu
Connected.
SQL> show user
USER is "LIU"

#创建一个表T4
SQL> create table t4 as select * from dba_objects where rownum<=10000;

Table created.

#定义一个游标,打开游标
SQL> var c1 refcursor
SQL> begin
  2 open :c1 for select * from liu.t4;
  3 end;
  4 /

PL/SQL procedure successfully completed.

#更新表T4的一行数据,并提交
SQL> update liu.t4 set object_id=111 where rownum<=2;

1 row updated.

SQL> commit;

Commit complete.

 而这时,游标一直处于open状态,这个select语句直到print :c1操作完成才结束。即模拟了一个执行时间较长的select。

 接下来是比较关键的部分了,模拟对undo表空间的大量占用。

#创建表T5
SQL> create table t5 as select * from dba_objects where 1=2;

Table created.
#使用一个循环,让大量的事务对表T5进行批量的修改
SQL> begin
  for i in 1..20000 loop
  insert into liu.t5 select * from dba_objects where rownum<=1000;
  delete from liu.t5;
  commit;
  end loop;
  end;
  /

此时,会有大量的redo log及undo log产生,直到把磁盘空间占满,

SQL> select event,seconds_in_wait from v$session where username='SYS';

EVENT SECONDS_IN_WAIT
---------------------------------------------------------------- ---------------
log file switch (archiving needed) 18
SQL*Net message from client 0

从上面的等待时间可以看到,日志已经不能进行正常的切换了。

[root@oracle11g ~]# df -Th|grep archive
/dev/sdc1 ext4 9.9G 9.3G 102M 99% /archive
#清空归档,释放空间
[root@oracle11g ~]# cd /archive/
[root@oracle11g archive]# rm -rf *
#然后切换日志
SQL> alter system switch logfile;
System altered.
#再次查看等待事件
SQL> select event,seconds_in_wait from v$session where username='SYS';

EVENT SECONDS_IN_WAIT
---------------------------------------------------------------- ---------------
log buffer space 0
SQL*Net message from client 35
SQL*Net message to client 0
SQL*Net message from client 35

然后紧接着出现如下报错


ERROR at line 1:
ORA-30036: unable to extend segment by 8 in undo tablespace 'TEST_UNDO'
ORA-06512: at line 4

此时,说明undo表空间已被全部覆盖。接下来,我们打印出前面一直处于open状态的游标。

SQL> print :c1
…
ERROR:
ORA-01555: snapshot too old: rollback segment number 23 with name
"_SYSSMU23_894261744$" too small

那么,这个ora-01555错误终于出现了。造成这个报错的原因在于,undo已经全部被我们模拟的大量事务所覆盖。

简单总结

首先,会导致ora-01555错误出现的情况如下,

1.undo表空间过小且不能自动扩展
2.retention时间过小
3.事务提交频繁
4.undo数据增长过快
5.select执行时间过长

然后,我们的解决方法有以下几种,

1.加大undo表空间
2.retention时间设置大一些
3.合并事务
4.优化sql执行,提升速度

时间: 2024-09-20 20:33:53

Oracle的ORA-01555的相关文章

Oracle数据库ORA 54013错误的解决办法_oracle

ORA-54013: 不允许对虚拟列执行 INSERT 操作 这是Oracle 11 的新特性 -- 虚拟列. 在以前的Oracle 版本,当我们需要使用表达式或者一些计算公式时,我们会创建数据库视图,如果我们需要在这个视图上使用索引,我们会创建基于函数的索引.现在Oracle 11允许我们直接在表上使用虚拟列来存储表达式.虚拟列的值是不存储在磁盘的,它们是在查询时根据定义的表达式临时计算的.我们不能往虚拟列中插入数据,我们也不能隐式的添加数据到虚拟列,我们只能使用物理列来插入数据.然后可以查询

Oracle TNSNAMES.ORA配置

在安装目录下,如:E:\Oracle\Ora81\network\ADMIN下用写字板或记事本打开TNSNAME.ORA文件,文件内容大概如下: TEST.SOFTONE.COM = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = zcb_8115)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = test) ) ) 蓝色部分为安装时录入的信息. 如果该文件没有配置

ORACLE的ORA-1693错误以及表和索引的表空间的移动

本公司开发的软件,有客户不能上传大的附件,页面不报任何错误.查看JBOSS日志,同样看不到任何错误,排除了软件本身故障. 在查看oracle数据库日志,发现当上传大的附件时出现错误信息 OEA_1693: MAX # EXTENTS 4096 reached in lobsegment nes.sys_LOB0000024832C00008$$ 解决过程 上网找了下资料 ORA-1693 max # extents (string) reached in lob segment string.s

oracle 11g导出数据时报ORA 1455错误的处理方法_oracle

由于导出的该用户的表可能存在空数据表,那么可能就会出现此其异常. 首先: 查看: SQL>show parameter deferred_segment_creation; 如果为TRUE,则将该参数改为FALSE: 在sqlplus中,执行如下命令: SQL>alter system set deferred_segment_creation=false; 然后: 可以针对数据表.索引.物化视图等手工分配Extent SQL>Select 'alter table '||table_n

Oracle ORA 07445 evaopn2()+128错误问题的解决方案_oracle

问题描述 Plsql developer执行一段sql报错: 经查alert log详细报错信息为: ORA-07445: exception encountered: core dump [evaopn2()+128] [SIGSEGV] [Address not mapped to object] [0x000000000] [] [] 数据库版本 10.2.0.4.0 问题原因 复杂视图合并问题导致的oracle bug 解决方法 1.修改隐藏参数: alter system set "_

Oracle 错误总结及问题解决 ORA

参考地址 ORA-00001: 违反唯一约束条件 (.)错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常.ORA-00017: 请求会话以设置跟踪事件ORA-00018: 超出最大会话数ORA-00019: 超出最大会话许可数ORA-00020: 超出最大进程数 ()ORA-00021: 会话附属于其它某些进程:无法转换会话ORA-00022: 无效的会话 ID:访问被拒绝ORA-00023: 会话引用进程私用内存:无法分离会话ORA-00024: 单一进程模式下不允许从多个进程注册

Oracle 9i 数据库移动过程

oracle|过程|数据|数据库 Oracle 9i 数据库移动过程 作者:未知   数据库移动,在项目实施过程中,经常会发生,对于有经验的DBA来说,数据库移动是十分容易.但对于一些只了解系统,对数据库不是十分懂的人员来说,oracle的移动就不是那么容量了. 例如当系统安装完成以后,存储空间扩容了,需要对原对ORACLE进行移动,需要进行数据移动.以前在ORACLE8I FOR WINDOWS 2000中是可以进行移动的.现在ORACLE9I FOR AIX 5L 的移动如何做呢???其实经

Oracle 10g Physical DataGuard的搭建过程

primary 环境 DB version:oracle10.2.0.4 IP:192.168.1.7 hostname:vzwc db_name:dbserver db_unique_name:dbserver service_name:dbserver instance_name:ORCL standby 环境 DB version:oracle10.2.0.4 IP:192.168.1.6 hostname:dgstb db_name:dbserver db_unique_name:sta

oracle用户可以tnsping通、普通用户tnsping报错的问题

今天碰到了一个有趣的问题 oracle用户可以tnsping通,普通用户tnsping报错 用普通用户tnsping数据库的时候报 TNS-03505: Failed to resolve name 而用oracle用户tnsping数据库的时候却可以ping通 <34 linux-sit:/home/smsds>tnsping orarpt TNS Ping Utility for Linux: Version 11.1.0.6.0 - Production on 24-DEC-2011 1