oracle 數(shù)據(jù)庫數(shù)據(jù)遷移解決方案
去年年底做了不少系統(tǒng)的數(shù)據(jù)遷移,大部分系統(tǒng)由于平臺和版本的原因,做的是邏輯遷移,少部分做的是物理遷移,有一些心得體會,與大家分享。
首先說說遷移流程,在遷移之前,寫好方案,特別是實施的方案步驟一定要寫清楚,然后進行完整的測試。我們在遷移時,有的系統(tǒng)測試了四五次,通過測試來完善方案和流程。
針對物理遷移,也即通過RMAN備份來進行還原并應用歸檔的方式(這里不討論通過dd方式進行的冷遷移),雖然注意的是要將數(shù)據(jù)庫設為force logging的方式,在用RMAN做全備之前,一定要執(zhí)行:
否則可能會產生壞塊。
對于邏輯遷移,在job_processes設置為>0的數(shù)值之前,注意job的下次執(zhí)行時間和job所屬用戶。比如job的定義在之前已經(jīng)導入,但是在遷移之時,job已經(jīng)運行過,那么遷移完成之后,job的下次時間還是原來的時間,這樣可能會重復運行。另外,job通過IMP導入后,job所屬用戶會變成導入用戶的名稱,顯然job原來的用戶就不能對JOB進行管理了,可以通過下面的sql進行修改:
在遷移之前,應該禁止對系統(tǒng)進行結構上的修改和發(fā)布,比如表結構,索引,存儲過程包等。
如果是用exp/imp導入的對象,包括存儲過程等,應該檢查對象是否與原生產庫一致,比如由于dblink的原因,imp之后,存儲過程不能創(chuàng)建,導致有部分存儲過程丟失,盡管這些存儲過程可能沒有被使用。
下面是一些加快遷移速度的技巧:
通過dblink,使用append insert的方式,同時利用并行,這種方式比exp/imp更快
對于有LONG類型的列,insert..select的方式顯然是不行的,可以通過exp/imp的方式,但是這種方式速度非常慢,其原因在于imp時一行一行地插入表。有另外一種方式,即sqlplus的copy命令,下面是一個示例:

不過,sqlpus的copy命令不支持有timestamp和lob列類型的表。如果有timestamp類型的表,可以通過在exp時,加上rowid的條件,將一個表分成多個部分同時操作,對于有l(wèi)ob類型的表,也可以同樣處理(因為insert …select方式下,有l(wèi)ob類型列時,也同樣是一行一行地插入)。注意在這種方式下,就不能使用direct的方式exp/imp。下面是exp導出時parfile示例:

