ORA-01555的模拟

1。使用一个很小的undo tablespace,并且固定大小
    create undo tablespace undo_small datafile 'xxx' size 1m autoextend off;
    alter system set undo_tablespace=undo_small scope=memory;
2。建立表,确保数据object_id随机分布   
    create table t as select * from all_objects order by dbms_random.random;
    create index idx_t on t(object_id);
3。在session 1里面进行一个loop的commit操作,这个操作将很快reuse undo block
    DECLARE
    BEGIN
      FOR x IN (SELECT ROWID rid FROM t) LOOP
        UPDATE t SET t.object_name=lower(t.object_name) WHERE t.ROWID=x.rid;
        COMMIT;
      END LOOP;
    END;
4。在session 2里面进行查询(强制使用索引,造成random访问)
    DECLARE
      v t.object_name%TYPE;
      CURSOR c IS SELECT /*+ first_rows */ object_name FROM t ORDER BY t.object_id;
    BEGIN
      OPEN c;
      LOOP
        FETCH c INTO v;
        EXIT WHEN c%NOTFOUND;
        dbms_lock.sleep(0.01);
      END LOOP;
      CLOSE c;
    END;

结果分析:
    1。当cursor在时间点T1被打开的时候,就决定了数据的读一致性(测试如下)
    2。s2读取被s1修改过的数据d1时,需要从undo里面获得T1时刻的d1前镜象数据
    3。因为undo很小,undo中存放d1前镜象的block已经被reuse,所以ORA-01555    

你可能感兴趣的:(ora)