Table of Contents
1 注意事項
- 檢查數據庫版本(用於決定導出時生成為哪個版本的dmp頭文件) select version from v$instance; 也可以用sqlplus -v 查看。
- 檢查字符集是否一致(字符集不一致,不能導入) select userenv('language') from dual;
- 檢查數據量及磁盤空間(決定采取什么樣的方式導出及導入)
2 前期准備
2.1 創建目錄
create directory DUMP_DIR as '&PATH'; grant read,write on directory dump_dir to &oper_user;
2.2 檢查字符集
確保兩端字符集是一致的。不然數據導入后會出現亂碼。當然這在安裝數據庫的時候就應該考慮到。
select userenv('language') from dual; USERENV('LANGUAGE') ---------------------------------------------------- AMERICAN_AMERICA.ZHS16GBK
經檢查兩端一致。
2.3 ASM磁盤組空間
-
查看原庫數據文件大小
SQL> elect sum(bytes)/(1024*1024*1024) from dba_data_files; SUM(BYTES)/(1024*1024*1024) --------------------------- 2529.21808
當然這里面包含了system,sysaux,undo,temp,users 等。所以只要滿足這個空間大小,就可以滿足業務數據所需要的空間。
-
擴展ASM磁盤組 grid 用戶通過asmca 添加 asm 磁盤。
asmca -adddisk -diskGroupName DATA -diskList /dev/mapper/asm-data10,/dev/mapper/asm-data15,/dev/mapper/asm-data20,/dev/mapper/asm-data25,/dev/mapper/asm-data30 -sysAsmPassword Sys123ora -silent
-
檢查磁盤組狀態
col name for a12 col path for a25 set lines 32767 pages 500 select name,path,group_number,disk_number,header_status,mount_status,mode_status,state,total_mb,free_mb from v$asm_disk order by 1 nulls first; select group_number,name,state,type,total_mb,free_mb,offline_disks from v$asm_diskgroup;
執行結果如下:
....... 內容過多,省略 ........ ARCH_0000 /dev/mapper/asm-data3 4 0 MEMBER CACHED ONLINE NORMAL 512078 511972 DATA_0000 /dev/mapper/asm-data2 3 0 MEMBER CACHED ONLINE NORMAL 512078 512046 DATA_0001 /dev/mapper/asm-data10 3 1 MEMBER CACHED ONLINE NORMAL 512078 512053 DATA_0002 /dev/mapper/asm-data15 3 2 MEMBER CACHED ONLINE NORMAL 512078 512053 DATA_0003 /dev/mapper/asm-data20 3 3 MEMBER CACHED ONLINE NORMAL 512078 512054 DATA_0004 /dev/mapper/asm-data25 3 4 MEMBER CACHED ONLINE NORMAL 614478 614449 DATA_0005 /dev/mapper/asm-data30 3 5 MEMBER CACHED ONLINE NORMAL 614478 614448 MGMT_0000 /dev/mapper/asm-data1 1 0 MEMBER CACHED ONLINE NORMAL 512076 478248 OCR_0000 /dev/mapper/asm-ocr2 2 0 MEMBER CACHED ONLINE NORMAL 10240 9948 OCR_0001 /dev/mapper/asm-ocr1 2 1 MEMBER CACHED ONLINE NORMAL 10240 9952 OCR_0002 /dev/mapper/asm-ocr3 2 2 MEMBER CACHED ONLINE NORMAL 10240 9952 SYSTEM_0000 /dev/mapper/asm-data4 5 0 MEMBER CACHED ONLINE NORMAL 512076 508780 48 rows selected. SQL> GROUP_NUMBER NAME STATE TYPE TOTAL_MB FREE_MB OFFLINE_DISKS ------------ ------------ ----------- ------ ---------- ---------- ------------- 1 MGMT MOUNTED EXTERN 512076 478248 0 2 OCR MOUNTED NORMAL 30720 29852 0 4 ARCH MOUNTED EXTERN 512078 511972 0 5 SYSTEM MOUNTED EXTERN 512076 508780 0 3 DATA MOUNTED EXTERN 3277268 3277103 0
磁盤大小,磁盤、磁盤組的狀態也都正常。
2.4 在目標庫中創建表空間
2.4.1 11G及之前
原庫查詢表空間信息
select tablespace_name, file_name,(bytes/(1024*1024*1024)) as file_size,autoextensible from dba_data_files order by tablespace_name; -- 或者通過以下語句直接生成創建表空間語句 select decode(row_number() over(partition by tablespace_name order by tablespace_name), 1, 'create tablespace ' || rpad(tablespace_name, first_value(length(tablespace_name)) over ( order by length(tablespace_name) desc )+5, ' '), 'alter tablespace ' || rpad(tablespace_name, first_value(length(tablespace_name)) over ( order by length(tablespace_name) desc), ' ') || ' add ') || rpad(' datafile ''&file_path' || lower(tablespace_name) || '_' ||row_number() over(partition by tablespace_name order by tablespace_name) || '.dbf''', length(' datafile ''&file_path'||'_'||'.dbf''')+ first_value(length(tablespace_name)) over ( order by length(tablespace_name)desc )+5,' ') || --' size '||decode(ceil(bytes/(1024*1024*1024)),32,31,ceil(bytes/(1024*1024*1024)))||'G autoextend on;'*/ ' size 1G autoextend on;' from dba_data_files where tablespace_name not in ('SYSTEM', 'SYSAUX', 'TEMP', 'UNDOTBS2', 'USERS') order by tablespace_name;
上面語句會直接生成目標庫的創建表空間和添加數據文件的語句。直接在目標庫執行。
添加完表空間后, 對比兩側表空間總量是否滿足數據遷移條件:
set lines 32767 pages 5000 select tablespace_name,sum(bytes)/(1024*1024*1024) as size_gb from dba_data_files where tablespace_name not in ('SYSTEM','SYSAUX','USERS') AND tablespace_name not like 'UNDO%' AND tablespace_name NOT LIKE 'TEMP%' group by tablespace_name order by 1;
2.4.2 12C
12C 在數據泵導出時,是可以將表空間的元數據一起導出來的,因此不再需要我們手動去目標庫創建。 但是12C 導出表信息時,會完全按照原庫的表空間大小導出,如果我們不需要全部數據,那么表空間 就沒有必要創建那么大。最好還是自己手動創建一下。
2.5 目標庫創建用戶
select dbms_metadata.get_ddl('USER',username) from dba_users where
3 常用參數及示例
-
ATTACH
作用 當我們使用ctrl+C 退出交互式命令時,可心使用attach參數重新進入到交互模式 語法 ATTACH=[schema_name.]job_name Schema_name用戶名,job_name任務名 示例 Expdp scott/tiger ATTACH=scott.export_job
-
CONTENT
作用 限制了導出的內容,包括三個級別:全部/數據/元數據(結構) 語法 CONTENT={ALL | DATA_ONLY | METADATA_ONLY} ALL -- 導出所有數據,包括元數據及數據 DATA_ONLY -- 只導出數據 METADATA_ONLY -- 只包含元數據 示例 Expdp scott/tiger DIRECTORY=dump DUMPFILE=a.dump CONTENT=METADATA_ONLY
-
DIRECTORY
作用 此路徑可以理解為實際絕對路徑在oracle數據庫里的別名,是導出文件的存儲位置 路徑的創建: create directory &DIRECTORY_NAME AS '&PATH'; 查看已存在路徑: select * from dba_directories; 語法 directory=[directory_name] 示例 Expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=lhb.dump
-
DUMPFILE
作用 此參數用戶命名導出文件,默認是 expdat.dmp. 文件的存儲位置如果在文件名前沒有指定directory,則會默認存儲到directory參數指定的路徑下。 語法 DUMPFILE=[dump_dir:]file_name 示例 Expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=dump_dir1:a.dmp
-
ESTIMATE
在使用Expdp進行導出時,Expdp需要計算導出數據大小容量,Oracle可以通過兩種方式進行容量估算,一種是通過數據塊(blocks)數量、一種是通過統計信息中記錄的內容(statistics)估算. 語法結構: EXTIMATE={BLOCKS | STATISTICS} 示例: Expdp scott/tiger TABLES=emp ESTIMATE=STATISTICS DIRECTORY=dump_dir DUMPFILE=halberd.dump Expdp scott/tiger TABLES=emp ESTIMATE=BLOCKS DIRECTORY=dump_dir DUMPFILE=halberd.dump
-
EXTIMATE_ONLY
作用 此參數用於統計導出的數據量大小及統計過程耗時長短。 語法 EXTIMATE_ONLY={Y | N} 示例 Expdp scott/tiger ESTIMATE_ONLY=y NOLOGFILE=y directory=dump_dir schemas=halberd
-
EXCLUDE
作用 此參數用於排除不需要導出的內容,如我們進行全庫導出,但是不需要導出用戶scott,此時需要在exlude后先指定排除類型為schema,再指定具體的schema。具體使用方法見include參數. EXCLUDE與include的使用方法是一樣的 語法 EXCLUDE=object_type[:name_clause] [,object_type[:name_clause] ] name_clause "='object_name'" "in ('object_name'[,'object_name',....])" "in (select_clause) " Object_type對象類型,如:table,view,procedure,schema等 name_clause指定名稱的語句,如果不具體指定是哪個對象,則此類所有對象都不導出, select 語句中表名不要加用戶名。用戶名,通過schemas 指定。 示例 expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd.dup EXCLUDE=VIEW expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd.dup EXCLUDE=TABLE:\" IN\(\'TEMP\',\'GRADE\'\)\" EXCLUDE=TABLE:"='APPLICATION_AUDIT'"
-
FILESIZE
作用 用於指定單個導出的數據文件的最大值,與%U一起使用。比如,我們需要導出100G的數據,文件全部存儲到一個文件內,在文件傳輸時,會耗費大量的時間,此時我們就可以使用這個參數,限制每個文件的大小,在傳輸導出文件時,就可以多個文件同時傳送,大大的節省了文件傳輸時間。提高了工作的效率。 語法 FILESIZE=integer[B | K | M | G] 示例 Expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd%U.dup FILESIZE=20g
-
FLASHBACK_SCN/FLASHBACK_TIME
作用 基於undo 及scn號(時間點)進行的數據導出。使用此參數設置會進行flashback query的功能,查詢到對應指定的SCN時的數據,然后進行導出。只要UNDO不被覆蓋,無論數據庫是否重啟,都可以進行導出. flashback_time參數與flashback_scn的原理是一樣的。在導出的數據里保持數據的一致性是很有必要的。這個。。我想,沒誰傻忽忽的把這兩個參數一起使用吧?所以我就不提醒你兩個參數不可以同時使用了。 語法 FLASHBACK_SCN=scn_value FLASHBACK_TIME 有多種設定值的格式: flashback_time=to_timestamp (localtimestamp) flashback_time=to_timestamp_tz (systimestamp) flashback_time="TO_TIMESTAMP (""25-08-2003 14:35:00"", ""DD-MM-YYYY HH24:MI:SS"")" 使用此格式可能會遇到ORA-39150錯誤。 示例 Expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd.dmp FLASHBACK_SCN= 12345567789 Expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd.dmp FLASHBACK_TIME= to_timestamp (localtimestamp)
-
FULL
作用 指定導出內容為全庫導出。這里需要特別注意的是,expdp 不能導出sys用戶對象。即使是全庫導出也不包含sys用戶。 語法 FULL={Y | N} 示例 expdp \'\/ as sysdba\' directory=dump_dir full=y
-
HELP
作用 當我們對參數的意義不了解時,或者忘記參數怎么寫時,就可以用這個參數,來尋求幫助,實際上和操作系統里的man命令是一樣的。 示例 impdp -help expdp help=y
-
INCLUDE
作用 限制范圍,指定自己想要的內容,比如要導出某個用戶的某張表。 語法 INCLUDE = object_type[:name_clause],object_type[:name_clause] 示例 impdp dbmon/dbmon_123 directory=dump_dir network_link=zjzwb2 SCHEMAS=AICBS remap_schema=aicbs:aicbsb include=table:\"IN\(SELECT TABLE_NAME FROM dbmon.TABLES_TOBE_MASKED\)\" LOGFILE=zjzwb.log transform=segment_attributes:n PARFILE中設置: INCLUDE=table:"in(select table_name from dba_tables where owner='AA')" INCLUDE=TABLE:"IN('TEST1','TEST2')" include=table:"like 'SEC#_%'escape'#'" 在include、exclude參數中,在escape語句中,不能用\作為轉義符!可以選用選用其他特 殊字符作為轉義符。如果確實要用\,也要可以用ascii碼代替: include=table:"like 'SEC\_%'escape chr(92)" . SHELL環境設置: INCLUDE=TABLE:\"IN\(SELECT TABLE_NAME FROM DBA_TABLES WHERE OWNER=\'AA\'\)\" INCLUDE=TABLE:\"IN\(\'TEST1\',\'TEST2\'\)\" 說明 當導入命令在目標端發起時,select 子句所涉及的表要在源端,並且dblink 所使用的用戶有訪問的權限。
-
JOB_NAME
作用 指定任務名,如果不指定的話,系統會默認自動命名:SYS_EXPORT_mode_nn 語法 JOB_NAME=&JOB_NAME 其他 查看有哪些expdp/impdp job,可以通過dba_datapump_jobs查看,其實你通過v$session.action也可以查看到 大多與attach參數一起使用,重新進行expdp交互命令時使用。
-
LOGFILE
作用: 指定導出日志名稱。默認是:expdp.log 語法 LOGFILE=[DIRECTORY:]file_name , 如果參數值里沒有指定路徑,會默認使用directory參數值所指向的路徑。 directory : 存儲路徑, file_name :日志文件名 示例 expdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd.dmp logfile=halberd.log impdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd.dmp logfile=halberd.log
-
NETWORK_LINK
作用 此參數只有在導入(impdp)時使用,可通過本地數據庫里的db_link連接到其他數據庫A,將數據庫A的數據直接導入到本地數據庫。中間可節省導出數據文件,傳送數據文件的過程。很方便。 語法 network_link=[db_link] 示例 impdp scott/tiger DIRECTORY=dump_dir DUMPFILE=halberd.dmp NETWORK_LINK=to_tjj SCHEMAS=halberd logfile=halberd.log
-
NOLOGFILE
作用 不寫導入導出日志,這個筆者是灰常灰常滴不建議設置為“Y”滴。 語法 nologfile=[y|n]
-
PARALLEL
作用 指定導出/導入時使用多少個並發,默認是1. 語法 parallel=[digit] 示例 expdp \'\/ as sysdba\' directory=dump_dir schemas=halberd dumpfile=halberd%U.dmp parallel=8 logfile=halberd.log
- NOTE1
-
這里需要特別注意的是,在RAC環境中使用parallel大於1時,需要將directory 設置為共享路徑,或者加上參數cluster=n.否則會報錯類似如下:
ORA-31693: Table data object "owner"."table_name" failed to load/unload and is being skipped due to error: ORA-31617: unable to open dump file "file_name" for write ORA-19505: failed to identify file "file_name" ORA-27037: unable to obtain file status IBM AIX RISC System/6000 Error: 2: No such file or directory Additional information: 3
- NOTE2
-
並行數隨意指定,或者達不到預期效果,或者對數據庫產生影響。 為parallel 設置一個合適的值,需要從另外兩點入手:
- db_writer_processes 該參數限制了最張可開啟的最大寫進程數
- dumpfile參數應使用xxx%U.dmp 這種用法,使每個進程都有文件可寫,避免多個進程同時寫一個文件的情況(ORA-39095)
-
PARFILE
作用 參數文件,這個參數文件里,存儲着一些參數的設置。比如上面說過的,parallel,network_link,等。導出時,可以使用此參數,expdp/impdp會自動讀取文件中的參數設置,進行操作。 語法 PARFILE=[directory_path] file_name 示例 expdp \'\/ as sysdba\' parfile=halberd.par cat halberd.par directory=dump_dir logfile=test.log schemas=test query="where create_date > last_day(add_months(sysdate,-1)) and create_date <= last_day(sysdate)" transform=segment_attributes:n network_link=to_aibcrm table_exists_action=append impdp \'\/ as sysdba\' parfile=test.par
-
QUERY
作用 此參數指定在導入導出時的限制條件,和SQL語句中的 "where" 語句是一樣兒一樣兒滴 語法 QUERY=([schema.] [table_name:] query_clause, [schema.] [table_name:] query_clause,……) CONTENT=METADATA_ONLY, EXTIMATE_ONLY=Y,TRANSPORT_TABLESPACES. 示例 Expdp scott/tiger directory=dump dumpfiel=a.dmp Tables=emp query="WHERE deptno<>20"
-
SCHEMAS
作用 指定導出/導入哪個用戶 語法 schemas=schema_name[,schemaname,....] 示例 expdp \'\/ as sysdba\' directory=dump_dir schemas=halberd
- REMAP_SCHEMA
只在導入時使用 作用 當把用戶A的對象導入到用戶(其實應該叫schema,將就看吧)B時,使用此參數,可實現要求 格式 remap_schema=schema1: schema2 示例 impdp \'\/ as sysdba\' directory=dump_dir dumpfile=halberd.dmp logfile=halberd.log remap_schema=scott:halberd
- TABLES
作用 指定導出哪些表。 格式 TABLES=[schema.]table_name[:partition_name][,[schema.]table_name[:partition_name]] 說明 Schema 表的所有者;table_name表名;partition_name分區名.可以同時導出不同用戶的不同的表 示例 expdp \'\/ as sysdba\' directory=dump_dir tables=emp.emp_no,emp.dept
- TABLESPACES
作用 指定導出/導入哪個表空間。 語法 tablespaces=tablespace_name[,tablespace_name,....] 示例 expdp \'\/ as sysdba\' directory=dump_dir tablespace=user
- REMAP_TABLESPACE
作用 只有在導入時使用,用於進行數據的表空間遷移。 把前一個表空間中的對象導入到冒號后面的表空間 用法 remap_tablespace=a:b 說明 a: 數據所在的原表空間; b: 目標表空間 示例 impdp \'\/ as sysdba\' directory=dump_dir tables=emp.dept remap_tablespace=user:user1
- TRANSPORT_FULL_CHECK
檢查需要進行傳輸的表空間與其他不需要傳輸的表空間之間的信賴關系,默認為N。當設置為“Y”時,會對表空間之間的信賴關系進行檢查,如A(索引表空間)信賴於B(表數據表空間),那么傳輸A而不傳輸B,則會出錯,相反則不會報錯。
- TRANSPORT_TABLESPACES
作用 列出需要進行數據傳輸的表空間 格式 TRANSPORT_TABLESPACES=tablespace1[,tablespace2,.............]
- TRANSFORM
作用 此參數只在導入時使用,是一個用於設定存儲相關的參數,有時候也是相當方便的。假如數據對應的表空間都存在的話,就根本用不到這個參數,但是,假如數據存儲的表空間不存在,使用此參數導入到用戶默認表空間就可以了。更靈活的,可以使用remap_tablespace參數來指定。 格式 transform=transform_name:value[bject_type] transform_name = [OID | PCTSPACE | SEGMENT_ATTRIBUTES | STORAGE]:[Y|N] segment attributes:段屬性包括物理屬性、存儲屬性、表空間和日志,Y 值按照導出時的存儲屬性導入,N時按照用戶、表的默認屬性導入 storage:默認為Y,只取對象的存儲屬性作為導入作業的一部分 oid: owner_id,如果指定oid=Y(默認),則在導入過程中將分配一個新的oid給對象表,這個參數我們基本不用管。 pctspace:通過提供一個正數作為該轉換的值,可以增加對象的分配尺寸,並且數據文件尺寸等於pctspace的值(按百分比) 示例 transform=segment_attributes:n --表示將用戶所有對象創建到用戶默認表空間,而不再考慮原來的存儲屬性。
- VERSION
此參數主要在跨版本之間進行導數據時使用,更具體一點,是在從高版本數據庫導入到低版本數據庫時使用,從低版本導入到高版本,這個參數是不可用的。默認值是:compatible。此參數基本在導出時使用,導入時基本不可用。 VERSION={COMPATIBLE | LATEST | version_string} COMPATIBLE : 以參數compatible的值為准,可以通過show parameter 查看compatible參數的值 LATEST : 以數據庫版本為准 version_string : 指定版本。如: version=10.2.0.1
- SAMPLE
SAMPLE 給出導出表數據的百分比,參數值可以取.000001~100(不包括100)。不過導出過程不會和這里給出的百分比一樣精確,是一個近似值。 格式: SAMPLE=[[schema_name.]table_name:]sample_percent 示例: SAMPLE="HR"."EMPLOYEES":50
- table_exists_action
此參數只在導入時使用。 作用:導入時,假如目標庫中已存在對應的表,對於這種情況,提供三種不同的處理方式:append,truncate,skip,replace 格式: table_exists_action=[append | replace| skip |truncate] 說明: append : 追加數據到表中 truncate: 將目標庫中的同名表的數據truncate掉。 skip : 遇到同名表,則跳過,不進行處理,注意:使用此參數值時,與該表相關的所有操作都會skip掉。 replace: 導入過程中,遇到同名表,則替換到目標庫的那張表(先drop,再創建)。 示例: table_exists_action=replace
- SQLFILE
只在導入時使用! 作用: 使用此參數時,主要是將DMP文件中的metadata語句取出到一個單獨的SQLfile中,而數據並不導入到數據庫中 格式: sqlfile=&file_name.sql 示例: impdp \'\/ as sysdba\' directory=dump_dir dumpfile=halberd.dmp logfile=halberd.log sqlfile=halberd.sql
- legacy mode
-
在11g中,才有這種模式。這種模式里兼容了以前版本中的部分參數,如:consistent,reuse_dumpfiles等(其實我現在也就知道這兩個參數,哈哈,以后再遇到再補充)
- consistent
這個是保持數據一致性的一個參數。在11g中使用時,如果設置 consistent=true,則會默認轉換成 flashback_time參數,時間設置為命令開始執行的那個時間點。 格式: consistent=[true|false]
- reuse_dumpfiles
作用:重用導出的dmp文件 。假如第一次我們導失敗了,雖然導出失敗,但是dmp文件 還 是會生成的。在修改導出命令,第二次執行時,就可以 加上這個參數。 格式: reuse_dumpfile=[true|false]
- partition_options
1 NONE 不對分區做特殊處理。在系統上的分區表一樣創建。 2 DEPARTITION 每個分區表和子分區表作為一個獨立的表創建,名字使用表和分區(子分區)名字的組合。 3 MERGE 將所有分區合並到一個表 注意:如果導出時使用了TRANSPORTABLE參數,這里就不能使用NONE和MERGE
4 常用語句示例
- expdp導出
1)導出表 expdp tables=dbmon.lihaibo_exp dumpfile=sms.dmp DIRECTORY=dump_dir; 2)並發導出parallel,指定job名 我們需要特別注意一點,parallel 一定要與 dumpfile=...%U.dmp結合 使用,或者有多個表需要同時導出。單表,或者其他諸如network_link方式,指定parallel,也無法開啟並發進程 expdp scott/tiger@orcl directory=dpdata1 dumpfile=scott3%U.dmp parallel=4 job_name=scott3 3)全表 expdp scott/tiger@orcl TABLES=emp,dept dumpfile=expdp.dmp DIRECTORY=dpdata1; 4)導出表,並指定表中的內容 expdp scott/tiger@orcl directory=dpdata1 dumpfile=expdp.dmp Tables=emp query="WHERE deptno=20"; 5)導出表空間 expdp system/manager DIRECTORY=dpdata1 DUMPFILE=tablespace.dmp TABLESPACES=temp,example; 6)導出全庫 expdp system/manager DIRECTORY=dpdata1 DUMPFILE=full.dmp FULL=y;
- impdp導入
1) 全用戶導入 impdp scott/tiger DIRECTORY=dpdata1 DUMPFILE=expdp.dmp SCHEMAS=scott; 2) 用戶對象遷移 impdp system/manager DIRECTORY=dump_dir DUMPFILE=expdp.dmp TABLES=scott.dept REMAP_SCHEMA=scott:system; (SCOTT為原用戶,system為目標用戶) 3) 導入指定表空間 impdp system/manager DIRECTORY=dump_dir DUMPFILE=tablespace.dmp TABLESPACES=example; 4) 全庫導入 impdb system/manager DIRECTORY=dump_dir DUMPFILE=full.dmp FULL=y; 5) 表已存在的處理 impdp system/manager DIRECTORY=dump_dir DUMPFILE=expdp.dmp SCHEMAS=system TABLE_EXISTS_ACTION=append; 6) 表空間遷移 impdp system/manager directory=dump_dir dumpfile=remap_tablespace.dmp logfile=remap_tablespace.log remap_tablespace=A:B (A為原表空間名,B為指定的目標表空間名)
5 交互式命令
- 連接到對應的job impdp \'\/ as sysdba\' attach=&job_name 不知道job_name 去哪兒找?看上面的參數:job_name
- 查看運行狀態: status
- 停止導入導出: kill_job(直接kill 掉進程,不自動退出交互模式)
- 停止導入導出:stop_job(逐一停止job進程的運行,並退出交互模式)
- 修改並發值: parallel
- 退出交互模式: exit / exit_client(退出到日志模式,對job無影響)
6 技巧
6.1 不生成文件直接導入目標數據庫
在一些情況下,我們並沒有足夠的存儲空間允許我們存儲導出的dmp文件。這個時候,我們就無計可施了么? 不是的。我們可以不生成dmp文件,直接將數據抽取到目標數據。在遷移大量數據而沒有充足存儲空間時,這是一個救命稻草。 最關鍵的點就是在目標端執行impdp的時候,使用network_link,直接從源庫抽取數據。 有兩點,我一直心存疑問和不確定,今天終於想明白了:
- 配置表應該配置在源端
- network_link 指向源端
示例如下:
cat test.par directory=dump_dir logfile=test.log schemas=test query="where create_date > last_day(add_months(sysdate,-1)) and create_date <= last_day(sysdate)" transform=segment_attributes:n network_link=to_aibcrm table_exists_action=append impdp \'\/ as sysdba\' parfile=test.par
6.2 通過shell腳本自動導入
此處只關注,impdp 命令在shell腳本中執行,需要轉義的地方。
cat import_sr.sh #!/bin/sh cd /u01/app for da in 2012-10 2013-09 2013-08 2013-07 2013-06 2013-05 2013-04 2013-03 2013-02 2013-01 2012-12 2012-11 2014-08 2014-07 2014-06 2014-05 2014-04 2014-03 2014-02 2014-01 2013-12 2013-11 2013-10 2015-07 2015-06 2015-05 2015-04 2015-03 2015-02 2015-01 2014-12 2014-11 2014-10 2014-09 2016-06 2016-05 2016-04 2016-03 2016-02 2016-01 2015-12 2015-11 2015-10 2015-09 2015-08 2017-05 2017-04 2017-03 2017-02 2017-01 2016-12 2016-11 2016-10 2016-09 2016-08 2016-07; do impdp \'\/ as sysdba\' parfile=import_sr.par logfile=sr${da}.log query=\" where create_date\> last_day\(add_months\(to_date\(\'$da\',\'yyyy-mm\'\),-1\)\) and create_date \<\=last_day\(to_date\(\'$da\',\'yyyy-mm\'\)\)\" done -- 參數文件內容 directory=dump_dir tables=SR.SR_VOUCHER_FILE_tomig remap_table=sr.SR_VOUCHER_FILE_tomig:sr_his.sr_voucher_file transform=segment_attributes:n network_link=to_aibcrm table_exists_action=append
6.3 如何導出數百張表
通過命令行參數 tables=… 來指定表名是有限制的,印象里最多是四五十張表。如果單次需要處理的表名超過了這個數量,怎么辦? 就要用到現在我們說的這種方法,通過schemas 與include 來配合使用。
下面先來看下示例:
schemas=test1 include=table:"in(select table_name from tables_tobe_exported where owner='AA')"
tables_tobe_exported :: 在表里存儲需要導出的表明細,此表應創建在數據源端。 該表有兩個字段,owner, table_name分別對應表的schema與表名。
7 性能相關
7.1 wait for unread message on broadcast channel
很多次,當導入,或者導出的時候,被這個等待事件無折騰的茶不思飯不想。而每次遇到這個等待事件 邏輯備份或者遷移所消耗的時間都異常的長。比如本來1小時可以完成的任務,在這個事件的堅持下, 可以延長至五六個小時,甚至更長。
我決心要解決掉它。
7.1.1 查看數據泵發起的會話狀態
col sid for 99999 col owner for a8 col job_name for a20 col session_type for a12 col module for a17 col state for a8 col event for a44 col seconds_in_wait for 99999999999 col sql_text for a60 select a.inst_id,a.owner_name as owner,a.job_name,a.session_type,s.sid, s.module, s.state, s.event, s.seconds_in_wait ,substr(sql.sql_text,1,60) as sql_text from dba_datapump_sessions a left join gv$session s on a.inst_id = s.inst_id and a.saddr = s.saddr join gv$sql sql on sql.sql_id = s.sql_id and s.inst_id = sql.inst_id where s.module like 'Data Pump%' order by s.module, s.sid;
示例:
INST_ID OWNER JOB_NAME SESSION_TYPE SID MODULE STATE EVENT SECONDS_IN_WAIT SQL_TEXT ---------- -------- -------------------- ------------ ------ ----------------- -------- -------------------------------------------- --------------- ------------------------------------------------------------ 1 SYS SYS_IMPORT_SCHEMA_03 MASTER 79 Data Pump Master WAITING wait for unread message on broadcast channel 0 BEGIN :1 := sys.kupc$que_int.receive(:2); END; 1 SYS SYS_IMPORT_SCHEMA_03 WORKER 73 Data Pump Worker WAITING direct path write 0 CREATE INDEX "BOSS"."PK_PDSERVICEINST" ON "BOSS"."T_PDSERVIC
這里,我們看到Master的等待事件,是 waiting for unread message on broadcast channel
. 而實際的操作進程正在創建索引,等待事件是 "direct path read"。也就是說數據泵真正的等待是 在創建索引時,將數據讀取至PGA, 這個沒有什么辦法去解決。只能期待Oracle 研發可以想到優化的方法。
但是很多時候,在這里查不出真正的等待事件,或者說我們查看的時候,影響最大的等待事件並沒有顯現出來。 通常的做法是采用10046進行會話追蹤。通過tkprof工具分析trace文件,查看最關鍵的根源給了我們什么 提示。
7.1.2 追蹤數據泵會話
- 10046
一般采用10046追蹤即可。
alter system set events ‘10046 trace name context forever, level 12’; -- 開始執行導入或者導出工作 ALTER SYSTEM SET events ‘10046 trace name context off’;
執行完后,查找最新的 <DB_NAME>_dmnn_<spid>.trc <db_name>_dwnn_<spid>.trc .
- **
- 查找trace文件
先來認識下trace文件的格式:
- Data Pump Master Control Process (MCP).
Format : <SID>_dm<number>_<process_id>.trc Example: ORCL_dm00_2896.trc or: ORCL_dm01_3422.trc (for second active Master Control Process) Location: BACKGROUND_DUMP_DEST or <ADR_HOME>/trace
- Data Pump Worker Process trace file.
Format : <SID>_dw<number>_<process_id>.trc Example: ORCL_dw01_2936.trc or: ORCL_dw01_2844.trc and ORCL_dw02_2986.trc (if PARALLEL=2) Location: BACKGROUND_DUMP_DEST or <ADR_HOME>/trace
- Data Pump Shadow Process trace file.
Format : <SID>_ora_<process_id>.trc Example: ORCL_ora_3020.trc Location: USER_DUMP_DEST or <ADR_HOME>/trace
Oracle 10G 與11G 中trace文件的默認存放路徑發生了改變:
--Oracle 10G SHOW PARAMETER dump NAME TYPE VALUE ------------------------------------ ----------- ----------------------------- background_dump_dest string <background_dump_dest_location> user_dump_dest string <user_dump_dest_location> ... --Oracle 11G SHOW PARAMETER diag NAME TYPE VALUE ------------------------------------ ----------- ----------------------------- diagnostic_dest string <diagnostic_dest_location>
- NOTE
- Oracle中 如果 BACKGROUND_DUMP_DEST and/or USER_DUMP_DEST 沒有
- 分析trace文件
tkprof <trace_file> <out_file> waits=y sort=exeela
示例如下:
Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ wait for unread message on broadcast channel 698 1.00 684.41 Disk file operations I/O 2 0.00 0.00 Streams AQ: enqueue blocked on low memory 21 60.00 1201.93 db file sequential read 28 0.00 0.03 class slave wait 1 0.00 0.00 library cache: mutex X 1 0.00 0.00 direct path write 2 0.00 0.00 reliable message 20 0.00 0.00 db file scattered read 1 0.00 0.00 enq: RO - fast object reuse 9 0.01 0.03 enq: CR - block range reuse ckpt 9 0.00 0.05
在這個示例中,我們通過"Total Waited" 列可以看出,最耗時的是"Streams AQ: enqueue blocked on low memory".
在上面的示例中,我們發現了等待事件 " Streams AQ: enqueue blocked on low memory"這個等待事件是說,Steam_pool_size過小了。 也可能是個BUG。
- 針對stream_pool_size
- 原因
在stream_pool_size 上引發數據泵緩慢的原因,有可能真的是小了。
可能遇到了BUG:17365043,會導致在"Streams AQ: enqueue blocked on low memory" 上等待1分鍾。該問題在12.2.0.1中被修復。 如果按照此文檔不能修復問題,可以參考以下內容:
Note.1990633.1 –Expdp Is Very Slow After Upgrade From 11.2.0.3 To 11.2.0.4 With Wait On AQ: enqueue blocked on low memory 該文檔中的問題在BUG 18828868 中被修復,而BUG18828868 被 Bug 21286665 所取代。
- 解決方法
- 臨時解決方案 停止數據泵,重啟oracle database ,重新發起expdp/impdp命令。但是有可能根本解決不了,或者在中途再次出現。
- 調整streams_pool_size 給該參數設置一個固定的值。比如128M /256M 等。
首先查看 stream_pool 是否被調整過。
select component,current_size/1024/1024,last_oper_type,last_oper_time from v$sga_dynamic_components; COMPONENT CURRENT_SIZE/1024/1024 LAST_OPER_TYP LAST_OPER ------------------------------ ---------------------- ------------- --------- shared pool 320 GROW 24-MAY-19 large pool 32 SHRINK 22-MAY-19 java pool 16 STATIC streams pool 16 SHRINK 24-MAY-19 DEFAULT buffer cache 496 SHRINK 24-MAY-19 KEEP buffer cache 0 STATIC RECYCLE buffer cache 0 STATIC DEFAULT 2K buffer cache 0 STATIC DEFAULT 4K buffer cache 0 STATIC DEFAULT 8K buffer cache 0 STATIC DEFAULT 16K buffer cache 0 STATIC DEFAULT 32K buffer cache 0 STATIC Shared IO Pool 0 STATIC ASM Buffer Cache 0 STATIC
從上面的查詢結果 來看,shared_pool 空間不足,導致從large_pool 和streams_pool 回收了一部分內存。
我們手動把內存調整大一些。
ALTER SYSTEM SET streams_pool_size=256m SCOPE=both sid='*';
-
關閉streams pool 自動調整 如果前兩個方法不能解決問題,可以嘗試關閉streams_pool_size 自動調整功能。
alter system set “_disable_streams_pool_auto_tuning”=TRUE;
關閉隱藏參數需要重啟數據。
- 安裝補丁 Patch 24560906.
- 原因
- 數據泵trace參數
在使用數據泵的時候,可以添加TRACE參數. 默認:0480300 0490300(0480300+0010000) 可以輸出 expdp/impdp詳細內容 0690300(0490300+0200000) 可以輸出 隊列服務信息
示例:
expdp \'\/ as sysdba\' full=y dumpfile=full%U.dmp trace=0690300
如果發現
8 數據遷移后的對象對比
我們用數據泵遷移完數據后,總是要核對一下數據是否全部遷移過去。 一般來說,我們是針對數據對象類型進行核對,如果兩端的個數是一致的,那么基本認定 遷移是沒有問題的。
但是經常會遇到兩種特殊情況,一種是LOB對象個數對不上(一般目標庫比源庫少),一種是索引個數對不上。很多 時間目標端比源庫還多。
針對索引,由於一些字段特別是LOB字段,Oracle會自建索引,索引名自動命名(這種類型的索引由Oracle 自動維護,不做對比)。 由於索引是創建在用戶名+表名+字段名列表 上的。因此可以認為用戶名+表名+字段名列表代表了一個索引,而且是人為創建的索引。 只要這部分索引對得上,那么索引的遷移就沒有問題。
那么為了能精確核對。整理了以下腳本,用以進行數據類型核對.
- NOTE
- 在源庫執行此SQL前,先purge dba_recyclebin;
purge dba_recyclebin; select object_type,count(*) from dba_objects where owner in (owner_list) AND OBJECT_TYPE NOT LIke 'INDEX%' group by object_type union select 'INDEX',COUNT(*) FROM( select table_owner,table_name, listagg(column_name,',') within group( order by column_position) from dba_ind_columns@tooldqa01 where table_owner in (owner_list) group by table_owner,table_name);
Created: 2020-07-22 Wed 18:55