將表分成幾部分同時操作,不僅僅可以利用rowid,也可以利用表上的列,比如說,表上有一個created_date的列,并且保證是遞增插入數(shù)據(jù),那么這種情況下,也可以使用這個字段將表分成不同的范圍同時進行導出和導入。不過使用ROWID通常具有更高的效率。
當然對于有l(wèi)ob列的表,可以按上述方式,拆成多個insert方式同時插入,不需要exp/imp。
·對于特別大的分區(qū)表,雖然使用并行可以提高速度,但是受限于單個進程(不能跨DB LINK進行并行事務,只能并行查詢,也即insert..select只能是SELECT部分才能進行并行)的處理能力,這種方式下速度仍然有限??梢圆⑿袑?shù)據(jù)插入多個中間表,然后通過exchange partition without validation 的方式,交換分區(qū),這種方式將會大大提高了速度。
·有朋友可能會問,為什么不并行直接插入分區(qū)表,當然如果是非direct path(append)方式,則是沒問題的,但是這種方式插入的性能較低。而direct path的方式,會在表上持有mode=6(互斥)的TM鎖,不能多個會話同時插入。(update: 在insert 時使用這樣的語句:insert into tablename partition (partname) select * from tablename where ….,更簡單更有效率。)
·遷移時,將數(shù)據(jù)分成兩部分,一部分是歷史表,第二部分是動態(tài)變化的表,在遷移之前,先導入歷史表,并在歷史表上建好索引,這無疑會大大減少遷移時業(yè)務系統(tǒng)中斷時間。
·遷移之前,考慮清理掉垃圾數(shù)據(jù)。
·遷移時,應保證表上沒有任何索引,約束(NOT NULL除外)和觸發(fā)器,數(shù)據(jù)導入完成后,再建索引。建索引時同樣,同時使用多個進程跑腳本。索引創(chuàng)建無成后,應去掉索引的PARALLEL屬性
·在創(chuàng)建約束時,應按先創(chuàng)建CHECK約束,主鍵,唯一鍵,再創(chuàng)建外鍵約束的順序。約束狀態(tài)為 ENABLE NOVALIDATE,這將大大減少約束創(chuàng)建時間。而在遷移完成后,再考慮設回為ENABLE VALIDATE。
·通過使用dbms_stats.export_schame_stats和dbms_stats.import_schame_stats導入原庫上的統(tǒng)計信息,而不用重新收集統(tǒng)計使用。
朋友們可以看到,以上均是針對9i的,實際上在10g甚至11g環(huán)境下,也仍然很多借鑒意義。當然這些技巧不僅僅用于完整的數(shù)據(jù)庫遷移,也可以應用到將個別表復制到其他數(shù)據(jù)庫上。
這里沒有提到的是利用物化視圖或高級復制、觸發(fā)器之類的技術,因為這些技術,畢竟要修改生產庫,對生產庫的運行有比較大的影響,因此,只有在停機時間要求特別嚴格,而在這個時間內又不能完成遷移時才應該考慮。
從遷移的經(jīng)驗來說,只有完善的流程,完整的測試才可以保證成功。這里只是列舉了一些小技巧,如果對整個遷移過程有興趣,可以針對這個話題再進行討論。
相關文章
Oracle中使用觸發(fā)器(trigger)和序列(sequence)模擬實現(xiàn)自增列實例
這篇文章主要介紹了Oracle中使用觸發(fā)器(trigger)和序列(sequence)模擬實現(xiàn)自增列實例,包含代碼實例,而且小編已經(jīng)測試過了哦,需要的朋友可以參考下2014-07-07
Oracle字段根據(jù)逗號分割查詢數(shù)據(jù)的方法
項目需求是這樣的表里的某個字段存儲的值是以逗號分隔開來的,要求根據(jù)分隔的每一個值都能查出來數(shù)據(jù),但是不能使用like查詢。這篇文章主要介紹了Oracle字段根據(jù)逗號分割查詢數(shù)據(jù),需要的朋友可以參考下2018-08-08
Linux系統(tǒng)下Oracle數(shù)據(jù)庫監(jiān)聽啟動關閉命令詳解
現(xiàn)在很多朋友在學習linux下oracle 數(shù)據(jù)庫的時候可能都發(fā)現(xiàn)了一個問題,oracle數(shù)據(jù)庫的服務不能自動啟動,這篇文章主要給大家介紹了關于Linux系統(tǒng)下Oracle數(shù)據(jù)庫監(jiān)聽啟動關閉命令的相關資料,需要的朋友可以參考下2024-01-01
Oracle數(shù)據(jù)庫中l(wèi)ead和lag函數(shù)用法示例
lag與lead函數(shù)是跟偏移量相關的兩個分析函數(shù),通過這兩個函數(shù)可以在一次查詢中取出同一字段的前N行的數(shù)據(jù)(lag)和后N行的數(shù)據(jù)(lead)作為獨立的列,這篇文章主要給大家介紹了關于Oracle數(shù)據(jù)庫中l(wèi)ead和lag函數(shù)用法的相關資料,需要的朋友可以參考下2024-06-06
Oracle數(shù)據(jù)庫刪除表空間后磁盤空間不釋放的問題及解決
這篇文章主要介紹了Oracle數(shù)據(jù)庫刪除表空間后磁盤空間不釋放的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
oracle導出sql語句的結果集和保存執(zhí)行的sql語句(深入分析)
本篇文章是對oracle導出sql語句的結果集與保存執(zhí)行的sql語句進行了詳細的分析介紹,需要的朋友參考下2013-05-05
Oracle利用errorstack追蹤tomcat報錯ORA-00903 無效表名的問題
這篇文章主要介紹了Oracle利用errorstack追蹤tomcat報錯ORA-00903 無效表名,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06

