當執行一個查詢時間非常長的時候,可能碰到ora-01555錯誤,本文來模擬並解釋一下原因.
013555是因爲查詢的數據在執行查詢的過程中,被修改了,同時在undo表空間中已經找不到了造成的.
首先來了解一下Oracle在執行一個查詢的時候,在開始查詢後其根據條件本該查詢出來的數據發生變化的時候,Oracle是將變化之前的數據查詢出來的.模擬如下:
1,有一張表的數據如下:
SQL> select * from A;
ID VAL
---------- ----------
1 a
2 b
2,在一個session(session A)中通過遊標查詢不open的方式模擬查詢開始了,但是還沒有真正訪問某一條記錄:
SQL> variable rc refcursor;
SQL> exec open :rc for select * from A; --這時候只是表示了開始查詢,記錄了查詢開始的SCN信息等
PL/SQL procedure successfully completed.
3,在另一個session(session B)中修改A表的數據如下並且提交:
SQL> update A set val = 'C';
2 rows updated.
SQL> commit;
Commit complete.
4,在session A中開始訪問已經修改並且提交的數據,但是看的數據仍然是查詢開始的時間點的數據:
SQL> print rc;
ID VAL
---------- ----------
1 a
2 b
上面的過程是Oracle通過undo表空間中的數據保證的.
那麼如果在print rc的時候,undo表空間中對應查詢開始時間點的數據不存在了的話,就會01555了.
1,爲了模擬這個現象,我們需要讓系統使用一個比較小的undo表空間,並且不自動擴展.
create undo tablespace undotbs02 datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS02.DBF' size 1M;
alter system set undo_tablespace=undotbs02
2,在一個session(session A)中通過遊標查詢不open的方式模擬查詢開始了,但是還沒有真正訪問某一條記錄:
SQL> variable rc refcursor;
SQL> exec open :rc for select * from A; --這時候只是表示了開始查詢,記錄了查詢開始的SCN信息等
PL/SQL procedure successfully completed.
3,在另一個session(session B)中修改A表的數據如下並且提交,通過下面的循環修改造成undo表空間的數據被覆蓋:
SQL> declare
2 i number :=0;
3 begin
4 loop
5 update a set id=i;
6 i := i+1;
7 if mod(i,200)=0 then
8 commit;
9 end if;
10 end loop;
11 end;
12 /
4,在session A中開始訪問已經修改並且提交的數據,發生01555錯誤
SQL> print rc;
ERROR:
ORA-01555: snapshot too old: rollback segment number 16 with name "_SYSSMU16$"
too small
*最好在執行循環更新的那個session中開始的時候通過 select distinct sid from v$mystat;把sid記下來,最後通過alter system kill session '$sid,$serial#' 殺死那個session,
如果萬一沒有最先記錄下來也可以通過select * from v$locked_object看出那個循環更新的session.
另外,改變了但是沒有提交的數據是必須放在undo表空間的,如果undo表空間不夠用,會發生ORA-30036錯誤.還是在undo表空間只有1M的情況下做下面的實驗:
SQL> select count(*) from A;
COUNT(*)
----------
20008
SQL> delete from A;
delete from A
*
ERROR at line 1:
ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS02'
將undo表空間改爲一個有比較大的size的datafile的表空間則可以正常delete.
---------------------
作者:IT農夫
來源:CSDN
原文:https://blog.csdn.net/kkdelta/article/details/7635430
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!