mysql之DTS的那些事


最近才考慮數據庫遷移,想起了之前做DTS踩過的那些坑。

DTS同步binlog,開始是使用binlog event + position方式,之后追加支持了GTID。

基於數據庫遷移,比如從源A庫遷移到源B庫,包括但不限於數據庫上雲。

數據庫遷移方案有兩種場景:

(1)、停機遷移方案【停服時間比較長】

    這種方案是允許停服的場景,通過mysqldump就搞定了,就不說了。

(2)、在線不停機方案【最多只是切庫的時間點,停服重部服務一下,停服時間很短。若不停服,就得想辦法處理切為時間點的新產生的BINLOG】

     這種場景方案中,我們采用先在線整庫遷移,然后在通過binlog在線DTS對齊數據。

     步驟如下:

         1、源數據庫采用ROW模式,開啟binlog權限

         2、需要一個源庫的全局schema查詢用戶,獲取源數據庫的schema同步到目標庫

         3、選取某個時間點的BINLOG OFFSET做標記,然后通過JDBC同步整個庫表數據到目標庫,直至完畢。

         4、通過netty服務單線程讀取源庫BINLOG數據,從上一步標記的offset位置開始讀取,讀入kafka。

         5、多線程消費kafka數據到目標庫,直至同步到最新的binlog數據,遷移完成。

 

第二種方案中遇到的那些坑:

   1、最好選取源庫的一個只讀庫做為同步數據的源庫,這樣不影響源庫線上業務。另外開始同步整庫時,需要選取當前Offset位置以備增量同步時使用,並且整庫同步期間禁止寫入或至少禁止修改schema操作(減少后面增量同步binlog時的程序報錯,及異常表手動處理的成本)。

   2、多線程消費kafka時,容易出現binlog順序錯亂的問題,目前采用按表寫partition的方式,指定partitions消費,避免順序錯亂,但帶來的新問題就是kafka的各partitions數據傾斜問題。

   3、目前解析binlog同步數據時,DDL和DML操作沒有特殊分別處理,如果數據量比較 大時,DDL很容易超時,導致此DDL之后同步的binlog都有問題,需要重新同步

   4、同步binlog時,指定時間窗口大小,記錄同步時的binlog位置到zk上,如果需要重新同步數據,可能會導致一部分binlog重復同步。如果窗口過小,zk也扛不住

   5、遇到沒有主鍵或唯一性限制的表,重復同步,會導致數據重復

   6、若遇到同步blob相關類型時,若二進制數據過大,可能導致同步失敗

   7、同步服務的部署問題,源庫和目標庫都需要開公網IP。

   8、同步服務的效率和源庫、目標庫的網絡帶寬,數據庫配置息息相關

   9、由於業務在正常的運轉的,需要找個時間點校驗數據的完整性,在業務流量低時,手動停止同步,線上服務切到新庫,(這樣需要處理切庫時的binlog,最好短時停服切庫)

   10、一旦開始同步,在手動停止同步之前,不能修改DDL,否則會導致同步任務失敗

   11、存儲過程及視圖不會同步,需要切庫后,手動處理

 

備注:

    1、 GTID最初由google實現,MySQL 從5.6.5 新增了基於 GTID 的復制方式。通過 GTID 保證了每個在主庫上提交的事務在集群中有一個唯一的ID。這種方式強化了數據庫的主備一致性,故障恢復以及容錯能力。GTID (Global Transaction ID)是全局事務ID,當在主庫上提交事務或者被從庫應用時,可以定位和追蹤每一個事務。

    2、查看當前的Binlog最終偏移量方法

       ## 獲取binlog文件列表,找到最新的binlog文件
          mysql> show binary logs;

          mysql> show binlog events in 'binlog.0000MAX';  ##查來下面的End_log_pos,就是最新的binlog偏移量了

               | Log_name | Pos | Event_type | Server_id | End_log_pos | Info


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM