通過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操作。