激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - 數據庫技術 - 異構數據庫遷移的九個大坑怎么躲開

異構數據庫遷移的九個大坑怎么躲開

2022-03-08 22:38ITPUB黎君原 數據庫技術

在開源技術使用日益廣泛的今天,筆者也可能突然被要求用一個新工具同步數據到一個新數據庫,時間還可能更緊迫。到時怎么辦呢?

“貳過”,重犯同一過失的意思,語出《論語》,完整句子為“不遷怒不貳過”,乃仲尼對其不幸早逝的弟子顏回的極高評價。就it項目而言,從管理者的角度來說,一個錯誤犯兩次,別說是同一個人了,哪怕是同一團隊的不同人也不可接受。說到這里,不由得腦補出一位平時慈眉善目的老領導作嗔怒狀,大喊“干掉干掉”的恐怖場面。不重犯同一錯誤真的很難嗎,實話實說,確實難,君不聞,人類從歷史中得到的最大教訓就是從不吸取教訓。

異構數據庫遷移的九個大坑怎么躲開

筆者上述感嘆的背后是有故事的。那是本世紀最“2”的一天,筆者在排查Oracle到ADB(此處指ADB PG,全稱AnalyticDB PostgreSQL版,是阿里的MPP架構的數據庫)之間數據實時同步過程中,突然發現自己埋了個大雷——沒區分空值和空字符串,導致同樣的字段值在全量同步階段標志為空字符串,增量同步階段則標志為空值,這顯然不是一種合乎邏輯的行為。

其實在發現這個問題前,筆者已經在這項目中苦苦掙扎了一個月,在此之前的兩天,筆者自以為數據質量已經完全沒問題,數據同步達到“又不是不能用”的境界了(筆者注:此處能用是真的能用,非為上線而上線那種能用)。Oracle DB本身確實不區分空值和空字符串,對于搞Oracle出身的工程師,沒意識到這個似乎情有可原,然而筆者作為搬磚佬,已經前前后后搬了十幾年,數據庫異構遷移項目也認認真真地做過好幾個,這件事對筆者而言,其實無異于“低級錯誤”。

回想起來,這個項目筆者做得甚是狼狽,這里面固然有進度緊以及新工具、新技術引入需要邊學邊用的客觀因素,但這不足以平息筆者對自己的憤怒。問題來了,在開源技術使用日益廣泛的今天,筆者也可能突然被要求用一個新工具同步數據到一個新數據庫,時間還可能更緊迫。到時怎么辦呢?再憤怒一次嗎?不了不了,還是腳踏實地總結一下,記下這些坑,日后類似項目,哪怕被拿著槍指著頭也好,下述問題都要在前期階段予以考慮。

一、空值和空字符串

對于Oracle DB??,空值和空字符串是同?回事,其中判斷某個值是否為空值/空字符串統?使?"IS NULL"即可,?于=''是?效的。

這點對于其余數據庫來說,可真不?定了。就源端為Oracle DB,?標端為其余數據庫的項???,我們需要與開發商確認好,?標端究竟?哪種值表?源端的空值/空字符。?對于實時同步的項?來說,還需要在全量同步以及增量同步期間保持數據的?致。

除了空值和空字符串以外,其實還有?個隱藏的?boss——固定?度類型中的空格值。以Oracle DB為例,char類型?于存放固定?度的字符串,??度不?的字符串則會被?動補充空格,對于這種值,?論是char_col=''還是char_col is null均?法識別,只能通過trim(char_col) is null識別,對此值使?length函數會返回本字段的?度,?個?0值。?這種數據同步到adb后則表現有?定差異了,char_col=''可以識別這種數據(哪怕ADB中也是?了固定?度的數據類型),然?對這個值使?char_length函數,結果會返回0,如果實在要把這種數據抓出來,我們還得加?個條件oct_length(char_col)>0。很明顯,這?是?個坑!

二、數據類型轉換問題

筆者的朋友阿強一直立志做一個溫文儒雅的人,嗯,前提是不要讓他“寫材料”、“擦屁股”以及“估算工作量”!沒錯,“估算工作量”對他這種以txt狂魔自稱的人來說是一種煎熬,光說起這個詞,他已經腦補出把pm按在地上,一邊揍一邊說,“我想做個好人,為什么要逼我”?問題來了,如果讓阿強估算這個數據類型轉換的工作量,估計他連40米的刀都可以拿出來了。

跨數據庫的表字段數據類型轉換工作主要涉及“精度”、“效率”、以及“兼容性”等方面。部分數據同步軟件確實具備自動轉換的功能,然而這種情況,僅對于管理規范的數據庫適用,不規范的庫則需要耗費較大精力了,下面舉幾個典型的例子說明這個問題:

