回覆列表
  • 1 # 楊建榮的學習筆記

    從Oracle遷移到MySQL需要考慮的事情其實遠比我們要理清資料型別轉換這些技術細節要多,也更重要。

    有兩個問題需要前置考慮:

    為什麼要從Oracle遷移出去?

    為什麼要遷移到MySQL

    如果解答了上述的兩個問題,也就基本理順了整個事情的脈絡,我會本著基本客觀的態度來說明。

    問題1:為什麼要從Oracle遷移出去?

    這件事情從行業的實踐來看(主要是說網際網路行業),絕對不是先從技術可行性觸發,而是從業務可行性來入手,歸根結底,主要的出發點就兩個字:成本

    MySQL開源免費,更重要的是行業實踐驗證充分,所以它具有得天獨厚的優勢。阿里多年前的去IOE風風火火,儼然成為了行業的標杆。

    成本的事情很微妙,三言兩語說不清。舉例來說,你可以使用Office來辦公,當然你可能考慮買授權或者綠色版啟用,但是如果使用WPS就是名正言順的事情,當然功能上是和Office有一些差距,但是不會存在一些模糊的邊界。

    從業務的另一個維度來看,試想我們所接觸的網際網路行業,很多業務除了充值和錢相關的業務,其實對於資料完整性一致性的要求就會降低一個維度,很多時候錢能解決的問題都不是問題,比錢更重要的是什麼,我覺得應該是安全,安全包括生命安全,行業安全,系統安全,這些絕對不允許出一些重大問題的,這些影響面太大,比如醫院醫生給患者開藥的資料,這些影響面是很大的,一旦出問題很容易成為公眾事件。而以金融級業務作為一個分界點,之上的是安全領域,之下的領域其實就是一些可選擇的空間了,這些空間很大。選擇商業的一個原因也在此,有技術兜底,這些成本對企業來說也是需要和廠商的繫結關係。稀裡糊塗硬上,出了問題找不到專業的快速支援,那就悲劇了。

    然後是開源定製,其實很多開源技術的開源協議是有差別的,我們採用開源技術也需要考慮這些協議的邊界和適用範圍。

    所以到此需要明確的是:

    1.成本因素需要權衡,絕對不是非黑即白的事情

    2.遷移到MySQL其實不是終極解決方案,只是一種可選的方案

    3.對開源技術積累足夠,技術把控能力要強

    4.遷移的本質是找到最適合的業務場景,而不是為了技術實現而實現

    對於第4點,舉個例子,Oracle從效能上是毫無疑問的,但是如果有海量的讀請求,其實就不適合Oracle來扛了,當然也不適合用MySQL,可能Redis的方案會更好一些。

    問題2:為什麼要遷移到MySQL

    要回答這個問題,其實我們的主線就是MySQL可以做什麼。

    第一還是成本,開源免費,方便定製,MySQL的可選方案可絕對不只有社群版,還有一系列的分支,比如Percona分支,MariaDB分支,儲存引擎InnoDB,MyRocks等統統都是免費可選。

    第二是MySQL效率高,足夠輕量級。MySQL的效率從使用上來說,學習週期會很短,容易上手,而且對於系統的資源要求不高。

    第三是水平擴充套件能力,把Oracle比作地鐵,MySQL比作公交車會更容易理解,我們可以很輕鬆的加開公交專線,但是加開地鐵線路那就完全不同了。我覺得這是遷移到MySQL的一個核心點,這也就是為什麼很多網際網路的MySQL規模動輒幾百幾千了,爆發式增長的業務,MySQL擴充套件能力了不是體現在MySQL資料庫本身,而是對於架構的擴充套件性上,而這也就是為什麼很多MySQL DBA比較貴的一個原因。

    第四是複製,這是MySQL相比Oracle的一個亮點,如果需要做跨資料中心的複製,允許存在一定的延遲,使用MySQL原生的複製方案是一件很容易的事情,MySQL支援很多不同維度的複製方案。

    第五是業務輕依賴,這個可以分為兩個維度來說。一個是功能限制,一個是效能限制。這本身是MySQL功能和效能上的缺失,但是反而是一個優點因為要支撐分散式需求,需要業務對資料庫的依賴要更輕巧一些,原本支援不好的儲存過程就可以很自然的弱化了。

    第六是開源帶來的生態體系,開源紅利帶給企業的是很多的技術方案選擇,讓原本需要花錢買的事情變成了我們幹我們用。

    問題3:從Oracle遷移到MySQL需要考慮的事情

    首先是架構的差異,在oracle和MySQL裡面的差異還是比較大的,當然Oracle裡面也是可以使用同義詞的架構來實現類似MySQL的訪問模型的。

    資料型別的差異其實是比較具體的技術細節,我舉一些補充的。

    oracle裡面的Null和空串都可以按照null來處理,但是MySQL裡兩者是不同的。

    oracle表名,使用者名稱都是有長度限制,在30個字元以內,在MySQL里長度要大得多,尤其是表名就需要注意了。

    oracle裡會預設統一按照大寫來處理,MySQL裡面預設是大小寫敏感的。

    對於MySQL型別在MySQL裡需要考慮的細節較多,比如數值型,oracle裡面number搞定,MySQL有一系列的數值型別可以選擇,不建議大一統的big int適配所有需求。

    要更清晰的回答注意事項,可以歸類為一個問題:MySQL相比Oracle少了些什麼?

    效能上肯定有差異,我們主要理一理功能上的。比較的原則不是說oracle有一定要MySQL有,而是從一些使用場景上來說更好的使用特性。

    儲存過程支援有限,這是很多企業的技術債,處理好了是坦途,處理不好是大坑。比如儲存過程,硬要用儲存過程呼叫來對接,後期後患無窮。

    沒有同義詞

    沒有db link,這個特性MySQL裡不支援其實是件好事,杜絕了那種跨庫關聯的需求。

    沒有sequence,這個MySQL的自增列完全可以彌補。

    沒有物化檢視,難以實現增量重新整理的需求。

    分割槽表有,但是很少用

    最佳化器薄弱,多表關聯,Hash Join在MySQL裡還是一個弱項。

    索引的差異,覆蓋索引的實現兩者差異也很大。

    繫結變數的效能差異不大,Oracle裡面敏感的繫結變數問題在MySQL裡不是問題。

    效能工具,MySQL裡面的效能工具還是比較少的,而且粒度和效果有限。

    小結一下:

    遷移的本質是找到最適合的業務場景,而不是為了技術實現而實現

  • 2 # 愛可生雲資料庫

    OGG全稱為Oracle GoldenGate,是由Oracle官方提供的用於解決異構資料環境中資料複製的一個商業工具。相比於其它遷移工具OGG的優勢在於可以直接解析源端Oracle的redo log,因此能夠實現在不需要對原表結構做太多調整的前提下完成資料增量部分的遷移。本篇文章將重點介紹如何使用OGG實現Oracle到MySQL資料的平滑遷移,以及講述個人在遷移過程中所碰到問題的解決方案。

    (一)OGG邏輯架構

    參照上圖簡單給大家介紹下OGG邏輯架構,讓大家對OGG資料同步過程有個簡單瞭解,後面章節會詳細演示相關程序的配置方式,在OGG使用過程中主要涉及以下程序及檔案:

    Manager程序:需要源端跟目標端同時執行,主要作用是監控管理其它程序,報告錯誤,分配及清理資料儲存空間,釋出閾值報告等Extract程序:執行在資料庫源端,主要用於捕獲資料的變化,負責全量、增量資料的抽取Trails檔案:臨時存放在磁碟上的資料檔案Data Pump程序:執行在資料庫源端,屬於Extract程序的一個輔助程序,如果不配置Data Pump,Extract程序會將抽取的資料直接傳送到目標端的Trail檔案,如果配置了Data Pump,Extract程序會將資料抽取到本地Trail檔案,然後透過Data Pump程序傳送到目標端,配置Data Pump程序的主要好處是即使源端到目標端發生網路中斷,Extract程序依然不會終止Collector程序:接收源端傳輸過來的資料變化,並寫入本地Trail檔案中Replicat程序:讀取Trail檔案中記錄的資料變化,建立對應的DML語句並在目標端回放二、遷移方案(一)環境資訊OGG版本 OGG 12.2.0.2.2 For Oracle OGG 12.2.0.2.2 For MySQL 資料庫版本 Oracle 11.2.0.4 MySQL 5.7.21 OGG_HOME /home/oracle/ogg /opt/ogg (二)表結構遷移表結構遷移屬於難度不高但內容比較繁瑣的一步,我們在遷移表結構時使用了一個叫sqlines的開源工具,對於sqlines工具在MySQL端建立失敗及不符合預期的表結構再進行特殊處理,以此來提高表結構轉換的效率。注意:OGG在Oracle遷移MySQL的場景下不支援DDL語句同步,因此表結構遷移完成後到資料庫切換前儘量不要再修改表結構。(三)資料遷移資料同步的操作均採用OGG工具進行,考慮資料全量和增量的銜接,OGG需要先將增量同步的抽取程序啟動,抓取資料庫的redo log,待全量抽取結束後開啟增量資料回放,應用全量和增量這段期間產生的日誌資料,OGG可基於引數配置進行重複資料處理,所以使用OGG時優先將增量進行配置並啟用。此外,為了避免本章節篇幅過長,OGG引數將不再解釋,有需要的朋友可以檢視官方提供的Reference文件查詢任何你不理解的引數。1.源端OGG配置(1)Oracle資料庫配置針對Oracle資料庫,OGG需要資料庫開啟歸檔模式及增加輔助補充日誌、強制記錄日誌等來保障OGG可抓取到完整的日誌資訊檢視當前環境是否滿足要求,輸出結果如下圖所示:(2)Oracle資料庫OGG使用者建立OGG需要有一個使用者有許可權對資料庫的相關物件做操作,以下為涉及的許可權,該示例將建立一個使用者名稱和密碼均為ogg的Oracle資料庫使用者並授予以下許可權(3)源端OGG 管理程序(MGR)配置(4)源端OGG 表級補全日誌(trandata)配置表級補全日誌需要在最小補全日誌開啟的情況下才起作用,之前只在資料庫級開啟了最小補全日誌(alter database add supplemental log data;),redolog記錄的資訊還不夠全面,必須再使用add trandata開啟表級的補全日誌以獲得必要的資訊。(5)源端OGG 抽取程序(extract)配置Extract程序執行在資料庫源端,負責從源端資料表或日誌中捕獲資料。Extract程序利用其內在的checkpoint機制,週期性地檢查並記錄其讀寫的位置,通常是寫入到本地的trail檔案。這種機制是為了保證如果Extract程序終止或者作業系統宕機,我們重啟Extract程序後,GoldenGate能夠恢復到以前的狀態,從上一個斷點處繼續往下執行,而不會有任何資料損失。(6)源端OGG 傳輸程序(pump)配置pump程序執行在資料庫源端,其作用非常簡單。如果源端的Extract抽取程序使用了本地trail檔案,那麼pump程序就會把trail檔案以資料塊的形式透過TCP/IP協議傳送到目標端,Pump程序本質上是Extract程序的一種特殊形式,如果不使用trail檔案,那麼Extract程序在抽取完資料後,直接投遞到目標端。補充:pump程序啟動時需要與目標端的mgr程序進行連線,所以需要優先將目標端的mgr提前配置好,否則會報錯連線被拒絕,無法傳輸抽取的日誌檔案到目標端對應目錄下(7)源端OGG 異構mapping檔案(defgen)生成該檔案記錄了源庫需要複製的表的表結構定義資訊,在源庫生成該檔案後需要複製到目標庫的dirdef目錄,當目標庫的replica程序將傳輸過來的資料apply到目標庫時需要讀寫該檔案,同構的資料庫不需要進行該操作。2.目標端OGG配置(1)目標端MySQL資料庫配置確認MySQL端表結構已經存在MySQL資料庫OGG使用者建立mysql> create user "ogg"@"%" identified by "ogg";mysql> grant all on *.* to "ogg"@"%";#### 提前建立好ogg存放checkpoint表的資料庫mysql> create database ogg;(2)目標端OGG 管理程序(MGR)配置目標端的MGR程序和源端配置一樣,可直接將源端配置方式在目標端重複執行一次即可,該部分不在贅述(3)目標端OGG 檢查點日誌表(checkpoint)配置checkpoint表用來保障一個事務執行完成後,在MySQL資料庫從有一張表記錄當前的日誌回放點,與MySQL複製記錄binlog的GTID或position點類似。#### 切換至ogg軟體目錄並執行ggsci進入命令列終端shell> cd $OGG_HOMEshell> ggsciggsci> edit param ./GLOBALScheckpointtable ogg.ggs_checkpointggsci> dblogin sourcedb [email protected]:3306 userid oggggsci> add checkpointtable ogg.ggs_checkpoint(4)目標端OGG 回放執行緒(replicat)配置Replicat程序執行在目標端,是資料投遞的最後一站,負責讀取目標端Trail檔案中的內容,並將解析其解析為DML語句,然後應用到目標資料庫中。#### 切換至ogg軟體目錄並執行ggsci進入命令列終端shell> cd $OGG_HOMEshell> ggsci#### 新增一個回放執行緒並與源端pump程序傳輸過來的trail檔案關聯,並使用checkpoint表確保資料不丟失ggsci> add replicat r_cms,exttrail /opt/ogg/dirdat/ms,checkpointtable ogg.ggs_checkpoint#### 增加/編輯回放程序配置檔案ggsci> edit params r_cmsreplicat r_cmstargetdb [email protected]:3306,userid ogg,password oggsourcedefs /opt/ogg/dirdef/cms.defdiscardfile /opt/ogg/dirrpt/r_cms.dsc,append,megabytes 1024HANDLECOLLISIONSMAP cms.*,target cms.*;注意:replicat程序只需配置完成,無需啟動,待全量抽取完成後再啟動。至此源端環境配置完成 待全量資料抽取完畢後啟動目標端回放程序即可完成資料準實時同步。3.全量同步配置全量資料同步為一次性操作,當OGG軟體部署完成及增量抽取程序配置並啟動後,可配置1個特殊的extract程序從表中抽取資料,將抽取的資料儲存到目標端生成檔案,目標端同時啟動一個單次執行的replicat回放程序將資料解析並回放至目標資料庫中。(1)源端OGG 全量抽取程序(extract)配置#### 切換至ogg軟體目錄並執行ggsci進入命令列終端shell> cd $OGG_HOMEshell> ggsci#### 增加/編輯全量抽取程序配置檔案#### 其中RMTFILE指定抽取的資料直接傳送到遠端對應目錄下#### 注意:RMTFILE引數指定的檔案只支援2位字元,如果超過replicat則無法識別ggsci> edit params ei_cmsSOURCEISTABLESETENV (NLS_LANG = "AMERICAN_AMERICA.AL32UTF8")SETENV (ORACLE_SID=cms)SETENV (ORACLE_HOME=/data/oracle/11.2/db_1)USERID ogg@appdb,PASSWORD oggRMTHOST 17X.1X.84.121,MGRPORT 7809RMTFILE /opt/ogg/dirdat/ms,maxfiles 100,megabytes 1024,purgeTABLE cms.*;#### 啟動並檢視抽取程序正常shell> nohup ./extract paramfile ./dirprm/ei_cms.prm reportfile ./dirrpt/ei_cms.rpt &## 檢視日誌是否正常進行全量抽取shell> tail -f ./dirrpt/ei_cms.rpt(2)目標端OGG 全量回放程序(replicat)配置#### 切換至ogg軟體目錄並執行ggsci進入命令列終端shell> cd $OGG_HOMEshell> ggsciggsci> edit params ri_cmsSPECIALRUNEND RUNTIMETARGETDB [email protected]:3306,USERID ogg,PASSWORD oggEXTFILE /opt/ogg/dirdat/msDISCARDFILE ./dirrpt/ri_cms.dsc,purgeMAP cms.*,TARGET cms.*;#### 啟動並查看回放程序正常shell> nohup ./replicat paramfile ./dirprm/ri_cms.prm reportfile ./dirrpt/ri_cms.rpt &#### 檢視日誌是否正常進行全量回放shell> tail -f ./dirrpt/ri_cms.rpt三、資料校驗資料校驗是資料遷移過程中必不可少的環節,本章節提供給幾個資料校驗的思路共大家引數,校驗方式可以由以下幾個角度去實現:1.透過OGG日誌檢視全量、增量過程中discards記錄是否為0來判斷是否丟失資料;2.透過對源端、目標端的表執行count判斷資料量是否一致;3.編寫類似於pt-table-checksum校驗原理的程式,實現行級別一致性校驗,這種方式優缺點特別明顯,優點是能夠完全準確對資料內容進行校驗,缺點是需要遍歷每一行資料,校驗成本較高;4.相對摺中的資料校驗方式是透過業務角度,提前編寫好數十個返回結果較快的SQL,從業務角度抽樣校驗。四、遷移問題處理本章節將講述遷移過程中碰到的一些問題及相應的解決方式。(一)MySQL限制在Oracle到MySQL的表結構遷移過程中主要碰到以下兩個限制:1. Oracle端的表結構因為最初設計不嚴謹,存在大量的列使用varchar(4000)資料型別,導致遷移到MySQL後超出行限制,表結構無法建立。由於MySQL本身資料結構的限制,一個16K的資料頁最少要儲存兩行資料,因此單行資料不能超過65,535 bytes,因此針對這種情況有兩種解決方式:根據實際儲存資料的長度,對超長的varchar列進行收縮;對於無法收縮的列轉換資料型別為text,但這在使用過程中可能導致一些效能問題;2. 與第一點類似,在Innodb儲存引擎中,索引字首長度限制是767 bytes,若使用DYNAMIC、COMPRESSED行格式且開啟innodblargeprefix的場景下,這個限制是3072 bytes,即使用utf8mb4字符集時,最多隻能對varchar(768)的列建立索引;3. 使用ogg全量初始化同步時,若存在外來鍵約束,批次匯入時由於各表的插入順序不唯一,可能子表先插入資料而主表還未插入,導致報錯子表依賴的記錄不存在,因此建議資料遷移階段禁用主外來鍵約束,待遷移結束後再開啟。mysql>set global foreign_key_checks=off;(二)全量與增量銜接HANDLECOLLISIONS引數是實現OGG全量資料與增量資料銜接的關鍵,其實現原理是在全量抽取前先開啟增量抽取程序,抓去全量應用期間產生的redo log,當全量應用完成後,開啟增量回放程序,應用全量期間的增量資料。使用該引數後增量回放DML語句時主要有以下場景及處理邏輯:目標端不存在delete語句的記錄,忽略該問題並不記錄到discardfile目標端丟失update記錄- 更新的是主鍵值,update轉換成insert- 更新的鍵值是非主鍵,忽略該問題並不記錄到discardfile目標端重複insert已存在的主鍵值,這將被replicat程序轉換為UPDATE現有主鍵值的行(三)OGG版本選擇在OGG版本選擇上我們也根據使用者的場景多次更換了OGG版本,最初因為客戶的Oracle 資料庫版本為11.2.0.4,因此我們在選擇OGG版本時優先選擇使用了11版本,但是使用過程中發現,每次資料抽取生成的trail檔案達到2G左右時,OGG報錯連線中斷,檢視RMTFILE引數詳細說明了解到trail檔案預設限制為2G,後來我們替換OGG版本為12.3,使用MAXFILES引數控制生成多個指定大小的trail檔案,回放時Replicat程序也能自動輪轉讀取Trail檔案,最終解決該問題。但是如果不幸Oracle環境使用了Linux 5版本的系統,那麼你的OGG需要再降一個小版本,最高只能使用OGG 12.2。(四)無主鍵表處理在遷移過程中還碰到一個比較難搞的問題就是當前Oracle端存在大量表沒有主鍵。在MySQL中的表沒有主鍵這幾乎是不被允許的,因為很容易導致效能問題和主從延遲。同時在OGG遷移過程中表沒有主鍵也會產生一些隱患,比如對於沒有主鍵的表,OGG預設是將這個一行資料中所有的列拼湊起來作為唯一鍵,但實際還是可能存在重複資料導致資料同步異常,Oracle官方對此也提供了一個解決方案,透過對無主鍵表新增GUID列來作為行唯一標示,具體操作方式可以搜尋MOS文件ID 1271578.1進行檢視。(五)OGG安全規則報錯資訊2019-03-08 06:15:22 ERROR OGG-01201 Error reported by MGR : Access denied.錯誤資訊含義源端報錯表示為該抽取程序需要和目標端的mgr程序通訊,但是被拒絕,具體操作為:源端的extract程序需要與目標端mgr進行溝通,遠端將目標的replicat進行啟動,由於安全性現在而被拒絕連線。報錯原因在Oracle OGG 11版本後,增加了新特性安全性要求,如果需要遠端啟動目標端的replicat程序,需要在mgr節點增加訪問控制引數允許遠端呼叫解決辦法在源端和目標端的mgr節點上分別增加訪問控制規則並重啟## 表示該mgr節點允許(ALLOW)10.186網段(IPADDR)的所有型別程式(PROG *)進行連線訪問ACCESSRULE, PROG *, IPADDR 10.186.*.*, ALLOW(六)資料抽取方式報錯資訊2019-03-15 14:49:04 ERROR OGG-01192 Trying to use RMTTASK on data types which may be written as LOB chunks (Table: "UNIONPAYCMS.CMS_OT_CONTENT_RTF").報錯原因根據官方文件說明,當前直接透過Oracle資料庫抽取資料寫到MySQL這種initial-load方式,不支援LOBs資料型別,而表 UNIONPAYCMS.CMSOTCONTENT_RTF 則包含了CLOB欄位,無法進行傳輸,並且該方式不支援超過4k的欄位資料型別解決方法將抽取程序中的RMTTASK改為RMTFILE引數 官方建議將資料先抽取成檔案,再基於檔案資料解析進行初始化匯入

  • 中秋節和大豐收的關聯?
  • 喜歡穿暴露裝的女人是什麼心態?