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