ORA-08104: this index object xxxxx is being online built or rebuilt

来源:互联网 发布:java 断点续传 编辑:程序博客网 时间:2024/06/07 01:27
create/rebuild index online时会在该索引所在用户下创建一个在线日志中间表SYS_JOURNAL_obj#,和在ind$及online_ind$表里标记256或512(11G里的标记位可能不是);
如果服务进程在语句执行过程中意外终止的话,可能会导致相关在ind$标记位信息及在线日志中间表不能及时处理及清除(这个清除动作一般由smon进程来处理)这将导致
对该索引的后续操作因ORA-8104错误而无法继续,如果是分区表,索引是global,在添加分区也无法继续:
SQL> drop index idex_id;
drop index idex_id
           *
ERROR at line 1:
ORA-08104: this index object 79279 is being online built or rebuilt

SQL> alter index idex_id rebuild online
  2  ;
alter index idex_id rebuild online
*
ERROR at line 1:
ORA-08104: this index object 79279 is being online built or rebuilt


实际处理情况
异常结束了:
SQL> create index idex_id on large_t(object_id) online;
create index idex_id on large_t(object_id) online
                        *
ERROR at line 1:
ORA-01013: user requested cancel of current operation

重新创建时的报错情形:
SQL> create index idex_id on large_t(object_id) online;
create index idex_id on large_t(object_id) online
             *
ERROR at line 1:
ORA-00955: name is already used by an existing object

drop时的报错情形:
SQL> drop index idex_id;
drop index idex_id
           *
ERROR at line 1:
ORA-08104: this index object 79279 is being online built or rebuilt

rebuild时的报错情形:
SQL> alter index idex_id rebuild online;
alter index idex_id rebuild online
*
ERROR at line 1:
ORA-08104: this index object 79279 is being online built or rebuilt

查询相关视图发现信息并没有被smon清除从而上面报错:
SQL> set linesize 200
SQL> col object_name for a30;
SQL> SELECT owner,object_name,object_id,object_type,created,last_ddl_time FROM DBA_OBJECTS D WHERE D.OBJECT_NAME like 'SYS_JOURNAL_%';
OWNER                          OBJECT_NAME                     OBJECT_ID OBJECT_TYPE         CREATED   LAST_DDL_
------------------------------ ------------------------------ ---------- ------------------- --------- ---------
TEST                           SYS_JOURNAL_79279                   79280 TABLE               29-JUL-14 29-JUL-14

SQL> select owner#,obj#,name from obj$ where name='IDX_ID';
    OWNER#       OBJ# NAME
---------- ---------- ------------------------------
        44      59077 IDX_ID

SQL>
SQL> select obj#,flags from ind$ where obj#=79279;
      OBJ#      FLAGS
---------- ----------
     79279        256
     
调用脚本来处理并且跟踪其产生的信息
SQL> oradebug setmypid    
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 8;
Statement processed.
SQL>
SQL> DECLARE
  2   r_value BOOLEAN;
  3  BEGIN
  4    r_value := FALSE;
  5    WHILE isClean=FALSE
  6    LOOP
  7      r_value := dbms_repair.online_index_clean(
  8      dbms_repair.all_index_id, dbms_repair.lock_wait);
  9      dbms_lock.sleep(3);
 10    END LOOP;
 11  END;
 12  /

PL/SQL procedure successfully completed.
SQL> oradebug tracefile_name;
/u01/app/oracle/admin/ORCL/udump/orcl_ora_27996.trc
SQL> oradebug close_trace   
Statement processed.

从跟踪的trc里可以看到对很多$结尾的表做了select和delete动作,主要有
drop table "TEST"."SYS_JOURNAL_79279" purge
delete from ind$ where bo#=:1
delete from ind$ where obj#=:1

1)、如果调用这个函数去处理时,有dml在表上面做操作,可能会导致函数一直loop去处理,但是没有处理成功,在alert日志里会报出,
就种情况要找出什么session在做dml操作,然后再做处理
Mon Jul 29 16:16:25 2014
online index (re)build cleanup: objn=79279 maxretry=2000 forever=0
Mon Jul 29 16:20:19 2014
online index (re)build cleanup: objn=79279 maxretry=2000 forever=0
Mon Jul 29 16:24:14 2014
online index (re)build cleanup: objn=79279 maxretry=2000 forever=0

2)、这个函数也不是万能的,在11.2.0.3.6的版本上,就遇到一个利用此函数也不能清除的案例,最后,查询发现索引对象已经不存在,并且在ind$和obj$表里
查不到相关对象了,但是在ind_online$表里发现还有记录,可能原因是smon在做clean动作时,需要去关联相关表,发现某些记录不存在,不能识别然后做
clean动作导致吧,这里纯属推测,针对这种情形,手工drop table xxxx purge,保留online_ind$里的信息;如果在10gR1之前遇到这种情况,恭喜了,可
能是遇到了bug。

通过函数处理后,发现可以了
SQL> /
alter index idex_id rebuild online
*
ERROR at line 1:
ORA-01418: specified index does not exist


SQL> /
drop index idex_id
           *
ERROR at line 1:

ORA-01418: specified index does not exist






===========================
相关交流信息
QQ群: 330218614
Email: 623009431@qq.com
Blog: http://blog.csdn.net/trsenzhang
============================

0 0