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