攜程MySQL遷移OceanBase最佳實踐
一、前言
MySQL在業界流行多年,很好地支撐了攜程的業務發展。但隨著技術多元化及業務的不斷發展,MySQL也遇到了新的挑戰,主要體現在:業務數據模型呈現多元化,OLTP和OLAP出現融合的趨勢;在MySQL數據庫上慢查詢治理成本高;使用傳統的分庫分表方案對開發不友好,核心數據庫改造成分庫分表方案,時間一般以年為單位。
分布式數據庫能比較好地解決上述問題,同時也帶來了新的挑戰。2021年,OceanBase(簡稱OB)開源,攜程開始逐步探索OceanBase的基本特性和應用場景。OceanBase兼容大部分MySQL的功能和語法,同時提供水平擴展性、強一致性和高可用性,能滿足業務需求并降低運維成本。因此,我們開始推進部分MySQL實例遷移到OB。為保證遷移順暢,我們設計了遷移評估工具、OB遷移流程、OB監控大盤和OB故障診斷工具等。并將遷移過程中遇到的問題和大家進行分享。
二、評估工具
平滑遷移異構數據庫,我們需要進行兼容性、性能和分區適應性等各項檢查。提前把不兼容或有可能引起遷移異常的場景找出來并解決。官方提供了OceanBase Migration Assessment(OMA)工具,用于異構數據庫遷移到OB的可行性評估。遷移評估工具OMA有語法兼容性檢查和性能評估,但還不能完全滿足我們的需求。主要體現在下面幾點:
- 中間件版本檢查,一個DB有多個應用在訪問,只有某個版本后的中間件才開始支持OceanBase,需要檢查訪問該DB的所有應用的中間件版本,并督促開發進行升級,以確保都在支持OB版本之上。
- 性能采集和回放提供的MySQL General Log采集模式有一定風險,尤其是對于業務繁重的數據庫,我們需要更平滑的性能采集和回放方案。另外對于單實例多DB場景,存在遷移和不遷移的DB共存的情況,需要進行過濾。
- 線上存在非通過中間件訪問的數據庫賬號,如ETL取數賬號、數據查詢工具賬號、應用直連賬號等,對其兼容性需要進行檢查。因為遷移到OB之后,數據庫登錄賬號需要進行改變,包含租戶信息。
- OceanBase是分布式數據庫,數據如何進行分區就顯得非常重要,以避免形成熱點數據。一張表可能有多個字段都適合作為分區鍵,在遷移工具中,根據數據分布以及訪問情況,需要提供表分區推薦,以減少遷移成本。
因此我們對OMA評估工具進行了拓展和改造。在不影響現有的數據庫運行下,省去中間環節,做到一鍵評估。其中MySQL數據采集與分析大致流程示意圖如下,全量數據導入OceanBase后,目標端我們用開源Locust工具,進行SQL回放和壓測,并最終形成評估報告。
三、遷移流程
在評估流程完成并且評估結果符合遷移要求的前提下,可以發起MySQL到OceanBase自動遷移流程。為減少遷移成本,我們把遷移流程進行了封裝,做到一鍵自動遷移,自動切換包含以下流程:
1)遷移前配置校驗。遷移前,會集中對所有的切換注意事項和相關配置再進行一次全面的檢查,提前排除配置問題可能導致的切換風險。
2)MySQL賬號兼容OceanBase帶租戶賬號創建。由于OceanBase是多租戶管理模式,應用的連接串必須指定租戶名,因此相應賬號需要在目標OB集群預先創建,中間件或工具切換賬號時,只需重置連接并切換到新賬號即可。
3)數據一致性校驗。數據通過Canal從MySQL同步到OB后,我們需要對一致性做校驗。校驗的方法是根據表主鍵進行切分,進行結果集比較是否一致。當遇到熱點表時,數據校驗過程會發起多次嘗試來反復驗證。
4)DDL表結構修改暫停。由于MySQL和OceanBase表結構變更方式差異較大,當DB遷移從MySQL到OceanBase觸發流程后,我們會在源MySQL禁止DDL操作。當然,如果開發有緊急發布需求,我們可以廢棄流程,等DDL發布完成后,再重啟遷移流程。
5)反向同步鏈路搭建。無論前面的遷移評估或者流程多么完善,反向同步鏈路對于異構數據庫的遷移是必備的。一旦遷移出現異常,可以快速回退。反向同步鏈路是基于OceanBase的CDC服務,訂閱增量日志在MySQL端回放,保證遷移后OceanBase側和MySQL側數據始終一致。
當數據同步完成,并且沒有增量延遲后,遷移流程將生成具體的切換任務,切換流程如下:
我們只需要在預定的時間窗口內,點擊觸發切換流程,就可以完成從MySQL到OceanBase的切換。整個切換流程可在一分鐘之內完成,而且業務端無需進行改造。我們擁有反向鏈路,如碰到有異常情況,可以隨時安排回退。反向鏈路在正常情況下將保留兩周以上。
四、OceanBase監控
分布式數據庫和單機數據庫一個比較大的區別在于分布式監控比單機版數據庫更為復雜。一是因為組件眾多,需要有一個全局視點;二是因為需要對告警點進行聚合。業務新遷移到OceanBase時,觀察集群監控、關注告警信息是判斷遷移成功與否的關鍵。日常的冒煙現象或者不規范現象,需要及時發現、及時處理,避免問題惡化。準確監控和及時告警可以幫助運維人員快速定位問題,快速解決故障。
4.1 監控大盤
OceanBase的監控數據主要通過在每臺Server上部署的Agent程序從本地直接采集。Agent中包含眾多組件,內容如下:
Agent程序會向hickwall上報采集到的數據,以模板化的形式展示出來,以此形成監控大盤。如下圖所示:
4.2 告警郵件
OceanBase的告警,主要通過訂閱hickwall上的監控數據以及定時的服務巡檢來完成。基于采集的監控數據設立告警閾值,一旦指標超過閾值便會進行告警通知。另外,我們還會對配置進行定期檢查,來解決規范性問題等。
4.3 OceanBase SQL審計
OceanBase接入了攜程的SQL審計流程。與以往傳統的審計插件模式不同,現在以抓取網絡包的方式,通過對MySQL協議解析得到全量的SQL審計信息。接入審計流程后,可以快速定位到SQL信息,包括應用編號、訪問IP、執行參數、有無報錯信息等。
4.4 OceanBase審計運用案例
在使用MySQL command-line tool連接OceanBase過程中出現連接不上的錯誤時,我們使用SQL審計日志進行定位,發現客戶端在連接OB的過程中會執行一些元數據查詢工作,在進行show tables這一步驟后會報錯斷連,后續定位到一個特殊的表,該表表名的最后一個字符是分號(t_sample;)導致了這次報錯,隨即我們在開源社區反饋了這例問題。
五、OceanBase自動故障診斷
隨著越來越多的MySQL遷移到OceanBase,數據庫性能、故障定位的實時性和準確性的要求變得越來越高。自動故障診斷系統可以全方位、及時、精準地定位線上問題,為運維和排障提供依據。
5.1 構建實時性能數倉
OceanBase性能數倉構建的流程圖如下:
- 收集性能指標相關數據,以下是常用的性能指標對應的數據源:
- 開發數據收集程序,在服務器本地每10秒采集一次上述性能指標的數據。并在采集之后對數據進行結構化處理,包括對數值型數據進行標準化處理,對文本型數據進行時序化處理。
- 將結構化處理之后的數據落地存儲到ClickHouse中。
5.2 自動化分析
自動化分析的流程圖如下:
5.3 實時檢測性能指標
通常判斷性能異常的指標包括CPU占用率、磁盤IO占用率、Threads Running、QPS、網卡流量等。基于運維經驗,可以針對每個指標設定相應的閾值,當突破閾值時,則認為當前實例存在性能問題。比如CPU占用率高于65%或磁盤IO占用率高于80%則代表服務器出現異常。
5.4 異常數據匹配數倉
首先,對于數值型數據,分析工具會自動選取故障指標和故障時間段,通過相似性匹配數倉中數據所有數值型數據包含SQL、Table、Perf三種類型,它們相關的性能指標說明如下:
- SQL對應的性能指標:
執行次數、總耗時、CPU耗時、邏輯讀次數、物理讀次數等。
- Table對應的性能指標:
增刪改行數、增刪改的SQL數、相關事務數等。
- Perf對應的性能指標:
CPU、I/O、RPC時長、索引緩存大小、緩存命中率等。
其次,對于文本型數據,分析工具會通過故障時間區間獲取所有時序化的文本數據,通常包含:
- 數據庫服務日志、系統內部任務記錄、數據庫進程信息等。
最后,基于前面兩種類型的數據進行綜合性分析,分析要點主要有:
- SQL層面:
SQL性能消耗占比、有無正在執行的慢SQL、是否缺失索引、是否存在遠程執行或分布式執行等。
- OceanBase內部:
OceanBase是否在做合并、是否正在均衡副本、是否存在其他異常日志等。
- 應用層面:
客戶端是否進行發布。
最終基于以上自動化分析,實現服務器性能波動真實原因的精準定位,自動生成故障定位分析報告, 并通過郵件及時推送給DBA和相關開發人員。
5.5 運用案例
下面基于該工具自動生成的一例分析報告來介紹該工具的實際運用:
- 報告的故障指標板塊顯示4:30后服務器的CPU上升;
- 報告的OceanBase相關表板塊顯示CPU上升趨勢和下面這張表的訪問趨勢一致;
- 報告的OceanBase相關SQL板塊顯示這張表的訪問趨勢和下面的SQL語句訪問趨勢一致;
- 報告的分析結果板塊定位到CPU上升和tablex表的訪問上升有關,而這張表的訪問上升又和這1條SQL語句訪問耗時增長有關,最終定位由于該SQL導致CPU上升。后續我們聯系開發確認是正常業務上升,并添加服務器節點緩解CPU負載。
六、遷移遇到的問題和實踐
6.1 .Net應用訪問OceanBase失敗
在使用和測試OceanBase的過程中,我們發現.Net應用的官方MySQL連接器連接OceanBase執行SQL失敗。
經排查,我們發現.Net應用依賴連接中的ConnectionCharSetIndex,而OceanBase不存在Cnotallow=83即utf8_bin,只有utf8mb4_bin。因此我們對OceanBase的源碼進行了修復來滿足這類應用對OceaBase的適配性。
總結:OceanBase不夠完美,但是隨著時間推移,通過反復的測試和迭代,正在逐步完善它的各方各面。我們也參與其中,以運維和產品使用者的視角對它進行優化和完善。
6.2 Druid應用不兼容部分OB語法解析
我們在開發Oceanbase表結構設計工具的時候,發現OceanBase的SQL通過Druid解析時存在報錯。這個錯誤會導致在表結構設計的時候導入SQL DDL語句報錯。遇到問題后,我們先調整到Druid最新版本,發現問題仍然存在。
我們將問題先從復雜的表結構設計中抽離出最簡單的SQL DDL, 并結合分析Druid的源代碼,發現原來Druid代碼對OceanBase的兼容在SQLIndexDefinition中實現,但沒有在SQLIndexOptions實現。根據OceanBase的語法樹,實際應該在SQLIndexOptions實現才合理,找到問題所在后,我們提交了Pull Request, 然后被合并到Druild主線。問題得以解決。
總結:開源工具的一個好處在于碰到問題后我們可以進行代碼分析。并快速定位問題,最后反饋社區。
6.3 OceanBase讀寫分離支持
讀寫分離是數據庫非常重要的能力,在業務層面上,它覆蓋到了ETL取數,BI報表生成,緩存刷新等多個場景。Oceanbase雖然支持讀寫分離功能,但需要在代碼層顯性設置弱一致性讀參數,存在對業務高度侵入的缺陷。我們對OceanBase訪問代理OBProxy做了代碼改造,新增enable_weak_read以及weak_read_user_list兩個參數,通過代理層控制開啟讀寫分離策略,對應用透明度高。
讀寫分離場景下,應用與OBProxy建聯的流程示意圖如下:
基于以上的代碼修改,我們設計了一套優化版本的讀寫分離方案,即通過以賬號維度來控制是否使用讀寫分離。流量調度示意圖如下:
總結:OceanBase源生雖然提供了強大的功能,但是它并不一定100%滿足業務的場景和需求,因此對其組件進行二次開發是有必要的。我們不單單對于OBProxy進行了相關的功能適配,對于其他組件如cdc、Deploy組件等我們也根據實際場景需求,進行相應調整。
6.4 query range過大導致內存溢出
在初期使用OceanBase時,我們有碰到過Server Crash的經歷。當一個查詢的條件中IN運算符中包含過多元素(一萬級別以上)時,會爆出stack overflow的異常。
經過分析和社區交流,我們定位到優化器在抽取query range會耗費大量的內存。而OceanBase在算法迭代過程中沒有檢查查詢超時,導致該查詢一直消耗內存,直到用盡了 SQL ARENA的內存。這種模式沒有做好防御機制,從而導致內存溢出造成系統崩潰。這個問題在新版本中已經得到修復。當確認到問題后,我們第一時間通知開發減少IN內的元素數量,并安排了版本升級。
總結:OceanBase作為新鮮產品,社區論壇和Git issue是獲取日常運維和快速排障方案的利器,根據各種技術探索和交流分享,可以汲取優質內容,收獲前沿知識,快速定位和解決問題。
6.5 修正執行計劃
在遷移前后,數據庫的SQL性能是最值得關注的地方。作為分布式數據庫,OceanBase的優化器相較于MySQL來說更復雜并且由于其特殊的存儲結構導致表的統計直方圖刷新頻率很低,因此當可用索引和查詢條件的適配度不高時,優化器在選擇執行計劃時可能存在偏差。OceanBase自帶修正執行計劃的能力,即通過在數據庫層面直接指定同類型SQL以outline注釋的方法強制綁定執行計劃。
總結:OceanBase相較于傳統數據庫,其分布式的架構和特殊的存儲結構也會帶來運維門檻的提高,不過它同時也給予運維人員更高的自由度。運維人員需要熟悉并掌握這些強大的功能和運維技巧,使線上業務具備更好的穩定性。
七、未來展望
OceanBase開源已經一年有余,我們的運維工具也逐漸趨于成熟,運維能力也在逐步提高。越來越多的MySQL正在逐步往OceanBase上遷移。隨著OceanBase 4.0版本的推出,許多新特性也已經在逐步測試中。我們對4.0版本的新功能也非常期待。
7.1 單機分布式一體化架構
OceanBase 4.0版本推出單機分布式一體化架構,支持類似MySQL的輕量化單機模式部署,同時也可以在必要時迅速地擴容成分布式模式來提高性能上限。單機與分布式的靈活切換可以大大降低成本,并且基于源生主備庫的能力可以快速的完成主備的DR切換,有更強的高可用性保證。
7.2 兼容性增強
OceanBase對MySQL的高兼容性一直是我們考量的重點,高度兼容為開發同事節省了大量學習成本和代碼成本。在4.0版本中,在字符集、約束、函數、存儲過程等多方面與MySQL的匹配度更高,在使用上與MySQL更加接近。
當然,兼容性還包括對MySQL生態的兼容,包括binlog兼容、canal兼容、閃回工具兼容等等。
7.3 運維能力提升
OceanBase作為分布式數據庫,組件多、運維環境復雜是痛點。我們后續將基于現有的日志收集工具和分析工具,完成鏈路式的問題診斷,更精準地定位性能問題、集群內部任務問題等。