以從Oracle DB到PG的同步為例,整型的值固然可以通過number類型(不設定精度和小數位)存放到源端Oracle數據庫中,問題來了,PG中應該用啥字段對應了,僅僅安全起見,免得精度丟失,那肯定是numeric類型,然而這毫無疑問存在性能損失。Bigint等類型自然是更好的選擇,可是這又牽涉到與開發商溝通這樣有沒有可能導致應用報錯等情況了,這又是一個工作量。

以從Oracle DB到DB2的同步為例,DB2有一個隱性要求,組成主鍵的字段值前后不能包含空格,否則會被過濾掉,這樣會造成一些在源端Oracle數據庫本來就不相同的兩條記錄的在目標端DB2庫被誤判為同一條記錄進而引發數據沖突,影響數據同步。

不要問為什么要在id類字段加空格:

  • 這是合法的;
  • 這未嘗不是一種有創意的備份數據方法。

這么干,真的,沒毛病!

以從Oracle DB到ADB的同步為例,由于MPP架構需要,我們需要額外指定DISTRIBUTED列。對于ADB而言,這里還有一個附帶的要求,這個列應當為主鍵的一部分。

以Oracle DB到HBase的同步為例,HBase是強制要求有主鍵的,否則不能同步。之前的項目中,筆者被迫無奈拿Oracle的轉換后的ROWID作為HBase的rowkey,滿足其同步前置條件。

為什么是轉換后?這又是另一個故事了,這里就不展開了,只提示個關鍵詞,“預分區”。

嗯嗯,這明顯是個坑。那種由開發商定表結構的項目得心存感激,真的!

三、字符集轉換問題

字符集轉換深究起來其實并不是容易的事情,幾年前筆者所參與的一個O2O同步(即Oracle到Oracle的同步,下同) 遷移項目中,涉及了BIG5到UTF8的轉換,當時的同步工具為OGG。這個項目中各種亂七八糟的數據至今仍然對筆者歷歷在目,當然,這也讓筆者能更有經驗地處理異構數據庫同步中的字符集轉換問題。

跨字符集轉換的工作其實陷阱不少,因此,條件允許的話,筆者建議盡量規避。當然,遇到PG這種服務器端不支持GBK,而源端Oracle DB偏偏是GBK的情況,那只好迎難而上了,下面為筆者的建議:

  • 涉及中文的情況,所見非所得,判斷一條中文記錄是否正常的依據,應該為其十六進制編碼是否正常。對于Oracle DB而言,我們可以用dump函數,其余DB需要找到類似的。
  • 中文為多字節字符,在不同的字符集下占用的字節數并不一致,典型例子為GBK為2字節,UTF8為3字節。目標端環境可能需要相應調整字節寬度。
  • 不同字符集所涵蓋的漢字是不一樣的,例如BIG5中就沒有“邨”字。
  • 字符集中有一個“自定義”區域,如不進行特殊處理,有可能導致數據丟失。

“亂碼”會造成很大的困擾,對于Oracle DB而言,大致有如下幾種情況:

  • 無法通過Oracle自帶convert函數轉換為目標庫編碼,以ADB為例,這部分數據會導致GPFDIST導入失敗,進而影響數據全量同步。
  • 可以通過Oracle自帶convert函數轉換為目標庫編碼,但無法重新轉換為原有數據,這部分數據會有潛在的數據丟失影響,對于遷移類項目需要重點關注是否涉及“自定義”字符區域。
  • 含義不明的單字節字符,如chr(0)、chr(255),這些字符往往夾雜在正常的字符中,以ADB為例,涉及dts( Data Transmission Service, 數據傳輸服務,系阿里的數據同步工具/服務)增量同步的話,相應記錄有數據一致性風險。

四、特殊字符處理

對于數據庫異構同步而言,特殊的字符,諸如單引號、雙引號、換行、斜杠、反斜杠等等也是一個困擾項,這一點在數據全量同步階段尤其明顯。

對于文本方式的全量數據同步來說,我們可以考慮下述幾種方式:

  • 使用CSV格式;
  • 使用多字節分隔符;
  • 進行數據清洗;
  • 僅同步“正常”數據,“特殊”數據另行處理。

五、異常記錄處理

這里的異常記錄,指的是那種本身就違反數據庫規范,不應該插入到數據庫中的記錄。

以Oracle DB為例,筆者遇到的記錄有異常日期格式以及異常數值兩類。

