Oracle-數據泵使用


 一、為何選擇數據泵方式

相對於exp/imp方式,數據泵(expdp/impdp)更快,且能導出空表;相對於rman、dg等方式,數據泵操作更加簡單。此外,在數據量不大、可停庫的情況下,數據泵方式是可以保證數據的完整性的。

備注:exp/imp與expdp/impdp的區別

1、exp和imp是客戶端工具程序,它們既可以在客戶端使用,也可以在服務端使用。 2、expdp和impdp是服務端的工具程序,他們只能在Oracle服務端使用,不能在客戶端使用。 3、imp只適用於exp導出的文件,不適用於expdp導出文件;impdp只適用於expdp導出的文件,而不適用於exp導出文件。 4、對於10g以上的服務器,使用exp通常不能導出0行數據的空表,而此時必須使用expdp導出。

二、准備工作

若有必要,需要在新庫上建立必要的表空間、用戶(並賦權)、數據備份目錄,源庫上創建數據備份目錄等。

1、目標新庫上的操作

(1)創建臨時表空間

create temporary tablespace 用戶臨時表空間名稱 
tempfile '/u01/tablespaces/user_temp.dbf' 
size 50m 
autoextend on 
next 50m maxsize 20480m 
extent management local; 

備注:根據實際情況調整表空間大小等參數以及規划臨時表空間、回滾表空間等相關規划。

(2)創建數據表空間

create tablespace 用戶表空間名稱 
datafile '/u01/tablespaces/user_data.dbf' 
size 50m 
autoextend on 
next 50m maxsize 20480m 
extent management local; 

(3)建立用戶,並指定默認表空間

create user 用戶名稱 identified by 密碼 
default tablespace 用戶表空間名稱 
temporary tablespace 用戶臨時表空間名稱;

(4)給用戶授予權限

grant connect,resource to 用戶名1;
grant create database link to 用戶名;

注意:賦權給多個用戶的情況下,各個用戶名稱間用,分隔即可。

(5)登錄需要創建dblink的用戶,創建dblink

CREATE DATABASE LINK DBLink名稱 
CONNECT TO 用戶 IDENTIFIED BY 密碼 
USING '(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = XXX.XXX.XXX.XXX)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = 實例名)))';

注意:創建DBLINK默認是用戶級別的,對當前用戶有效。只有當需要對所有用戶有效時,再建立公有的DBlink對象(pulic參數)。

關於DBlink的知識點,參考:Oracle--dblink使用  http://www.cnblogs.com/chinas/p/6973058.html

2、創建數據備份目錄(源庫和目標庫)

備份目錄需要使用操作系統用戶創建一個真實的目錄,然后登錄oracle dba用戶,創建邏輯目錄,指向該路徑。這樣oracle才能識別這個備份目錄。

(1)在操作系統上建立真實的目錄

$ mkdir -p /u01/app/oracle/bankup

(2)登錄oracle管理員用戶

$ sqlplus /nolog
SQL> conn /as sysdba

(3)創建邏輯目錄

SQL> create directory auto_bankup as '/u01/app/oracle/bankup';

查看目錄是否已經創建成功:

SQL> select * from dba_directories;

5、用sys管理員給指定用戶賦予在該目錄的操作權限

SQL> grant read,write on directory data_dir to user;
SQL> grant read,write on directory data_dir to user1,user2;

三、導入導出

1、expdp導出

確保已經創建數據備份路徑,若沒有則按照准備工作中的說明進行創建。(注意:若CPU資源充足強烈推薦開啟並行參數,可以大大節省導入、導出的時間)

第一種:“full=y”,全量導出數據庫:

expdp user/passwd@orcl dumpfile=expdp.dmp directory=data_dir full=y logfile=expdp.log;

第二種:schemas按用戶導出:

expdp user/passwd@orcl schemas=user dumpfile=expdp.dmp directory=data_dir logfile=expdp.log;

第三種:按表空間導出:

expdp sys/passwd@orcl tablespace=tbs1,tbs2 dumpfile=expdp.dmp directory=data_dir logfile=expdp.log;

第四種:導出表:

expdp user/passwd@orcl tables=table1,table2 dumpfile=expdp.dmp directory=data_dir logfile=expdp.log;

第五種:按查詢條件導:

