通過DTS進行多表歸并任務時,若在源庫執行Online DDL操作,則會導致目標庫數據丟失。本文介紹如何避免這種情況的發生。

問題描述

在通過DTS進行多表歸并任務時,若在源庫進行Online DDL操作,對源庫的表結構等進行了調整修改,則同步到目標庫時,會出現數據丟失的情況。

說明 多表歸并任務指將不同源庫的表進行歸并,繼而同步或遷移到目標庫。
例如:當用戶配置了從源庫1 RDS MySQL和源庫2 RDS MySQL到目標庫RDS MySQL的多表歸并任務,則數據遷移的邏輯如下:
  • 源庫1的表A1遷移至目標庫表A。
  • 源庫2的表A2遷移至目標庫表A。

假設源庫1的表A1中100條記錄,源庫2的表A2中200條記錄,則多表歸并后,目標庫表A中應有300條記錄。

問題示例

以RDS MySQL(源庫)向RDS MySQL(目標庫)進行多表歸并任務為例,說明源庫進行Online DDL操作導致目標庫數據缺失的情況。

多表歸并場景:用戶配置了從源庫1 RDS MySQL和源庫2 RDS MySQL到目標庫RDS MySQL的多表歸并任務,數據遷移邏輯如下:
  • 源庫1的表A1遷移至目標庫表A。
  • 源庫2的表A2遷移至目標庫表A。

假設源庫1的表A1中100條記錄,源庫2的表A2中200條記錄,則多表歸并后,目標庫表A中應有300條記錄。

在源庫1的表A1中進行了如下Online DDL操作:
說明 Online DDL操作,參見通過無鎖變更工單實現無鎖結構變更
  • 創建臨時表:
    CREATE TABLE tmp_table_table LIKE table_name
  • 變更臨時表結構:
     ALTER TABLE tmp_table_table XXXX
  • 全量拷貝數據:
    INSERT IGNORE INTO tmp_table_table (SELECT %s FROM table_name FORCE INDEX (%s) WHERE xxx
  • 增量數據Binlog同步:
    UPDATA/INSERT/DELETE tmp_table_name
  • 切換新舊表:
    RENAME TABLE table_name to old_tmp_table_table, tmp_table_name to table_name

在上面的內部處理中,會創建臨時表、變更臨時表結構、并將原始表的全量數據拷貝到臨時表,最后會使用 rename 命令將臨時表切換成新的業務表。這樣的處理同步到目的端的結果,會導致源庫1的表A1的數據替換了目標庫表A的數據,源庫2的表A2的數據就丟失了。

可能原因

Online DDL操作的內部機制導致了源端的數據會覆蓋目標端的數據。

解決方案

  • 任務設置時,設置為不同步Online DDL操作。
  • 禁止在源端執行Online DDL操作。