Oracle数据库恢复之如何解决ORA-01555错误
首先我想说明的是ORA-01555是有可能导致整个库启不起来的。
我们来看一个极有趣的测试:
SQL_testdb>create table t1(id number,name varchar2(10));
Table created.
SQL_testdb>insert into t1 values(1,'cuihua1');
1 row created.
SQL_testdb>insert into t1 values(2,'cuihua2');
1 row created.
SQL_testdb>commit;
Commit complete.
SQL_testdb>select * from t1;
ID NAME
---------- ----------
1 cuihua1
2 cuihua2
现在我增加一下t1中这两条记录所对应的itl中的commit SCN让oracle产生一致读,并且改一下t1中这两条记录所对应的undo block的sequence后便构造出了ORA-01555:
SQL_testdb>select * from t1;
select * from t1
*
ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 19 with name "_SYSSMU19$" too small
我再把这两条记录所对应的undo block的sequence改回来,从结果里可以看到,上述两条记录明明已经commit了但这里就是读不到----因为这次产生的是正确的一致读:
SQL_testdb>select * from t1;
no rows selected
好了,我递增一下全库的SCN,不让oracle产生一致读了,于是这两条记录又回来了:
SQL_testdb>select * from t1;
ID NAME
---------- ----------
1 cuihua1
2 cuihua2
接着我如法炮制再次构造出ORA-01555:
SQL_testdb>select * from t1;
select * from t1
*
ERROR at line 1:
ORA-01555: snapshot too old: rollback segment number 19 with name "_SYSSMU19$"
too small
然后我什么都不改,只递增全库SCN,可以看到,上述ORA-01555已经不复存在,这两条记录现在又能看到了:
SQL_testdb>select * from t1;
ID NAME
---------- ----------
1 cuihua1
2 cuihua2
是不是觉得很晕?但这就是我在这篇文章里要说的重点:oracle里一致读的本质以及如何解决ORA-01555错误。