expdp user/passwd@orcl tables=table1='where number=1234' dumpfile=expdp.dmp directory=data_dir logfile=expdp.log;

2、impdp導入

注意:

  (1)確保數據庫軟件安裝正確,字符集、數據庫版本等與源庫一致,盡量此類因素引起的失敗。

  (2)確保數據庫備份目錄已提前建好,若沒有,參考前面的說明建立該目錄。

  (3)提前將源庫導出的數據文件傳遞到目標庫的備份目錄下,並確保導入時的數據庫用戶對該文件有操作權限。

第一種:“full=y”,全量導入數據庫;

impdp user/passwd directory=data_dir dumpfile=expdp.dmp full=y;

第二種:同名用戶導入,從用戶A導入到用戶A;

impdp A/passwd schemas=A directory=data_dir dumpfile=expdp.dmp logfile=impdp.log;   

第三種:
a.從A用戶中把表table1和table2導入到B用戶中;

impdp B/passwdtables=A.table1,A.table2 remap_schema=A:B directory=data_dir dumpfile=expdp.dmp logfile=impdp.log;

b.將表空間TBS01、TBS02、TBS03導入到表空間A_TBS,將用戶B的數據導入到A,並生成新的oid防止沖突;

impdp A/passwdremap_tablespace=TBS01:A_TBS,TBS02:A_TBS,TBS03:A_TBS remap_schema=B:A FULL=Y transform=oid:n 
directory=data_dir dumpfile=expdp.dmp logfile=impdp.log

第四種:導入表空間;

impdp sys/passwd tablespaces=tbs1 directory=data_dir dumpfile=expdp.dmp logfile=impdp.log;

第五種:追加數據;

impdp sys/passwd directory=data_dir dumpfile=expdp.dmp schemas=system table_exists_action=replace logfile=impdp.log; 

--table_exists_action:導入對象已存在時執行的操作。有效關鍵字:SKIP,APPEND,REPLACE和TRUNCATE

四、參數說明

1、expdb

(1)關鍵字及其說明

 ATTACH               連接到現有作業, 例如 ATTACH [=作業名]。 COMPRESSION           減小轉儲文件內容的大小, 其中有效關鍵字 值為: ALL, (METADATA_ONLY), DATA_ONLY 和 NONE。 CONTENT               指定要卸載的數據, 其中有效關鍵字 值為: (ALL), DATA_ONLY 和 METADATA_ONLY。 DATA_OPTIONS            數據層標記, 其中唯一有效的值為: 使用CLOB格式的 XML_CLOBS-write XML 數據類型。 DIRECTORY              供轉儲文件和日志文件使用的目錄對象,即邏輯目錄。 DUMPFILE              目標轉儲文件 (expdp.dmp) 的列表,例如 DUMPFILE=expdp1.dmp, expdp2.dmp。 ENCRYPTION             加密部分或全部轉儲文件, 其中有效關鍵字值為: ALL, DATA_ONLY, METADATA_ONLY,ENCRYPTED_COLUMNS_ONLY 或 NONE。 ENCRYPTION_ALGORITHM       指定應如何完成加密, 其中有效關鍵字值為: (AES128), AES192 和 AES256。 ENCRYPTION_MODE          生成加密密鑰的方法, 其中有效關鍵字值為: DUAL, PASSWORD 和 (TRANSPARENT)。 ENCRYPTION_PASSWORD       用於創建加密列數據的口令關鍵字。 ESTIMATE              計算作業估計值, 其中有效關鍵字值為: (BLOCKS) 和 STATISTICS。 ESTIMATE_ONLY           在不執行導出的情況下計算作業估計值。 EXCLUDE               排除特定的對象類型, 例如 EXCLUDE=TABLE:EMP。例:EXCLUDE=[object_type]:[name_clause],[object_type]:[name_clause] 。 FILESIZE               以字節為單位指定每個轉儲文件的大小。 FLASHBACK_SCN            用於將會話快照設置回以前狀態的 SCN。 -- 指定導出特定SCN時刻的表數據。
 FLASHBACK_TIME           用於獲取最接近指定時間的 SCN 的時間。-- 定導出特定時間點的表數據,注意FLASHBACK_SCN和FLASHBACK_TIME不能同時使用。

  FULL                 導出整個數據庫 (N)。   HELP               顯示幫助消息 (N)。 INCLUDE               包括特定的對象類型, 例如 INCLUDE=TABLE_DATA。 JOB_NAME           要創建的導出作業的名稱。 LOGFILE               日志文件名 (export.log)。 NETWORK_LINK            鏈接到源系統的遠程數據庫的名稱。 NOLOGFILE              不寫入日志文件 (N)。 PARALLEL              更改當前作業的活動 worker 的數目。 PARFILE               指定參數文件。 QUERY                用於導出表的子集的謂詞子句。--QUERY = [schema.][table_name:] query_clause。
 REMAP_DATA             指定數據轉換函數,例如 REMAP_DATA=EMP.EMPNO:REMAPPKG.EMPNO。 REUSE_DUMPFILES          覆蓋目標轉儲文件 (如果文件存在) (N)。 SAMPLE             要導出的數據的百分比。 SCHEMAS               要導出的方案的列表 (登錄方案)。   STATUS               在默認值 (0) 將顯示可用時的新狀態的情況下,要監視的頻率 (以秒計) 作業狀態。   TABLES               標識要導出的表的列表 - 只有一個方案。--[schema_name.]table_name[:partition_name][,…]
 TABLESPACES             標識要導出的表空間的列表。 TRANSPORTABLE          指定是否可以使用可傳輸方法, 其中有效關鍵字值為: ALWAYS, (NEVER)。 TRANSPORT_FULL_CHECK       驗證所有表的存儲段 (N)。 TRANSPORT_TABLESPACES     要從中卸載元數據的表空間的列表。 VERSION               要導出的對象的版本, 其中有效關鍵字為:(COMPATIBLE), LATEST 或任何有效的數據庫版本。

