資料緊急修復之啟用錯誤日誌

kingsql發表於2014-09-11
昨晚對測試環境進行了升級,同步了部分生產的資料。整個過程比較順利,但是在最後一步啟用foreign key constraint的時候報了錯誤。
ora-02298:cannot validate(xxxx.xxxx_fk) -parent keys not found
很明顯是一部分資料沒有同步到,有一部分資料丟失了。和開發做了確認,從生產中根據條件匯出了一個dump,關聯的表有100多個,每個表裡都是根據篩選條件過濾後的部分資料,可能有一部分資料和現有環境的資料有重複。開發說在主鍵對應的資料重複的情況下,如果發生主鍵衝突,reject的資料可以忽略。只要插入沒有衝突的資料即可

這個需求也很特別,首先想到的就是直接用Imp來匯入,如果發生主鍵重複,會丟擲錯誤,然後檢視下一條記錄,直到沒有衝突的資料都插入 。

為了保險起見建立了一個臨時使用者,把資料匯入到了這個臨時使用者中。
. . importing table                    "TEST_DATA"    2810237 rows imported
. . importing table            "TEST_NAME_LINK"       8281 rows imported

然後嘗試使用如下的方式檢視是否有資料衝突,最後rollback,可以看到確實有衝突資料。
insert into              xxxx.TEST_DATA select *from               app_tmp.TEST_DATA ;
insert into                    xxxx.TEST_NAME_LINK select *from                     app_tmp.TEST_NAME_LINK ;

ORA-00001: unique constraint (XXXX.TEST_DATA_PK) violated 
ORA-00001: unique constraint (XXXX.TEST_NAME_LINK_PK) violated 

做了備份之後,然後嘗試使用Imp來插入資料,果然有很多表多丟擲很多的衝突資料錯誤。這是期望中的,但是在TEST_DATA這個表的時候,衝突資料實在太多。每一秒鐘大概能夠輸出3條錯誤記錄,錯誤如下:
IMP-00019: row rejected due to ORACLE error 1
IMP-00003: ORACLE error 1 encountered
ORA-00001: unique constraint (xxxx.TEST_DATA_PK) violated
Column 1 10000101
Column 2 22-SEP-2012:02:49:52
Column 3
Column 4 105
Column 5 TEST0042
Column 6 TEST911
Column 7 0
....
每一秒鐘大概3條記錄的樣子,結果執行了有快半個小時,還是那不停的輸出日誌,日誌都400M左右了,大小堪比dump檔案的大小了。
最後果斷取消,因為在這種情況下有一部分資料已經插入了,一部分被reject了,得保證沒有衝突的資料都插入。
最後使用錯誤日誌。
EXEC DBMS_ERRLOG.create_error_log(dml_table_name => 'NAME_DATA',SKIP_UNSUPPORTED=>true,ERR_LOG_TABLE_NAME=>'NAME_DATA_ERROR');                 
然後使用如下的語句插入,大概等了有5分鐘左右的時間,就提示插入了2萬多條記錄,是2百多萬條記錄中的1%的比例。
SQL> insert into name_data select *from app_tmp.name_data LOG ERRORS INTO NAME_DATA_ERROR('duplicate data') REJECT LIMIT UNLIMITED;
28388 rows created.
SQL> commit;

檢視錯誤日誌
select count(*)from name_data_error;裡面就是被reject的資料。
做了基本確認後,再次嘗試enable foregin key constraint就沒有問題了。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28389881/viewspace-1267557/,如需轉載,請註明出處,否則將追究法律責任。

相關文章