將大量資料用戶的所有表從表空間 A 遷移至表空間 B,傳統 DROP/CREATE 需備份資料、耗時極長。利用 Oracle Export/Import (EXP/IMP) 搭配 INDEXFILE、INDEXES=N、IGNORE=Y 參數,可在不導出資料檔的情況下,僅透過中繼資料腳本修改表空間子句,實現大表空間「原地重組」。本文以 db_zgxt 用戶為例,詳細記錄 5 步驟完整流程。
db_zgxtExp0326.dmpC:\> EXP80 OWNER=db_zgxt FILE=Exp0326.dmp LOG=Exp0326.log
-- SQL*Plus 中
SELECT 'DROP TABLE ' || table_name || ' CASCADE CONSTRAINTS;'
FROM user_tables;
CASCADE CONSTRAINTS 自動刪除參考該表的外鍵約束C:\> IMP80 FULL=Y FILE=Exp0326.dmp INDEXFILE=db_zgxt.sql LOG=Imp0326_1.log
INDEXFILE=db_zgxt.sql:不實際導入,僅將 CREATE TABLE/INDEX 陳述式寫入腳本檔CREATE TABLE 以註解標記 (--)CREATE INDEX 正常輸出CREATE TABLE 前的註解符號A 替換為 B (含 TABLESPACE 子句、STORAGE 參數)CREATE INDEX 前加上註解符號 (暫不建立索引)SQL> @db_zgxt.sql
C:\> IMP80 FULL=Y FILE=Exp0326.dmp INDEXES=N IGNORE=Y LOG=Imp0326_2.log
INDEXES=N:不建立索引,大幅加速資料導入IGNORE=Y:遇到 ORA-00955: table already exists 忽略繼續,將資料導入步驟 3 建立的表db_zgxt.sql:CREATE TABLE 加註解CREATE INDEX 移除註解SQL> @db_zgxt.sqlNOLOGGING PARALLEL 進一步加速SORT_AREA_SIZE| 檢查項目 | 指令/方法 |
|---|---|
| 表筆數一致 | SELECT COUNT(*) FROM source_table MINUS SELECT COUNT(*) FROM target_table |
| 索引狀態 VALID | SELECT index_name, status FROM user_indexes WHERE table_name = '...' |
| 約束啟用 | SELECT constraint_name, status FROM user_constraints WHERE table_name = '...' |
| 授權完整 | SELECT * FROM user_tab_privs WHERE table_name = '...' |
| 觸發器狀態 | SELECT trigger_name, status FROM user_triggers WHERE table_name = '...' |
REMAP_TABLESPACE=A:B 一指令完成EXP/IMP 重組表空間雖屬經典技法,但其核心思想——分離中繼資料與資料、中繼資料可編輯、資料直導目標表——至今仍是資料庫遷移的基因。理解 INDEXFILE 產生可編輯腳本、INDEXES=N 延後索引、IGNORE=Y 容忍表存在,這三個參數的組合拳,即掌握了邏輯遷移的精髓。現代環境請優先使用 Data Pump REMAP_TABLESPACE,但經典 EXP/IMP 流程仍是理解遷移本質、處理舊版本環境、應對特殊約束場景的必備基本功。