異常日期格式,典型例子有"0000-00-00 00:00:00"和"2022-02-30 00:00:00"。筆者在好幾個客戶環境都遇過這種數據,以至于筆者覺得這很“常見”,需要加到測試項目里面。筆者這段時間做的Oracle到ADB同步項目確實遇到這種數據了,后者還造成dts的增量同步中斷,風險很高。所幸筆者的dts源端庫是基于OGG的目標庫部署的,Oracle自己的OGG工具也不能同步這種數據,這間接地擋了這部分異常的增量數據。在此基礎上,筆者只需要修復已有的異常數據即可,修復方法也很簡單,先+1再-1能修復大部分數據,至于不能修復的只能和業務協商重置一個值了。

異常數值類型,典型例子為NaN(即Not a Number),筆者僅在一個客戶環境中遇到,當時的場景為O2O同步 ,比較可怕的是連基本“來者不拒”的數據泵都無法同步這種數據。考慮到這個環境沒遇過這種數據,筆者這次偷懶了,沒做相應的測試。

六、全量同步測試

通常情況下,各種數據同步軟件都會自帶全量數據同步的功能,至于這個功能的效率、資源消耗、空間占用等項目需要進行評估。如果其不能滿足需求,則可能需要考慮替代的手段。

在選取測試表的時候,筆者考慮綜合下面幾個因素選擇幾個測試表:

  • 需要包括大表,大表往往是個瓶頸項;
  • 需要囊括本次同步涉及表的字段類型;
  • 如果環境中存在中文等多字節數據,則建議包含這種表;
  • 建議找靜態的表或者準靜態進行測試,以方便核對數據一致性。

七、增量同步測試

作為數據同步項目,同步效率是一個重要因素,筆者建議在搭建完整的同步鏈路之前,拿數據變更頻繁的關鍵表進行測試,通過單表單進程的方式,剔除潛在的配置不當風險。

對于這方面,筆者建議如下:

  • 盡量使用真實的數據;
  • 筆者這次測試通過Ogg同步增量數據,比較切合生產實際變更情況,這種方式可以參考。

增量同步發起后,在目標數據庫后臺觀察對應的SQL語句。以筆者本次項目為例,這個階段發現了兩個問題:

  • 由于大小寫敏感問題,dts目標側未成功識別出主鍵,導致所有字段被加到where條件,影響效率,此問題后來通過修改同步配置解決。
  • 筆者觀察到dts側雖然設置了高并發度,但實際運行中,僅個別進程工作,其余處于空閑狀態,無法充分利用資源。此問題后來通過修改配置參數解決。

八、數據一致性測試

數據一致性又是一個可以另外寫一篇文章的話題,對此,筆者建議如下:

  • 對比靜態或者準靜態的數據。很顯然,筆者這次使用的ogg中間庫方案很切合這個主題,如果沒這個,筆者只能通過停止同步進程后反查其停在哪個點,再用這個時間點做檢驗了。這個想法理論上可行,然而以筆者對dts的淺薄理解,這條路并不通,原因在于dts所停的時間點并不完全準確。
  • 活用md5函數。大部分正經的數據庫均包含內置的md5函數(PS:無意內涵DB2,真不是故意的),這可以將一個復雜的字符串簡化,以便用于運算確認兩端的數據一致性。

九、軟件局限性

“越是漂亮的女人就越會騙人,記住啊!”

“不光是漂亮的女人不能相信,連貌似忠良的男人也不能相信。”

我覺得這段對話充分展示了一個產品的售前與售后的結局——殊途同歸。對于售前來說,拼指標、造場景、講故事等等手段都是為了證明我家產品很棒,快來買買買;就售后而言,找到產品的痛點,予以規避,以達到保證工作順利開展,避免一口大鍋從天而降的目的。大家都是靠博弈而生的,沒什么兩樣,手里的牌均是對技術的了解。

扯遠了,回到it項目中,異構數據庫的同步往往是邏輯的同步方式,這種方式必然有各種瓶頸的。對售后來說,再怎么謾罵售前“管殺不管埋”也無濟于事,最現實的做法莫過于:找到短板,通過改善流程、優化需求甚至協同開發商改造應用的方式保證軟件的穩定運行。

這里先講個故事。Timesten是Oracle的內存數據庫,其Cachegroup功能可以實現從物理庫(即Oracle DB)到內存庫的實時數據同步,而這個同步延遲對業務穩定運行是非常關鍵的。在實際使用中,運維人員總結出的經驗就是得規避大事務變更,最終他們與開發商達成相應的操作規范,無論是業務變更需求也好,數據庫運維發起的清理作業也罷,如涉及Timestens同步的表,都得遵循變更量達10w萬就得分批提交,每個批次2萬條記錄,每批次之間sleep 30秒的硬性規定。我覺得這個故事的結局很完滿了,真的,要是換成非得揪著Timesten不放,意圖純粹靠軟件解決問題的話,那才是妥妥的災難現場呢,畢竟其基于trigger的同步機制從原理上就對大事務極不友好……

問題來了,如何找到軟件的短板呢?

閱讀官方文檔自然是一個渠道,當然,閱讀也是有“技巧” 的 :

我們支持xx指標以內的場景,這句話可以理解為超過這個您就得想想辦法了,同時,這個值也許是要打個折的,畢竟環境不一樣,存在差異也是很合理的。

我們支持功能a,也支持功能b,這都是實話,至于同時支持功能a和b是您自己認為的,我可沒說。

這個嘛,春秋筆法是有的,這種玩法自古就有了。陳壽不也沒在《三國志》里面明說司馬昭弒君嗎,后來大家不都知道了嗎?

除了文檔以外,我們還可以考慮結合自身經驗考慮下述點。

大事務測試

分別對同步范圍內外的對象做批量操作,加大數據庫日志量,觀察其對數據同步以及系統的影響,具體包括cpu、內存、io、空間等資源消耗以及同步延遲等。

以dts為例,源端oracle數據庫產生的所有數據均會被拉到dts的庫中分析,哪怕這數據與我們的同步策略無關。

目前有個黑名單功能可以繞過這問題。

長事務測試

包含啟動增量同步前開啟的事務能否正常同步、長時間未提交的事務是否影響同步進程重啟等維度。

很明顯, 這是被ogg嚇到的結果。

頻繁事務測試

筆者曾在O2O同步環境中遇到某應用使用了大量with as語法,后者隱式開啟了大量的短事務,進而短時間內事務量暴漲,進而 導致同步軟件Ogg抽取進程出現延遲。這個問題后來找開發商修改語句就解決了,然而其對筆者的心理陰影一直都在,以至于每遇到一個新場景,均會想想會不會遇到類似的問題。

事務順序

這個探究的是,軟件同步是否能保持事務的順序,如不能保持,那就得多留個心眼了,這種情況輕則導致同步延遲誤判,重則導致舊 數據覆蓋新數據,影響數據一致性。

一個簡單的測試樣例為,創建一個周期性(如每分鐘)更新的時間戳表,這個表的記錄數與源端Oracle DB的節點數一致。定時腳本依次連接各個實例并以當前時間更新相應的字段,在目標端,我們可以通過查詢時間點表觀察會不會出現下面兩種情況:

  • 后更新的數據是否會先被查詢出來;
  • 同步出現延遲的話,時間戳表記錄的時間會不會與同步進程的時間戳保持一致。

批量ddl測試

對于基于數據庫日志的同步工具,大批量的DDL語句很可能會觸發源端解析緩慢的情況,畢竟這涉及與數據字典的交互。

筆者曾遇過某個基于Ogg的O2O同步環境遇到這種瓶頸,而最終的解決方案為調整開發商版本上載的腳本,加大DDL語句之間等待時間間隔。

基于同步原理短板的探究

對于基于rowid的同步方案,沒啥好說的,只能從規范上減少move、shrink等改變rowid操作,實在要操作的話,需要重新同步相應的數據。

對于基于主鍵的同步方案,則重點考慮如何處理無主鍵表如何處理。

進程重啟測試

包含兩種場景,正常重啟以及異常重啟。

異常重啟即高可用方面的,具體不展開了;至于正常重啟的話,需要觀察進程的一些自定義參數會不會被重置。

原文地址:https://cloud.it168.com/a2022/0308/6634/000006634147.shtml

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 激情久久一区二区 | 91网址在线播放 | 欧美性生交xxxxx免费观看 | 欧美日韩在线中文字幕 | 一本免费视频 | 欧美一区二区三区成人 | 免费毛片电影 | free japan xxxxhdsex69 | jizzjizzjizz少妇 | 一区二区久久久久草草 | 成人毛片免费在线 | 亚洲乱妇19p| 一边吃奶一边摸下娇喘 | 99精品视频一区二区 | 久久久精品网 | 国产成视频在线观看 | 99视频在线观看视频 | 欧美日韩精品一区二区三区蜜桃 | 国产成人在线网站 | 国产精品啪一品二区三区粉嫩 | 欧美成人黄色 | 国产国语毛片 | 欧美成人精品一区二区三区 | 在线91视频| 亚洲99影视一区二区三区 | 黄网站色成年大片免费高 | 永久免费不卡在线观看黄网站 | 最新黄色av | 亚洲最大中文字幕 | 羞羞视频在线免费 | 夜夜看 | 黄色网址www| 麻豆视频在线观看 | 欧美hdfree性xxxx | 中国a毛片 | 九九热在线精品视频 | 日本a级免费 | 国产精品视频久久久 | 免费a级黄色片 | 日本在线播放一区二区三区 | 日韩精品一区二区在线 |