(2)命令及說明

 ADD_FILE              向轉儲文件集中添加轉儲文件。 CONTINUE_CLIENT          返回到記錄模式。如果處於空閑狀態, 將重新啟動作業。 EXIT_CLIENT             退出客戶機會話並使作業處於運行狀態。 FILESIZE               后續 ADD_FILE 命令的默認文件大小 (字節)。 HELP                總結交互命令。 KILL_JOB              分離和刪除作業。 PARALLEL              更改當前作業的活動 worker 的數目。PARALLEL=<worker 的數目>。 _DUMPFILES             覆蓋目標轉儲文件 (如果文件存在) (N)。 START_JOB             啟動/恢復當前作業。 STATUS               在默認值 (0) 將顯示可用時的新狀態的情況下,要監視的頻率 (以秒計) 作業狀態。STATUS[=interval]。 STOP_JOB              順序關閉執行的作業並退出客戶機。STOP_JOB=IMMEDIATE 將立即關閉數據泵作業。

2、impdb

(1)關鍵字及說明

ATTACH                         連接到現有作業, 例如 ATTACH [=作業名]。 CONTENT                    指定要卸載的數據, 其中有效關鍵字 值為: (ALL), DATA_ONLY 和 METADATA_ONLY。 DATA_OPTIONS                 數據層標記,其中唯一有效的值為:SKIP_CONSTRAINT_ERRORS-約束條件錯誤不嚴重。 DIRECTORY                  供轉儲文件,日志文件和sql文件使用的目錄對象,即邏輯目錄。 DUMPFILE                   要從(expdp.dmp)中導入的轉儲文件的列表,例如 DUMPFILE=expdp1.dmp, expdp2.dmp。 ENCRYPTION_PASSWORD            用於訪問加密列數據的口令關鍵字。此參數對網絡導入作業無效。 ESTIMATE                  計算作業估計值, 其中有效關鍵字為:(BLOCKS)和STATISTICS。 EXCLUDE                   排除特定的對象類型, 例如 EXCLUDE=TABLE:EMP。 FLASHBACK_SCN               用於將會話快照設置回以前狀態的 SCN。 FLASHBACK_TIME               用於獲取最接近指定時間的 SCN 的時間。 FULL                     從源導入全部對象(Y)。    HELP                     顯示幫助消息(N)。 INCLUDE                   包括特定的對象類型, 例如 INCLUDE=TABLE_DATA。 JOB_NAME                   要創建的導入作業的名稱。 LOGFILE                   日志文件名(import.log)。 NETWORK_LINK                鏈接到源系統的遠程數據庫的名稱。 NOLOGFILE                  不寫入日志文件。   PARALLEL                  更改當前作業的活動worker的數目。 PARFILE                   指定參數文件。 PARTITION_OPTIONS             指定應如何轉換分區,其中有效關鍵字為:DEPARTITION,MERGE和(NONE)。 QUERY                    用於導入表的子集的謂詞子句。 REMAP_DATA                 指定數據轉換函數,例如REMAP_DATA=EMP.EMPNO:REMAPPKG.EMPNO。 REMAP_DATAFILE              在所有DDL語句中重新定義數據文件引用。 REMAP_SCHEMA                將一個方案中的對象加載到另一個方案。 REMAP_TABLE                表名重新映射到另一個表,例如 REMAP_TABLE=EMP.EMPNO:REMAPPKG.EMPNO。 REMAP_TABLESPACE             將表空間對象重新映射到另一個表空間。 REUSE_DATAFILES               如果表空間已存在, 則將其初始化 (N)。 SCHEMAS                  要導入的方案的列表。 SKIP_UNUSABLE_INDEXES          跳過設置為無用索引狀態的索引。 SQLFILE                  將所有的 SQL DDL 寫入指定的文件。 STATUS                   在默認值(0)將顯示可用時的新狀態的情況下,要監視的頻率(以秒計)作業狀態。   STREAMS_CONFIGURATION          啟用流元數據的加載。 TABLE_EXISTS_ACTION            導入對象已存在時執行的操作。有效關鍵字:(SKIP),APPEND,REPLACE和TRUNCATE。 TABLES                   標識要導入的表的列表。 TABLESPACES                標識要導入的表空間的列表。  TRANSFORM                 要應用於適用對象的元數據轉換。有效轉換關鍵字為:SEGMENT_ATTRIBUTES,STORAGE,OID和PCTSPACE。 TRANSPORTABLE               用於選擇可傳輸數據移動的選項。有效關鍵字為: ALWAYS 和 (NEVER)。僅在 NETWORK_LINK 模式導入操作中有效。 TRANSPORT_DATAFILES            按可傳輸模式導入的數據文件的列表。 TRANSPORT_FULL_CHECK           驗證所有表的存儲段 (N)。 TRANSPORT_TABLESPACES          要從中加載元數據的表空間的列表。僅在 NETWORK_LINK 模式導入操作中有效。 VERSION                  要導出的對象的版本, 其中有效關鍵字為:(COMPATIBLE), LATEST 或任何有效的數據庫版本。僅對 NETWORK_LINK 和 SQLFILE 有效。

