【Oracle 11g】ORA-01555: snapshot too old(快照过旧)错误
这个错误会导致:接收到这个错误的查询无法继续处理。 引起这个错误的原因有3个:
解决方案
实验一、创造一个snapshot too old并解决它制造错误连接数据库,并建立undo表空间 C:UsersAdministrator>sqlplus / as sysdba
SQL*Plus: Release 11.2.0.1.0 Production on 星期一 9月 5 22:36:07 2016
Copyright (c) 1982,2010,Oracle. All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning,OLAP,Data Mining and Real Application Testing options
SQL> create undo tablespace undo_small
2 datafile '/tmp/undo.dbf' size 2m
3 autoextend off
4 /
表空间已创建。
我的oracle是安装在E盘的。如下是我的oracle_home(这个是我自己配置的,oracle安装的那个目录)。所以如上的行为,会在e:tmp目录中创建一个名为“undo.dbf”并占用磁盘空间2M的文件。 C:UsersAdministrator>set oracle_home
ORACLE_HOME=E:appAdministratorproduct11.2.0dbhome_1
设置undo表空间 SQL> alter system set undo_tablespace = undo_small;
创建一个把行打乱(order by dbms_random.random)的表t SQL>create table t as select * from all_objects order by dbms_random.random;
看看数据量 SQL> select count(*) from t; COUNT(*)
----------
71817
增加主键并执行存储过程(dbms_stats.gather_table_stats) 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 过程已成功完成。
如下两个存储过程需要同时执行。 SQL> begin
2 for x in (select rowid rid from t)
3 loop
4 update t set object_name = upper(object_name) where rowid = x.rid;
5 commit;
6 end loop;
7 end;
8 /
PL/SQL 过程已成功完成。
我是另外打开一个sqlplus,连接数据库,运行如下sql。然后立马运行如上的sql。只运行几秒,如下的查询就报错了。 SQL> declare
2 cursor c is
3 select /*+ first_rows */ object_name
4 from t
5 order by object_id;
6
7 l_object_name t.object_name%type;
8 l_rowcnt number := 0;
9 begin
10 open c;
11 loop
12 fetch c into l_object_name;
13 exit when c%notfound;
14 dbms_lock.sleep( 0.01);
15 l_rowcnt := l_rowcnt + 1;
16 end loop;
17 close c;
18 exception
19 when others then
20 dbms_output.put_line( 'rows fetched = ' || l_rowcnt);
21 raise;
22 end;
23 /
declare
*
第 1 行出现错误:
ORA-01555: 快照过旧: 回退段号 18 (名称为 "_SYSSMU18_3188057130$") 过小
ORA-06512: 在 line 21
此时,查看下undo空间,依然2M。 SQL> select bytes/1024/1024
2 from dba_data_files
3 where tablespace_name = 'UNDO_SMALL';
BYTES/1024/1024 ---------------
2
解决错误这个长时间运行的进程需要大约718秒完成。(表中有71817条记录,0.01秒运行一条记录,共需720秒。)我的undo_retention设置为900秒(所以undo大约保持15分钟)。 SQL> show parameter undo_retention
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900
修改undo表空间的数据文件,使之一次扩大1MB,知道最大达到2GB: SQL> alter database
2 datafile '/tmp/undo.dbf'
3 autoextend on
4 next 1m
5 maxsize 2048m;
数据库已更改。
再次并发的运行这些进程,两个进程都能顺利完成。这一次undo表空间的数据文件扩大了,因为,再次允许的undo表空间扩大。 SQL> select bytes/1024/1024
2 from dba_data_files
3 where tablespace_name = 'UNDO_SMALL';
BYTES/1024/1024 ---------------
21
本文参考《Oracle_Database_9i10g11g编程艺术深入数据库体系结构》第2版,Thomas Kyte著,苏金国 王小振等译,301~306页。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- dart – PageView:禁用默认滚动并将其替换为Tap事件
- C#对象与XMl文件之间的相互转换
- Swift3.0 GCD定时器的使用,实现倒计时,UIDatePicker的使用,
- 修改了settings.xml后无法生效
- ruby-on-rails – Ransack计数排序顺序错误
- c# – 我应该抛出Global.asax中的Application_Error处理程序
- c – 如何从OpenCV中的XML字符串中读取?
- 正则表达式 – 根据其他列向Panda数据框添加新列
- nosql – 多维地图中的地图维度究竟是什么?
- Cocos2d-x结构学习(十八)Timeline、BoneData、SlotData、