1. 程式人生 > 其它 >隻言片語分析datapump的工作原理(r2第18天)

隻言片語分析datapump的工作原理(r2第18天)

datapump是從oracle 10g推出的新的資料匯入匯出工具,可以說是exp/imp的加強版,主要的亮點在於服務端,結合了direct+parallel,而且從datapump的結構上來說也和exp/imp有很大的差別。而老式的exp/imp還有一套自己的資料字典表需要維護,習慣了exp/imp,突然切換到expdp/impdp還有是一些牴觸情緒的,因為從之前的感觸中沒有感受到datapump的強大,從公司的team的反饋,產品線中也遇到了不少的bug.但是很多東西你熟悉了了解了,就會明白oracle設計它的一些原因和出發點,有些小的問題也是可以接受的。 datapump官方沒有提供很多Internal的東西,都只限於操作層面。以下內容都基於個人理解,歡迎拍磚。 一般來說在資料的匯入過程中,oracle會建立3個臨時的表,之前在排查Impdp臨時中斷的問題中注意到了這個細節,但是如何把他們關聯一直沒有頭緒。http://blog.itpub.net/23718752/viewspace-1189257/ IMPORT的表類似下面的形式

SYS_IMPORT_TABLE_28 ERR的表類似下面的形式。 ERR$DP13FC20810001

ET的表類似下面的形式。 ET$1B5C6DCF0001 如果嘗試訪問這些表,會馬上丟擲ora錯誤,可以看出這些臨時表是基於external table的形式,而且是不對外訪問的,在資料匯入完成之後就會自動清空。 SQL> select *from ET$1B5C6DCF0001; ERROR: ORA-29913: error in executing ODCIEXTTABLEOPEN callout KUP-11024: This external table can only be accessed from within a Data Pump job.

而且impdp相對Imp有一個特別的優點就是可以隨時檢視匯入的進度。使用Impdp xxxx attach=SYS_IMPORT_TABLE_28 的形式就可以檢視匯入的資料量,匯入的進度。這些情況基本都是基於SYS_IMPORT_TABLE_28 表來讀取的資訊,它基本就是一個控制表。 而ET,ERR的表是怎麼關聯的呢,知道有一天我檢視一個性能問題的時候,從awr的日誌中發現瞭如下的一段內容,關於datapump的。

Elapsed Time (s)

Executions

Elapsed Time per Exec (s)

%Total

%CPU

%IO

SQL Id

SQL Module

SQL Text

3,553.36

0

1.01

35.03

10.32

6cz7m51m82vqg

Data Pump Worker

INSERT /*+ PARALLEL("MO1_MEMO"...

相關的sql如下:

6cz7m51m82vqg

INSERT /*+ PARALLEL("TEST_MEMO", 1)+*/ INTO RELATIONAL("APPO"."TEST_MEMO" NOT XMLTYPE) ("APP_ID", "ENTITY_KEY", "PERIOD_KEY", "MEMO_ID", "SYS_CREATION_DATE", "SYS_UPDATE_DATE",xxxxxxxx, "ATTR10VALUE", "CLOB_IND", "MEMO_SYSTEM_TEXT_C") SELECT "APP_ID", "ENTITY_KEY", "PERIOD_KEY", "MEMO_ID", "SYS_CREATION_DATE", "SYS_UPDATE_DATE", xxxxxxxx, "ATTR10VALUE", "CLOB_IND", "MEMO_SYSTEM_TEXT_C" FROM "ET$111D05F70001" KU$ LOG ERRORS INTO "APPO"."ERR$DP111D05F70001" REJECT LIMIT UNLIMITED

可以很清楚的發現原來datapump內部在做這樣的操作 使用Insert select的方式做資料的插入。幾種ET的表是作為中間的資料快取表,而ERR的表則是完全基於oracle的新版本特性,啟用了錯誤日誌。 有了這些資訊也就明白,datapump在資料有衝突的情況下是怎麼快取那些資訊的。這些資訊都被放入了ERR的表中。

Rejected row #1043:

column APP_ID: 1000 column ENTITY_KEY: 1 column PERIOD_KEY: 2 column MEMO_ID: 34141901

可能仔細檢視上面的sql語句發現insert select可能不是最好的方式,為什麼不適用insert /*+append*/ select的方式呢,你可以簡單做一個測試就會發現,其實在資料的插入中如果啟用錯誤日誌,再啟用append模式是衝突的。參見:http://blog.itpub.net/23718752/viewspace-1190545/ 上面的例子中我匯入資料的表中還有CLOB欄位,儘管在Impdp中指定了parallel,但是在實際的插入中還是並行度為1. 所以基於以上資訊,可以發現parallel的情況也是根據資料的情況來制定的,append的方式在某些情況下速度可能更快,可以根據自己的需要來選擇,甚至手工來完成。