online rebulid index異常終止遇到ora-08104
create index idx_p_merchant_detail_id on D_ORDER_DETAIL (merchant_detail_id) Online;
建立好長時間,沒有反映;然後取消,結果刪除索引的時候,報如下的錯誤:
錯誤:ORA-08104: this index object 67420 is being online built or rebuilt
通過 ONLINE 引數建立索引(或者重建索引), 如果程式被突然終止,或者是手工 CTRL+C 取消該操作,
在非常個別的時候,麻煩來了。重新建立索引,會告訴你該索引已經存在,drop index ,會告訴你該索
引被鎖,或者是 ORA-08104(this index object xxxxx is being online built or rebuilt) 錯誤。
該過程失敗之前建立的一些臨時物件由 SMON 負責清除,糟糕的是, SMON 可不是那麼聽話,馬上出來清除,
這個清除時間可能會很長,據說在 9i 上觀察是 2 個小時才清除掉。
如何解決呢?
在Oracle10g之前,對於這種情況沒有太好的辦法,只有等SMON程式來進行清理了。網上有說上重啟庫可以解決,
有說直接update系統表ind$的,對於不能停機的產品庫來說,這些都是不可取的方案。重啟不現實,修改系統表
更是DBA的大忌。
最好是等系統自動清除,如果因此給你帶來的影響讓你不得不手動儘早清除的話,那就看你的運氣了
如果是Oracle10g,則可以使用dbms_repair.online_index_clean手工清理(metalink的說法,9i打了Bug 3805539的patch的話也能用該過程了)。
如果是一個比較繁忙的 OLTP 系統, 並且是要維護單列索引,那麼風險真的是很大的。在 SMON 清除這些臨
時物件之前,沒有辦法在該列上建立新的索引。伺服器能撐住麼?
異常終止的情況下,可以發現ind$關於該索引的狀態還是online rebuild的:
SQL> select obj#,flags from ind$ where obj#=67420;
OBJ# FLAGS
---------- ----------
67420 514
Flags欄位的說明可以在ind$的sql.bsq指令碼中找到:
/* mutable flags: anything permanent should go into property */
/* unusable (dls) : 0x01 */
/* analyzed : 0x02 */
/* no logging : 0x04 */
/* index is currently being built : 0x08 */
/* index creation was incomplete : 0x10 */
/* key compression enabled : 0x20 */
/* user-specified stats : 0x40 */
/* secondary index on IOT : 0x80 */
/* index is being online built : 0x100 */
/* index is being online rebuilt : 0x200 */
/* index is disabled : 0x400 */
/* global stats : 0x800 */
/* fake index(internal) : 0x1000 */
/* index on UROWID column(s) : 0x2000 */
/* index with large key : 0x4000 */
/* move partitioned rows in base table : 0x8000 */
/* index usage monitoring enabled : 0x10000 */
514=0×202,表示該索引狀態為index is being online rebuilt : 0×200 + analyzed : 0×02
在SMON完成清理動作後,再次查詢索引狀態已經恢復正常:
SQL> select obj#,flags from ind$ where obj#=67420;
OBJ# FLAGS
---------- ----------
67420 2
清理完後,可以在alert.log中看到如下記錄:
User:,time:20071209 03:12:09,program:oracle@db1
(SMON),IP:,object:SYS_JOURNAL_67420,DDL: drop table "TAOBAO"."SYS_JOURNAL_67420"
解決一:
在10g中用dbms_repair.online_index_clean來清除建立索引的失敗的遺留
DECLARE
RetVal BOOLEAN;
OBJECT_ID BINARY_INTEGER;
WAIT_FOR_LOCK BINARY_INTEGER;
BEGIN
OBJECT_ID := 67420;
-- 我的資料庫中非法索引的id為67420.
WAIT_FOR_LOCK := NULL;
RetVal := SYS.DBMS_REPAIR.ONLINE_INDEX_CLEAN ();
COMMIT;
END;
/
注意:dbms_repair.online_index_clean這個函式一定要有返回值,否則會失敗的
解決二:(這種方法沒測試成功)
喚醒SMON:
WAKEUP command :To wake up a process use
ORADEBUG WAKEUP pid
For example to wake up SMON, first obtain the PID using
SELECT pid FROM v$process
WHERE addr =
(
SELECT paddr FROM v$bgprocess
WHERE name = 'SMON'
);
If the PID is 6 then send a wakeup call using
sql > ORADEBUG WAKEUP 6
記錄一下SMON的功能及其觸發頻率(9i):
Merging free extents or coalescing: every five minutes.
Cleaning up temporary segments: every two hours.
Updating SMON_SCN_TIME for used in time based flashback: every five minutes.
Cleaning up non existent objects in OBJ$: every 12 hours.
Cleaning up IND$ if online builder crashes: every hour.
Shrink undo segments:every 12 hours.
Transaction recovery only on startup.
Transaction rollback of dead transaction when posted by PMON, allowing the use of fast start parallel rollback if necessary.
解決方法三:
由於在做索引線上重建的時候,可能相關的表還在變化,Oracle需要記錄這個索引的相關變化,因此Oracle會建立一張臨時表來記錄這些變化,等索引重建完成後再刪除這張臨時表,這張臨時表的名字為SYS_JOURNAL_。REBUILD ONLINE剛剛開始的時候就會去建立這張日誌表,但是如果建立日誌表的時候,發現這張表已經存在了,就可能會報ORA-8104,並無法繼續做REBUILD ONLIE(普通的REBUILD會檢查索引的FLAG標誌和這張表,如果衝突,也會失敗)。如果REBUILD ONLINE被中途殺掉了,那麼這張表和IND$中的FLAGS不會被自動清除,必須由SMON來清除。而SMON每個小時會進行一次類似的清除工作,SMON做清除前首先要鎖住日誌表,如果這個索引相關的表還在變化,那麼SMON可能無法鎖住這張表,如果SMON鎖表失敗,就會放棄這次清理工作,等一個小時後再來清理。這樣一來,在業務較為繁忙的生產系統上,可能SMON永遠都沒有機會清除這張日誌表。
如果是9i的資料庫就很麻煩了,如果系統smon程式無法清除,或者重啟資料庫也無法解決,那只有手工清除了日誌表,並且修改索引的FLAGS。手工解決這個問題分為兩個步驟:
1、手工刪除日誌表:
首先找到這個索引的OBJECT_ID:
Select object_id from dba_objects where wner= and object_name=;
找到OBJECT_ID後,就可以知道表的名字了(SYS_JOURNAL_),直接DROP這張表。不過如果這張表上的DML比較頻繁,DROP操作可能不會一次成功,需要不停的重試。
2、手工修改IND$:
UPDATE IND$ SET FLAGS=FLAGS-512 WHERE OBJ#=;
手工清理要十分小心,一旦出錯會導致資料字典錯誤。
解決方法四:
還有一種穩妥的辦法是把應用停了,然後重啟資料庫,這樣相關表上沒有了DML操作,很快SMON就會完成自動清理。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22531473/viewspace-743458/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ADG 例項異常終止故障分析報告
- create index .. onlineIndex
- SpringBoot專案中遇到的異常Spring Boot
- 異常處理遇到過的那些坑
- 異源資料同步 → DataX 同步啟動後如何手動終止?
- 你可以終止 forEach 嗎?
- 終止非同步任務非同步
- 正常終止expdp作業
- CentOS 將於年底終止!CentOS
- 終止指定埠的程式
- 兩階段終止模式模式
- 華為無線AP終端異常掉線
- Windows 程式的建立和終止Windows
- AngularJS終止了長期支援AngularJS
- Docker 容器優雅終止方案Docker
- 3.6 延遲例項終止
- response()->download();下載中途終止
- Thread執行緒終止interruptthread執行緒
- oracle ORA-08104處理Oracle
- 學妹問我:我遇到了OutOfMemoryError異常怎麼辦?Error
- 自定義SPI使用JDK動態代理遇到UndeclaredThrowableException異常排查JDKException
- flash中呼叫XML遇到的中文顯示異常問題XML
- Activiti7 結束/終止流程
- Go的優雅終止姿勢Go
- Linux 下使用 killall 命令終止程式Linux
- 異常和異常呼叫鏈
- 異常篇——異常記錄
- 異常篇——異常處理
- Java 異常(二) 自定義異常Java
- 異常-異常的注意事項
- oracle expdp後臺終止或者暫停Oracle
- Java之 join 等待執行緒終止Java執行緒
- 異常-編譯期異常和執行期異常的區別編譯
- 異常?
- 異常
- hibernate異常之--count查詢異常
- 異常-異常的概述和分類
- 異常-throws的方式處理異常
- 兩種異常(CPU異常、使用者模擬異常)的收集