劉 偉
(武漢鐵路局信息技術處,武漢430071)
Oracle數(shù)據(jù)庫應用于很多鐵路信息系統(tǒng)中,作為Oracle數(shù)據(jù)庫管理員,經(jīng)常會使用EXP/IMP工具遷移用戶數(shù)據(jù),特別是在Oracle 較低的8i和9i版本中。本文針對一種較為異常的數(shù)據(jù)庫遷移現(xiàn)象,利用EXP/IMP、UltraEdit工具給出相應的解決方法。
2007年某鐵路信息系統(tǒng)遷入到IBM P570小型機,Oracle數(shù)據(jù)庫使用EXP/IMP工具完成了8i到9i的遷移。雖然Oracle數(shù)據(jù)庫目前運行的比較穩(wěn)定,但仍存在眾多的數(shù)據(jù)庫用戶使用同一個表空間的問題。隨著時間的推移,該表空間的數(shù)據(jù)文件變得越來越多,表空間變得越來越大,成為了一個必須重視的問題。經(jīng)過技術人員的討論,決定先將某個重要的用戶數(shù)據(jù)從該表空間中遷移出來。
這次遷移的工作是:在同一個Oracle數(shù)據(jù)庫中,將A用戶從表空間ts1遷移到表空間ts2上,并且表空間ts1是不允許刪除的。
這個工作可以利用下面幾個步驟來完成:
(1)給A用戶使用者發(fā)出通知,告之在某個時間段進行數(shù)據(jù)庫維護工作,這個時間段暫停對A用戶數(shù)據(jù)的訪問;
(2)在這個時間段,對A用戶進行加鎖操作;
(3)exp system/system_password file=a.dmp log=a_exp.log owner=a;
(4)記錄A用戶擁有的權限和角色;
(5)drop user a cascade;
(6)create user a identified by a_password default tablespace ts2 temporary tablespace temp;
(7)grant 記錄的權限或角色給用戶A;
(8)revoke unlimited tablespace from a;
(9)alter user a quota 0 on ts1;
(10)alter user a quota unlimited on ts2;
(11)alter user a quota unlimited on temp;
(12)imp a/a_password file=a.dmp log=a_imp.log fromuser=a touser=a。
在完成了上述12步操作后,A用戶的數(shù)據(jù)從表空間ts1又遷移回到ts1上了,這次遷移失敗。對于這個結果,咨詢了相關Oracle專家,分析認為可能是Oracle數(shù)據(jù)庫某方面的一個bug。
接下來,技術人員討論出了另外一種方法。利用UltraEdit工具編輯a.dmp,將a.dmp中tablespace“TS1”全部替換成tablespace“TS2”,然后再利用更改后的a.dmp完成遷移工作??墒莂.dmp的文件大小有20 G,加載到PC機內存編輯過程中頻繁死機。此辦法針對大容量dmp文件依然不合適。
利用UltraEdit工具更改dmp文件的方法經(jīng)證明在本信息系統(tǒng)的數(shù)據(jù)庫上是可以完成不同表空間的遷移?,F(xiàn)在的問題集中在dmp文件的大小上。
EXP命令有一個選項ROWS,默認情況下值為Y,表示導出數(shù)據(jù)行。當把ROWS設置為N時,dmp文件只包含表的結構,而不包括表中的數(shù)據(jù)。通過加上這個選項,a.dmp文件只有10 M大小。利用UltraEdit工具對a.dmp完成表空間名的替換,特別注意的是2個表空間名字的字節(jié)大小要保持一致,否則更改后的dmp文件就不可用了。
a.dmp是不包含數(shù)據(jù)的,所以還需利用EXP命令導出一個包含數(shù)據(jù)的dmp文件a_data.dmp。
利用IMP命令完成a.dmp的導入工作。導入的僅是結構,不包含實際數(shù)據(jù)。當每次IMP完成后,都有信息輸出,如圖1。
圖1 信息輸出界面圖
圖1中about to enable constraints…表示啟動該用戶內定義的各種約束,包括外鍵,觸發(fā)器等。所以在導入a_data.dmp文件前,必須禁用A用戶的外鍵和觸發(fā)器,否則可能會造成導入工作的錯誤。可以通過oracle enterprise manager console或者下面的語句來查詢外鍵和觸發(fā)器:
select constraint_name, table_name from user_constraints where owner='A' and constraint_type=’R’;
select trigger_name,trigger_type from user_triggers where table_owner='A';
可以通過下面的語句來禁用外鍵和觸發(fā)器:
alter table table_name disable constraint constraint_name;
alter trigger trigger_name disable;
導入a_data.dmp時,需要對IMP加上參數(shù)IGNORE=Y,表示忽略創(chuàng)建錯誤。由于a.dmp的導入使得表結構已經(jīng)存在,所以當a_data.dmp導入發(fā)現(xiàn)已建表時需要忽略創(chuàng)建錯誤。
當完成a_data.dmp導入工作,數(shù)據(jù)庫會自動啟用該用戶的各種約束,包括前面手工禁用A用戶的外鍵和觸發(fā)器。
完整的操作步驟如下:
(1)給A用戶使用者發(fā)出通知,告之在某個時間段進行數(shù)據(jù)庫維護工作,這個時間段暫停對A用戶數(shù)據(jù)的訪問;
(2)在這個時間段,對A用戶進行加鎖操作;
(3)exp system/system_password file=a.dmp rows=n log=a_exp.log owner=a;
(4)exp system/system_password file=a_data.dmp log=a_data_exp.log owner=a;
(5)利用UltraEdit工具將a.dmp中tablespace“TS1”全部替換成tablespace “TS2”;
(6)記錄A用戶擁有的權限和角色;
(7)drop user a cascade;
(8)create user a identified by a_password default tablespace ts2 temporary tablespace temp;
(9)grant 記錄的權限或角色給用戶A;
(10)revoke unlimited tablespace from a;
(11)alter user a quota 0 on ts1;
(12)alter user a quota unlimited on ts2;
(13)alter user a quota unlimited on temp;
(14)imp a/a_password file=a.dmp log=a_imp.log fromuser=a touser=a;
(15)禁用A用戶的外鍵和觸發(fā)器;
(16)imp a/a_password file=a_data.dmp ignore=y log=a_data_imp.log fromuser=a touser=a;
經(jīng)過上述操作后,遷移工作成功。
本文描述了一種較為特殊的Oracle數(shù)據(jù)庫遷移現(xiàn)象,通過3次試驗最終得出了切實可行的解決方法。該方法使用了Oracle EXP/IMP和UltraEdit,實施簡單并對數(shù)據(jù)庫的正常運行影響較小,具有數(shù)據(jù)的可恢復性。