(2)命令及說明

 CONTINUE_CLIENT          返回到記錄模式。如果處於空閑狀態, 將重新啟動作業。 EXIT_CLIENT            退出客戶機會話並使作業處於運行狀態。 HELP                總結交互命令。 KILL_JOB              分離和刪除作業。 PARALLEL              更改當前作業的活動 worker 的數目。PARALLEL=<worker 的數目>。 START_JOB             啟動/恢復當前作業。START_JOB=SKIP_CURRENT 在開始作業之前將跳過作業停止時執行的任意操作。 STATUS               在默認值 (0) 將顯示可用時的新狀態的情況下,要監視的頻率 (以秒計) 作業狀態。STATUS[=interval]。 STOP_JOB              順序關閉執行的作業並退出客戶機。STOP_JOB=IMMEDIATE 將立即關閉數據泵作業。

五、錯誤及處理

1、ORA-39112

導出正常,導入數據時,只成功導入部分記錄等數據,另外的部分提數ora 39112錯誤,經查是因為導出的用戶數據中,有部分記錄的表用的索引在另一表空間中,該空間還未創建,所以導致該失敗。

解決方法:在導入時,添加參數:RANSFORM=segment_attributes:n ,配合table_exists_action=replace參數,重新導入即可。

RANSFORM=segment_attributes:n 在導入時,會將數據導入默認的表空間中。

 補充,造成該問題的可能原因:

1、在原來測試庫中,目標schema和別的用戶相互授權了,可是你導出的dmp中沒有包含所有的用戶,導入時對應用戶沒有創建。 2、再就是,表空間問題,測試庫中的用戶下的某個表的索引沒有在他的默認表空間里,這樣你要在目標端(這里就是生產環境),創建好對應的表空間, 就是說如果你在測試庫把a用戶的下的某個表的權限授給了b,那么你在把a用戶用數據泵倒進生產庫時,他會在生產庫中檢測有沒有用戶b。也要做相同的操作。

