rebuild online意外终止导致ora-8104错误的实验

SQL> !oerr ora 8104
08104, 00000, "this index object %s is being online built or rebuilt"
// *Cause: the index is being created or rebuild or waited for recovering
// from the online (re)build
// *Action: wait the online index build or recovery to complete

因为rebuild index online 的意外终止,导致该索引处于一种被重建的状态,经实验证明该状态下可以使用

通过以下sql定位问题的object id
SQL> select obj#,flags from ind$ where bitand(flags,512) = 512;

解决方法有两种:

其一等待smon清理

Note: SMON will perform the cleanup and does this once every 60 minutes. SMON cleanup is only successful if there are no transactions against the base table [or [sub]partition] at the time of the attempted cleanup. In an environment where there are likely to be uncommitted transactions, this makes cleanup a bit ‘hit and miss’. To speed up the process, you can stop your application which uses the table and wait until the cleanup is done.

其二调用DBMS_REPAIR.ONLINE_INDEX_CLEAN手动清理

* Please note if you are unable to run the dbms_repair.online_index_clean function it is due to the fact that you have not installed the patch for Bug 3805539 or are not running on a release that includes this fix. The fix for this bug is a new function in the dbms_repair package called dbms_repair.online_index_clean, which has been created to cleanup online index [[sub]partition] [re]builds. New functionality is not normally introduced in patchsets; therefore, this is not available in a patchset but is available in 10gR2.

- Check your patch list to verify the database is patched for Bug 3805539 using the following command and patch for the bug if it is not listed:

以下是实验步骤

参考

http://www.syksky.com/oracle/rebuild-index-online-fails-ora-8104.html

---------------------------------------------------

表的数据量情况
SQL> select count(1) from t_ind_rebuild;

COUNT(1)
----------
1650816

索引的情况
SQL> select bytes/1024/1024/1024 from user_segments where segment_name='IND_T_IND_REBUILD';

BYTES/1024/1024/1024
--------------------
.0703125

会话a
SQL> select sid from v$mystat where rownum=1;

SID
----------
193


SQL> select spid from v$process p,v$session s where s.paddr=p.addr and sid=193;

SPID
------------------------
5567

SQL> alter index IND_T_IND_REBUILD rebuild online;
alter index IND_T_IND_REBUILD rebuild online
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 5567
Session ID: 193 Serial number: 5

会话b
SQL> !kill -9 5567


查看rebuild online意外中断后的信息
SQL> select obj#,flags from ind$ where bitand(flags,512) = 512;

OBJ# FLAGS
---------- ----------
13308 2562

SQL> alter index ivo.IND_T_IND_REBUILD rebuild online;
alter index ivo.IND_T_IND_REBUILD rebuild online
*
ERROR at line 1:
ORA-08104: this index object 13308 is being online built or rebuilt

可以使用该索引
SQL> explain plan for select * from ivo.T_IND_REBUILD where object_id<10;

Explained.

SQL> set lines 180
SQL> set pages 10000
SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1611265204

-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 712 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T_IND_REBUILD | 8 | 712 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T_IND_REBUILD | 8 | | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("OBJECT_ID"<10)

14 rows selected.


SQL> declare
2 isclean boolean;
3 begin
4 isclean := false;
5 while isclean = false loop
6 isclean := DBMS_REPAIR.ONLINE_INDEX_CLEAN(13308, dbms_repair.lock_wait);
7 dbms_lock.sleep(10);
8 end loop;
9 end;
10 /


PL/SQL procedure successfully completed.

SQL> SQL> SQL> SQL>
SQL>
SQL>
SQL>
SQL> select obj#,flags from ind$ where bitand(flags,512) = 512;

no rows selected

SQL>
SQL>
SQL>
SQL> alter index ivo.IND_T_IND_REBUILD rebuild online;

原文地址:https://www.cnblogs.com/archersun/p/3622199.html