一个过程报错:ORA-01410: invalid rowid。
这个过程以前都没有出现过这个错误。当时正在rebuild online索引。怀疑是这个原因导致的。
错误模拟:
1)session1,创建一个表T1,ID为主键。运行一个比较耗时的SQL,强制让这个SQL用上索引。
drop table t1;
create table t1 as
select
rownum id,
rpad(rownum,10) v1,
rpad('x',100) v2
from
all_objects
where
rownum <= 10000 ;
;
alter table t1 add constraint t1_pk primary key(id);
execute dbms_stats.gather_table_stats(user,'t1')
declare
m_v1 varchar2(10);
begin
for r in (select /*+ index(t1) */
v1
from t1
where id > 0) loop
m_v1 := r.v1;
dbms_lock.sleep(0.01);
end loop;
end;
/
2)session2运行如下语句:
DROP TABLE ttt;
alter index t1_pk rebuild online;
CREATE TABLE ttt AS select * from dba_objects;
session2会很快完成,这个时候查看session1,报错了ORA-01410: invalid rowid。
解释如下:
1)rebuild索引的时候,会现在一个临时段去创建。创建完成后,会释放老索引段的空间。比较权威的原话如下:
if you rebuild an index (whether or not you use the online option) Oracle will copy the index contents from one location to another and,
when the copy is complete, free up the space that held the original index contents.
2)如果你在rebulid之前运行了一个比较长的查询,这查询将继续使用老索引。Oracle introduced a form. of ‘cross-DDL read consistency’ many years
ago to make partition maintenance operations possible, and that’s the feature that allows your query to carry on running.
3)那么这种情况下怎么办呢?一个表需要扩展或者一个索引需要扩展或者一个新表需要创建,那么老索引的空间就有可能被填充,那么你之前的长查询还在依赖这个
老索引空间,这种情况一出现,就有可能出现错误ORA-01410: invalid rowid。
如果实验里创建表TTT的表空间不跟索引T1_PK在一个表空间,就不会报错。
不理解的再看下这篇文章:
打不开的用这个中转一下:
[本帖最后由 wei-xh 于 2010-12-9 10:53 编辑]