2、ORA-39346

導入過程中,遇到錯誤"  ORA-39346: data loss in character set conversion for object SCHEMA_EXPORT/PROCEDURE/PROCEDURE  "

oracle官方的描述如下:

Description: data loss in character set conversion for object string
Cause: Oracle Data Pump import converted a metadata object from the export database character set into the target database character set prior to processing the object. Some characters could not be converted to the target database character set and so the default replacement character was used.
Action: No specific user action is required. This type of data loss can occur if the target database character set is not a superset of the export databases character set.

 六、一鍵腳本

由於舊庫和新庫的網段不一樣,所以不是一鍵遷移腳本,而是先導出、導入操作分開進行的。自己寫了個腳本,減少重復勞動,有需要的同學可以參考下

#!/bin/bash
#############################################################################
#腳本功能:
#腳本路徑:
#使用方法:腳本名稱 操作類型參數
#############################################################################
export NLS_LANG=american_america.AL32UTF8
export ORACLE_HOME=/u01/app/oracle/product/12.1.0/db_1
export ORACLE_SID=cyrtestdb
export PATH=$PATH:$ORACLE_HOME/bin:/usr/bin:/usr/local/bin:/bin:/usr/bin/X11:/usr/local/bin:.

v_date=`date +%Y%m%d`
v_logfile=`echo $(basename  $0) | awk -F "." '{print $1".log"}'`  #日志文件名稱:腳本所在目錄下,腳本名稱.log

v_usr_1=""            #Oracle用戶名、密碼
v_pwd_1=""
v_usr_2=""
v_pwd_2=""            
v_db_instance=""    #數據庫實例名

v_backup_dir=""        #Oracle備份目錄(全局變量)
v_oradir_name=""    #
v_tmp_space1=""        #臨時表空間、表空間、索引表空間
v_tmp_space2=""
v_space1=""
v_space2=""
v_idx_space1=""
v_idx_space2=""
v_max_size="5120m"    #表空間數據文件最大值
v_dblink=""            #dblink名稱

#記錄日志
record_log(){
    echo -e `date '+%Y-%m-%d %H:%M:%S'` $1 | tee -a ${v_logfile}
}

#用戶數據導出
exp_usrdata(){
    v_exp_usr=$1
    v_exp_pwd=$2
    v_oradir_name=$3
    cd ${v_backup_dir}
    [[ -f ${v_exp_usr}"_"${v_date}".dmp" ]] && rm -rf ${v_exp_usr}"_"${v_date}".dmp"
    expdp ${v_exp_usr}/${v_exp_pwd} DIRECTORY=${v_oradir_name} DUMPFILE=${v_exp_usr}"_"${v_date}".dmp" SCHEMAS=${v_exp_usr} LOGFILE=${v_exp_usr}"_"${v_date}".log"
}

#在目標庫上創建數據庫備份目錄
create_bankup_dir(){
    #創建操作系統物理路徑
    [[ -d ${v_backup_dir} ]] && mkdir -p ${v_backup_dir}

    sqlplus -S / as sysdba >> ${v_logfile} <<EOF
    set heading off feedback off verify off
    spool tmp_space_flag.tmp
    grant read,write on directory '${v_oradir_name}' to '${v_usr_1}','${v_usr_2}';
    spool off
    exit;
EOF
    ##如果當前表空間不存在,則創建,否則退出當前函數
    if [[ `grep ${v_oradir_name} tmp_space_flag.tmp | wc -l` -eq 0 ]]; then
        record_log "創建備份目錄"$1"開始"
        sqlplus -S / as sysdba >> ${v_logfile} <<EOF
        set heading off feedback off verify off
        grant read,write on directory '${v_oradir_name}' to '${v_usr_1}','${v_usr_2}';
        exit;
EOF
        record_log "創建備份目錄"$1"結束"
    else
        record_log "創建備份目錄"$1"已存在"
        return
    fi
    ##注意清理臨時標志文件
    [[ -f ./tmp_space_flag.tmp ]] && rm -rf tmp_space_flag.tmp
}

