ORA-01555 原因与解决
ORA-01555的解释
假设有张表,叫table1,里面有5000万行数据,假设预计全表扫描1次需要1个小时,我们从过程来看:
1、在1点钟,有个用户A发出了select * from
table1;此时不管将来table1怎么变化,正确的结果应该是用户A会看到在1点钟这个时刻table1的内容。这个是没有疑问的。
2、在1点30分,有个用户B执行了update命令,更新了table1表中的第4000万行的这条记录,这时,用户A的全表扫描还没有到达第4000
万条。毫无疑问,这个时候,第4000万行的这条记录是被写到了回滚段里去了的,我假设是回滚段RBS1,如果用户A的全表扫描到达了第4000万行,是
应该会正确的从回滚段RBS1中读取出1点钟时刻的内容的。(未更新前的数据)
3、这时,用户B将他刚才做的操作commit了,但是这时,系统仍然可以给用户A提供正确的数据,因为那第4000万行记录的内容仍然还在回滚段
RBS1里,系统可以根据SCN来到回滚段里找到正确的数据,但是大家注意到,这时记录在RBS1里的第4000万行记录已经发生了一点重大的改变:就是
这个第4000万行的在回滚段RBS1里的数据有可能随时被覆盖掉,因为这条记录已经被提交了!
4、由于用户A的查询时间漫长,而业务在一直不断的进行,RBS1回滚段在被多个不同的tracnsaction使用着,这个回滚段里的extent循环到了第4000万行数据所在的extent,由于这条记录已经被标记提交了,所以这个extent是可以被其他transaction覆盖掉的!
5、到了1点40分,用户A的查询终于到了第4000万行,而这时已经出现了第4条说的情况,需要到回滚段RBS1去找数据,但是已经被覆盖掉了,于是01555就出现了。
?
ORA-01555 Explanation
There are two fundamental causes of the error ORA-01555 that are a
result of Oracle trying to attain a ‘read consistent‘ image. These
are :o The rollback information itself is overwritten so that
Oracle is unable to rollback the (committed) transaction entries to
attain a sufficiently old enough version of the block.o The
transaction slot in the rollback segment‘s transaction table
(stored in the rollback segment‘s header) is overwritten, and
Oracle cannot rollback the transaction header sufficiently to
derive the original rollback segment transaction slot.Both of these
situations are discussed below with the series of steps that cause
the ORA-01555. In the steps, reference is made to ‘QENV‘. ‘QENV‘ is
short for ‘Query Environment‘, which can be thought of as the
environment that existed when a query is first started and to which
Oracle is trying to attain a read consistent image. Associated with
this environment is the SCN (System Change Number) at that time and
hence, QENV 50 is the query environment with SCN 50.CASE 1 -
ROLLBACK OVERWRITTENThis breaks down into two cases: another
session overwriting the rollback that the current session requires
or the case where the current sessionoverwrites the rollback
information that it requires. The latter is discussed in this
article because this is usually the harder one to
understand.Steps:1. Session 1 starts query at time T1 and QENV 502.
Session 1 selects block B1 during this query3. Session 1 updates
the block at SCN 514. Session 1 does some other work that generates
rollback information.5. Session 1 commits the changes made in steps
‘3‘ and ‘4‘.
(Now other transactions are free to overwrite this rollback
information)6. Session 1 revisits the same block B1 (perhaps for a
different row).Now, Oracle can see from the block‘s header that it
has been changed and it is later than the required QENV (which was
50). Therefore we need to get an image of the block as of this
QENV.If an old enough version of the block can be found in the
buffer cache then we will use this, otherwise we need to rollback
the current block to generate another version of the block as at
the required QENV.It is under this condition that Oracle may not be
able to get the required rollback information because Session 1‘s
changes have generated rollback information that has overwritten it
and returns the ORA-1555 error.CASE 2 - ROLLBACK TRANSACTION SLOT
OVERWRITTEN1. Session 1 starts query at time T1 and QENV 502.
Session 1 selects block B1 during this query3. Session 1 updates
the block at SCN 514. Session 1 commits the changes
(Now other transactions are free to overwrite this rollback
information)5. A session (Session 1, another session or a number of
other sessions) then use the same rollback segment for a series of
committed transactions.These transactions each consume a slot in
the rollback segment transaction table such that it eventually
wraps around (the slots are written to in a circular fashion) and
overwrites all the slots. Note that Oracle is free to reuse these
slots since all transactions