ITPub博客

首页 > 数据库 > Oracle > undo系列学习之读一致性(ORA-01555错误机制分析)

undo系列学习之读一致性(ORA-01555错误机制分析)

原创 Oracle 作者:幕南风 时间:2014-07-03 13:21:02 0 删除 编辑

    oracle在读的过程中,数据是静止的,没有脏读,也就是,未提交的永远都不会被读到。我们可以理解为,oracle在读的开始时,提前为他今后所要读的内容拍了一张”照片“,把所有内容全部定格在一个时间点上,作为接下来读的依据。oracle利用scn来实现这个理论,开始查询时,会确定一个select scn,这样就保证了事务槽里所有的scn都小于select scn。好比如,现在是12:21分,那么我之前所敲的字都在12:21分之前做的。

    我们已经知道,undo段是循环使用,并且,oracle只会把inactive的事务给覆盖。若是一个长时间的查询需要读到被覆盖的块时,就会报ora-01555错误。借助v$undostat里面的字段ssolderrcnt来查询在每个10分钟,oracle内是否发生过01555错误。

    下面是一张01555错误的图:

    产生01555错误,原因有好多,这里列三个:

    1)undo_retention不够大

    2)undo空间压力大

    3)sql性能差

    下面我们来模拟01555错误。注意,这里要避免和30036错误相混淆。

    会话1:

hr@ORCL> var i refcursor
hr@ORCL> exec open :i for select * from t;

PL/SQL procedure successfully completed.

hr@ORCL> print i;

        ID NAME
---------- ----------
         1 a
         2 b

hr@ORCL> exec open :i for select * from t;

PL/SQL procedure successfully completed.


    会话2:

sys@ORCL> delete from hr.t;

3 rows deleted.

sys@ORCL> commit;

Commit complete.


    会话1:

hr@ORCL> print i;

        ID NAME
---------- ----------
         1 a
         2 b

 

    如果有数据,则证明查询是修改前的;如果没有数据,则证明查询是修改后的。但如果,此时undo里面没有数据,那就会报错。从查询输出,可知,查询是修改前的。

    会话2:

sys@ORCL> create undo tablespace undotbs2 datafile \'/u01/app/oracle/oradata/ORCL/datafile/undotbsthi.dbf\' size 1m autoextend off;

Tablespace created.

sys@ORCL> alter system set undo_tablespace=undotbs2;

System altered.

sys@ORCL> show parameter undo_tablespace

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_tablespace                      string      UNDOTBS2


    会话1:

hr@ORCL> select * from t;

no rows selected

hr@ORCL> insert into t values (1,\'a\');

1 row created.

hr@ORCL> insert into t values(2,\'b\');

1 row created.

hr@ORCL> insert into t values(3,\'c\');

1 row created.

hr@ORCL> select * from t;

        ID NAME
---------- ----------
         1 a
         2 b
         3 c

hr@ORCL> commit;

Commit complete.

hr@ORCL> exec open :i for select * from t;

PL/SQL procedure successfully completed.


    会话2:

sys@ORCL> select a.spid "专用服务器进程",b.process "客户进程"
  from v$process a,v$session b
  where a.addr=b.paddr
  and b.sid=(select sid from v$mystat where rownum=1)  2    3    4  
  5  ;

专用服务器进 客户进程
------------ ------------
8427         8425

sys@ORCL> declare
i number :=0;
begin
loop
update hr.t set id=i;
i:=i+1;
if mod(i,200)=0 then commit;
end if;
end loop;
end; 


    会话1:

hr@ORCL> print i;
ERROR:
ORA-01555: snapshot too old: rollback segment number 11 with name "_SYSSMU11$" too small


    会话3:

[root@localhost ~]# kill -9 8427


    小结:undo够不够,就看01555.

 

<!-- Baidu Button BEGIN -->

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

上一篇: undo系列学习之Oracle IMU及Redo Private Strands技术
下一篇: oracle证明题:未提交的事务也可能被DBWn写进数据文件
请登录后发表评论 登录
全部评论
腾讯数据库工程师

注册时间:2012-05-10

最新文章