Oracle Export (EXP) 和 Import (IMP) 是 Oracle 資料庫早期版本中最核心的邏輯備份與遷移工具。雖然 Oracle 10g 後推出了功能更強大的 Data Pump (expdp/impdp),但 EXP/IMP 仍廣泛用於舊版本資料庫維護、跨版本遷移及簡單的資料導出入場景。本文系統整理其核心概念、操作流程、參數詳解、常見問題及實戰腳本。
Dump 檔包含兩類核心內容:
三種導出模式包含的物件差異:
| 物件類型 | Table Mode | User Mode | Full Database Mode |
|---|---|---|---|
| 表定義/資料/索引/約束/觸發器 | ✓ | ✓ | ✓ |
| 授權/同義詞/視圖/序列/程序/包 | 擁有者 | 擁有者 | 全部 |
| 用戶/角色/設定檔/表空間/資料庫連結/Job/快照 | ✗ | 部分 | ✓ |
IMP 遵循固定順序解決物件依賴,典型順序如下(版本略有差異):
注意:導入後可能出現 INVALID 狀態的 Procedure/Function,需手動重新編譯(`ALTER PROCEDURE ... COMPILE`)。
`COMPRESS=Y`(預設)會將表的 `INITIAL` 儲存參數設為「所有 Extent 總大小」,而非實際資料大小。
風險案例:
建議:大表整理時使用 `COMPRESS=N`,或先 `ALTER TABLE ... MOVE` 整理後再導出。
exp userid=scott/tiger \
file=exp_$(date +%Y%m%d).dmp \
log=exp_$(date +%Y%m%d).log \
owner=scott \
buffer=4096000 \
rows=n \
compress=n \
consistent=y \
statistics=none
| 參數 | 說明 | 預設 |
|---|---|---|
| FULL | 全庫導出 | N |
| OWNER | 指定 Schema 列表 (User 模式) | - |
| TABLES | 指定表列表 (Table 模式),支援分區 `T1:P1` | - |
| COMPRESS | 壓縮 Extent (修改 INITIAL) | Y |
| CONSISTENT | 跨表一致性 (使用 Rollback Segment) | N |
| DIRECT | 直接路徑導出 (繞過 SQL 層,速度快) | N |
| QUERY | 導出子集 WHERE 條件 | - |
| FILESIZE | 單一 Dump 檔最大尺寸 (支援多檔) | - |
| PARFILE | 參數檔路徑 | - |
imp userid=scott/tiger \
file=exp_20231001.dmp \
log=imp_20231001.log \
fromuser=scott \
touser=scott_new \
ignore=y \
indexes=y \
constraints=y \
grants=y \
rows=y \
commit=y \
buffer=4096000
| 參數 | 說明 | 預設 |
|---|---|---|
| FROMUSER/TOUSER | Schema 重映射 | - |
| IGNORE | 忽略建立錯誤 (如表已存在) | N |
| INDEXES/GRANTS/CONSTRAINTS | 是否導入索引/授權/約束 | Y |
| ROWS | 是否導入資料 | Y |
| COMMIT | 批次提交 (減少 Rollback 使用) | N |
| DESTROY | 覆寫資料檔 (危險,慎用) | N |
| INDEXFILE | 將 DDL 輸出至檔案不執行 (審核用) | - |
| SKIP_UNUSABLE_INDEXES | 跳過不可用索引維護 | N |
#!/bin/bash
# 環境變數設定 (crontab 執行必須)
export ORACLE_BASE=/opt/oracle
export ORACLE_HOME=$ORACLE_BASE/product/19c
export ORACLE_SID=orcl
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
export PATH=$ORACLE_HOME/bin:$PATH
BACKUP_DIR=/backup/oracle/exp
USER_PASS=scott/tiger
LOG_DIR=$BACKUP_DIR/logs
mkdir -p $BACKUP_DIR $LOG_DIR
cd $BACKUP_DIR
DATE_TAG=$(date +%Y%m%d)
# 1. Schema 完整導出 (不含資料,僅結構)
exp $USER_PASS file=schema_${DATE_TAG}.dmp log=schema_${DATE_TAG}.log owner=scott rows=n compress=n consistent=y
# 2. 逐表導出資料 (直接路徑加速)
sqlplus -s $USER_PASS <<EOF
set heading off feedback off pagesize 0 trimspool on
spool table_list.lst
select table_name from user_tables;
spool off
EOF
for tbl in $(cat table_list.lst); do
exp $USER_PASS file=${tbl}_${DATE_TAG}.dmp log=${tbl}_${DATE_TAG}.log tables=$tbl direct=y rows=y
done
# 3. 壓縮所有 Dump
gzip -f *.dmp
echo "$(date) Backup completed" >> $LOG_DIR/backup_result.log
# .netrc 檔案 (置於 $HOME,權限 600)
machine backup-server.example.com
login oracle_bak
password ********
macdef init
binary
lcd /backup/oracle/exp
cd /remote/backup/oracle
mput *.gz
bye
# crontab -e (oracle 用戶)
# 每天 23:10 執行導出,23:30 啟動 FTP 傳輸
10 23 * * * /home/oracle/scripts/exp_full.sh
30 23 * * * ftp -i backup-server.example.com
| 錯誤代碼 | 原因 | 解決方案 |
|---|---|---|
| EXP-00024 / IMP-00023 | Export/Import 視圖未安裝或版本不符 | 以 SYS 執行 `$ORACLE_HOME/rdbms/admin/catexp.sql` |
| IMP-00010 | 非有效 Dump 檔 (常因 ASCII 模式傳輸) | FTP 必須使用 `binary` 模式傳輸 |
| ORA-01658 | 無法分配 INITIAL Extent (COMPRESS=Y 導致) | 導出時加 `COMPRESS=N` 或調整目標表空間檔案大小 |
| IMP-00069 | 字元集轉換失敗 | 設定 `NLS_LANG` 與源資料庫一致,或使用 `FROMUSER/TOUSER` 避免字典衝突 |
雖然 Data Pump (expdp/impdp) 在並行度、網路模式、細粒度過濾等方面全面超越 EXP/IMP,但後者因其簡單、相容性極佳、無需 Directory Object、支援極舊版本 (7.3+),在「異構舊版本遷移」、「輕量級邏輯備份」、「無共享儲存環境下的跨機器拷貝」等場景仍具不可替代價值。掌握其參數細節與陷阱,是資料庫管理員的基本功。