#創建表空間
create_space(){
    v_space_name=$1
    #判斷表空間類型(臨時表空間或普通表空間)
    if [[ `grep TMP $1` -eq 1 ]]; then
        v_space_type="temporary"
    else
        v_space_type=""
    fi 
    sqlplus -S / as sysdba >> ${v_logfile} <<EOF
    set heading off feedback off verify off
    create '${v_space_type}' tablespace '${v_space_name}' tempfile '${v_backup_dir}/${v_space_name}.dbf' size 50m autoextend on next 128k maxsize '${v_max_size}' extent management local; 
    exit;
EOF
}

#判斷表空間是否存在,若表空間不存在則創建
deal_spaces(){
    v_space_name=$1
    sqlplus -S / as sysdba <<EOF 
    set heading off feedback off verify off
    spool tmp_space_flag.tmp
    select tablespace_name from dba_tablespaces where tablespace_name='${v_space_name}';
    spool off
    exit;
EOF
    ##如果當前表空間不存在,則創建,否則退出當前函數
    if [[ `grep ${v_space_name} tmp_space_flag.tmp | wc -l` -eq 0 ]]; then
        record_log "創建表空間"$1"開始"
        create_space ${v_space_name}
        record_log "創建表空間"$1"結束"
    else
        record_log "表空間"$1"已存在"
        return
    fi
    ##注意清理臨時標志文件
    [[ -f ./tmp_space_flag.tmp ]] && rm -rf tmp_space_flag.tmp

}

#在目標庫上創建用戶並賦權
create_usrs(){
    v_create_usr=$1        #參數1:用戶名
    v_create_pwd=$2        #參數2:密碼
    v_create_tmp_space=$3         #參數3:臨時表空間名稱
    v_create_space=$4        #參數4:表空間名稱

    sqlplus -S / as sysdba >> ${v_logfile} <<EOF
    set heading off feedback off verify off
    create user '${v_create_usr}' identified by '${v_create_pwd}' default tablespace '${v_create_space}' temporary tablespace '${v_create_tmp_space}';
    grant connect,resource to '${v_create_usr}';
    grant exp_full_database to '${v_create_usr}';
    grant imp_full_database to '${v_create_usr}';
    grant unlimited tablespace to '${v_create_usr}';
    exit;
EOF
}

#用戶數據導入
imp_usrdata(){
    v_imp_usr=$1
    v_imp_pwd=$2
    v_oradir_name=$3
    impdp ${v_imp_usr}/${v_imp_pwd} DIRECTORY=${v_oradir_name} DUMPFILE=${v_imp_usr}"_"${v_date}".dmp" SCHEMAS=${v_imp_usr} LOGFILE=${v_imp_usr}"_"${v_date}".log" table_exists_action=replace RANSFORM=segment_attributes:n
}

#刪除用戶
drop_user(){
    v_drop_usr=$1
    #刪除用戶及用戶下的所有數據,刪除表空間及表空間下的所有數據
    sqlplus -S / as sysdba >> ${v_logfile} <<EOF
    set heading off feedback off verify off
    drop user '${v_drop_usr}' cascade;
    exit
EOF
}

#刪除表空間並刪除表空間下的數據文件
drop_tablespace(){
    v_drop_space=$1
    #刪除用戶及用戶下的所有數據,刪除表空間及表空間下的所有數據
    sqlplus -S / as sysdba >> ${v_logfile} <<EOF
    set heading off feedback off verify off
    drop tablespace '${v_drop_space}' including contents and datafiles;
    exit
EOF
    ##操作系統上表空間下的數據文件
    [[ -f ${v_backup_dir}/${v_drop_space}.dbf ]] && rm -rf ${v_backup_dir}/${v_drop_space}.dbf
}

#創建dblink
create_dblink(){
    v_clink_usr=$1
    v_clink_pwd=$2

    #以管理員身份對創建dblink賦權
    sqlplus -S / as sysdba >> ${v_logfile} <<EOF
    set heading off feedback off verify off
    grant create database link to '${v_clink_usr}';
    exit;
EOF
    #以普通用戶登錄創建dblink
    sqlplus -S ${v_clink_usr}/${v_clink_pwd}@${v_db_instance} >> ${v_logfile} <<EOF
    set heading off feedback off verify off
    CREATE DATABASE LINK ${v_dblink} CONNECT TO '${v_clink_usr}' IDENTIFIED BY '${v_clink_pwd}' USING '{v_db_instance}';
    exit
EOF
}

