日期:2014-05-16  浏览次数:20435 次

[每日一题] 11gOCP 1z0-052 :2013-09-28 ORA-01555: snapshot too old......................C52

转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/12204587




正确答案:A

 

重现ORA-01555快照过旧的错误。

[oracle@mydb admin]$ 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

建undo表空间

gyj@OCM>  create undo tablespace undotbs2 datafile'/u01/app/oracle/oradata/ocm/undotbs2.dbf' size 10M;
 
Tablespace created.
 
gyj@OCM> alter system set undo_tablespace=undotbs2;
 
System altered.
 
gyj@OCM> alter system set undo_retention=2 scope=both;
 
System altered.

第1步、session1: 目标是让b表报快照过旧的报错

gyj@OCM> conn gyj/gyj
Connected.
gyj@OCM> create table a (id int,cc varchar2(10));
 
Table created.
 
gyj@OCM>        insert into a values(1,'hello');
 
1 row created.
 
gyj@OCM> commit;
 
Commit complete.
 
gyj@OCM> create table b(id int,cc varchar2(10));
 
Table created.
 
gyj@OCM>        insert into b values(10,'AAAAAA');
 
1 row created.
 
gyj@OCM>        commit;
 
Commit complete.
 
gyj@OCM> select * from a;
 
       ID CC
---------- ----------
        1 hello
 
gyj@OCM> select * from b;
 
       ID CC
---------- ----------
       10 AAAAAA
 
gyj@OCM> var x refcursor;
gyj@OCM> exec open :x for select * fromb;
 
PL/SQL procedure successfully completed.

第2步、session2:修改b表,字段cc前镜像"OK"保存在UDNO段中

gyj@OCM> update b set cc='BBBBBB' where id= 10;
 
1 row updated.
 
gyj@OCM>   commit;
 
Commit complete.

第3步、session 3:该条语句就是刷新缓存

sys@OCM> alter system flush buffer_cache;
 
System altered.

第4步、再开3-5个会话:在A表上行大的事务,多运行几次以确保,回滚段被覆盖

gyj@OCM> begin
 2     for i in 1..20000 loop
 3      update a set cc='HELLOWWWW';
 4      commit;
 5     end loop;
 6    end;
 7   /
 
 
PL/SQL procedure successfully completed.

第5步、session 1:在B表上执行查询(第一步的查询)

gyj@OCM>  print :x
ERROR:
ORA-01555: snapshot too old: rollbacksegment number 21 with name "_SYSSMU21$" too small

ORA-01555快照过旧与Oracle的一致性读有关,一致性读的实现与UNDO有关。那什么是一致性读呢?

Oracle读一致性是指一个查询所获得的数据来自同一时间点。



一致性读在Oracle中是一个非常重要的概念, 大家一起跟着我先来做下面的一个实验:

gyj@OCM> create table gyj (id int,name varchar2(10));
Table created.
gyj@OCM> insert into gyj values(1,'GGGGGG');
1 row created.
gyj@OCM> commit;
Commit complete.
gyj@OCM> select * from gyj;
        ID NAME
---------- ----------
         1 GGGG