2012-11-01 27 views
4

最近,我們把我們的生產數據庫的實時/在線備份,通過發出以下命令:Oracle數據泵出口包括不正確的序列

expdp system/******@SID FULL=y DIRECTORY=data_pump_dir DUMPFILE=full_prod.dmp LOGFILE=full_prod_export.log JOB_NAME=prod_backup 

沒有任何錯誤,也沒有警告。

然後我們把這個轉儲和造就了一批由它開發的數據庫,由發行:

impdp system/******@SID SCHEMAS=MY_SCHEMA DIRECTORY=data_pump_dir DUMPFILE=full_prod.dmp LOGFILE=full_prod_import.log 

同樣,沒有錯誤,也沒有警告。

開發者環境設置好後,開發者啓動他們的應用程序並試圖插入一些測試數據。主要關鍵違規的前幾次嘗試失敗。經過一番挖掘,發現緩存的序列(NOCACHE序列很好)通常落後於一個或兩個值。

一個例子是我們的聯繫表中序列:

CREATE SEQUENCE REQ_CONTACT_SEQ 
START WITH 213041 
MAXVALUE 999999999999999999999999999 
MINVALUE 1 
NOCYCLE 
CACHE 20 
NOORDER; 

甲骨文顯示了213041這個序列的最後緩存值。現在,當我運行以下查詢:

SELECT MAX(id) FROM REQ_CONTACT; 

Oracle返回213042。很顯然,這個值比序列高1。

所以....我的問題是,我們是否只得到這個結果,因爲我們在生產過程中進行了數據導出 - 也就是說存在與數據庫的開放和活動連接?或者數據泵有緩存的序列有問題嗎?我們正在使用Oracle 10.2.0.4。

謝謝, Muel。

回答

5

我相信你的假設是正確的,這是因爲環境是活的並且有開放的聯繫。 過去幾年來,我一直在使用Oracle 10.2.0.4爲我們的開發機器執行相同的過程,並且必須創建一個腳本來運行生產導出的導入。 我基本上是由100增加每個問題的序列,然後設置增量值回落到1

alter sequence [sequence_name] increment by 100; 
select [sequence_name].nextval from dual; 
alter sequence [sequence_name] increment by 1; 
select [sequence_name].nextval from dual; 
commit; 

在我們的案例中,我們看到主鍵約束錯誤。隨着時間的推移,我已經向腳本添加了每個顯示PK約束錯誤的序列。

每隔一段時間,我會因新的PK約束錯誤而受到警惕,並且將不得不調整腳本並添加新的序列。

我在考慮創建一個變化,每增加序列,這將防止出現任何新的PK約束錯誤。 這不在我的頭頂,但我認爲它應該是某種LOOP DBMS語句,循環查詢中的每個值「select sequence_name from user_sequences」。

我一直覺得很奇怪,Oracle沒有辦法糾正這個問題,也沒有找到網上任何人的「簡單」解決方案。這將是一些腳本,查詢每個最大值(id)並將其與當前序列值進行比較,並將其差值遞增。

我也聽說過使用某種「狀態」變量運行expdp(導出數據泵)的方式,這會導致它在整個導出過程中保持事物的狀態。如果我找到任何東西,我會更新帖子。 在此期間,祝你好運!

編輯:要添加到expdp以維護導出數據的參數是「一致= y」 顯然,它只爲每個表單獨維護數據,所以我不確定序列值是否一致。

Oracle datapump details

+0

感謝您的有用的參考! – Muel

0

這個最好的解決辦法,就是閃回參數添加到出口。這將使您從開始導出的那一刻起保持所有數據一致。

FLASHBACK_TIME=SYSTIMESTAMP