#判斷dblink是否存在
deal_dblink(){
    v_link=$1
    v_link_usr=$2
    v_link_pwd=$3
    sqlplus -S / as sysdba <<EOF 
    set heading off feedback off verify off
    spool tmp_space_flag.tmp
    select object_name from dba_objects where object_name = '${v_link}'; 
    spool off
    exit;
EOF
    ##如果當前dblink不存在,則創建,否則退出當前函數
    if [[ `grep ${v_space_name} tmp_space_flag.tmp | wc -l` -eq 0 ]]; then
        record_log "創建"$1"開始"
        create_dblink ${v_link_usr} ${v_link_pwd}
        record_log "創建"$1"結束"
    else
        record_log $1"已存在"
        return
    fi
    ##注意清理臨時標志文件
    [[ -f ./tmp_space_flag.tmp ]] && rm -rf tmp_space_flag.tmp
}

#主函數
main(){
    v_start=`date +%s`
    if [[ $1 -eq "exp" ]]; then
         record_log "bl庫導出開始..."
        exp_usrdata ${v_usr_1} ${v_pwd_1} ${v_oradir_name}
        record_log "bl庫導出結束..."

        record_log "hx庫導出開始..."
        exp_usrdata ${v_usr_2} ${v_pwd_2} ${v_oradir_name}
        record_log "hx庫導出結束..."
    elif [[ $1 -eq "pre" ]]; then
        #1、創建備份目錄
        create_bankup_dir
        #2、創建表空間
        for v_sp in ${v_tmp_space1} ${v_tmp_space2} ${v_space1} ${v_space2} ${v_idx_space1} ${v_idx_space2}; do
            deal_spaces ${v_sp}
        done
        #3、創建用戶、賦權
        record_log "創建用戶開始..."
        create_usrs ${v_usr_1} ${v_pwd_1} ${v_tmp_space1} ${v_space1}
        create_usrs ${v_usr_2} ${v_pwd_2} ${v_tmp_space2} ${v_space2}
        record_log "創建用戶結束..."
        #4、為hx庫創建dblink
        record_log "創建dblink開始..."
        deal_dblink ${v_dblink} ${v_usr_2} ${v_pwd_2}
        record_log "創建dblink結束..."

    elif [[ $1 -eq "imp" ]]; then
        record_log "bl庫導入開始..."
        imp_usrdata ${v_usr_1} ${v_pwd_1} ${v_oradir_name}
        record_log "bl庫導入結束..."

        record_log "hx庫導入開始..."
        imp_usrdata ${v_usr_2} ${v_pwd_2} ${v_oradir_name}
        record_log "hx庫導入結束..."
    elif [[ $1 -eq "clean" ]]; then
        read -t 5 -p "確認清除 0-否 1-是" v_num
        if [[ ${v_num} -eq 1 ]]; then
            record_log "清理數據文件開始..."
            for m in ${} ${}; do
                drop_user ${m}
            done
            for n in ${v_tmp_space1} ${v_tmp_space2} ${v_space1} ${v_space2} ${v_idx_space1} ${v_idx_space2}; do
                drop_tablespace ${n}
            done
            record_log "清理數據文件結束..."
        else
            exit
        fi
    else
        echo "Usage: sh script [exp|clean|pre|imp]"
        exit
    fi
    v_end=`date +%s`
    v_use_time=$[ v_end - v_start ]
    record_log "本次腳本運行時間:"${v_use_time}""
}
main
View Code

 

參考文檔

Oracle使用EXPDP和IMPDP數據泵進行導出導入方法_數據庫技術  http://www.linuxidc.com/Linux/2017-09/146764.htm

ORA-39112: dependent object type comment skipped - CSDN博客  http://blog.csdn.net/zhengwei125/article/details/53670656

Oracle 12cR1 ORA-39346 data loss in character set conversion for object string  https://www.oraexcel.com/oracle-12cR1-ORA-39346

從11.2.0.4倒入12c報錯:ORA-39346 - Oracle 12c 重慶思庄Oracle論壇  http://bbs.cqsztech.com/forum.php?mod=viewthread&tid=17282

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM