作者: 大鱼海棠 原文来源: https://tidb.net/blog/4540ae34
一、概述
DM有all、full、incremental三种数据迁移同步方式(task-mode),在all同步模式下,因一些特殊情况,需要变更上游MySQL的数据源IP,一般有如下几种处理方式:
- 放弃已同步的数据,重新用all模式同步(适合数据量比较小的场景,操作简单)
- 记录同步到的位点信息,停掉task和数据源,将同步模式改为incremental并在task配置中指定MySQL示例的位点信息重新拉起任务
task中meta配置下游数据库的 checkpoint 不存在时 binlog 迁移开始的位置; 如果 checkpoint 存在,则以 checkpoint 为准。如果 meta 项和下游数据库的 checkpoint 都不存在,则从上游当前最新的 binlog 位置开始迁移
- 不修改task-mode的情况下,基于检查点断点续传, 本文主要基于该场景测试
二、MySQL环境准备
mysql
set global validate_password_mixed_case_count=0;
set global validate_password_policy='LOW'; 
set global validate_password_number_count=0; 
set global validate_password_special_char_count=0;
set global validate_password_length=4;
alter user root@'localhost' identified by 'dm_test'; 
配置文件
[mysqld]                                                                                                                                                                        
datadir=/mysql57/data                                                                                                                                                           
socket=/var/lib/mysql/mysql.sock                                                                                                                                                
symbolic-links=0                                                                                                                                                                
binlog_format=ROW                                                                                                                                                               
log_bin=/mysql57/logbin/logbin                                                                                                                                                  
log-error=/mysql57/log/mysqld.log                                                                                                                                               
pid-file=/var/run/mysqld/mysqld.pid                                                                                                                                             
gtid_mode=ON                                                                                                                                                                    
enforce_gtid_consistency=ON  
# 主从使用不同的server_id                                                                                                                                                   
server_id=2 
# 从库开启binlog记录                                                                                                                                                                 
log-slave-updates = 1
主从搭建
reset master;
change master to master_host='172.1.1.4', master_user='root', master_password='dm_test', master_port=3306, master_auto_position=1;
start slave;
show slave status\G
三、DM任务创建
1. 创建数据源
创建数据源配置文件
[tidb@vm10-2-103-112 ~]$ cat source-01.yaml                                                                                                                                     
source-id: "mysql-01"
enable-gtid: true                                                                                                                                                           
                                                                                                                                                                                
from:                                                                                                                                                                           
  host: "172.1.1.2"                                                                                                                                                          
  port: 3306                                                                                                                                                                    
  user: "root"                                                                                                                                                                  
  password: "dm_test" 
上游数据源账户所需权限
上游数据源用户所需权限:
- information_schem和需要同步的表的select权限
- reload权限
- REPLICATION CLIENT、REPLICATION SLAVE
创建数据源
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 operate-source create ./source-01.yaml
查看创建的数据源
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 config source mysql-01
2. 创建同步任务
task配置文件准备
vim task01.yaml
name: test1                      
task-mode: all                  
shard-mode: "pessimistic"       
                               
meta-schema: "dm_meta1"          
# timezone: "Asia/Shanghai"     
case-sensitive: false           
online-ddl: true               
clean-dump-file: true           # 是否清理 dump 阶段产生的文件,包括 metadata 文件、建库建表 SQL 文件以及数据导入 SQL 文件
collation_compatible: "loose"   # 同步 CREATE 语句中缺省 Collation 的方式,可选 "loose" 和 "strict",默认为 "loose"。"loose" 模式不会显式补充上游缺省的 Collation,"strict" 会显式补充上游缺省的 Collation。当使用 "strict" 模式,但下游不支持上游缺省的 Collation 时,下游可能会报错。
ignore-checking-items: []       
target-database:
  host: "172.1.1.4"
  port: 4000
  user: "dm_test"
  password: "dm_test"  
block-allow-list:                    
  bw-rule-1:                         
    do-dbs: ["dm_test.*"]
mydumpers:                           
  global:                            
    threads: 4                       
    chunk-filesize: 64               
    extra-args: "--consistency auto" 
loaders:                             
  global:                            
    pool-size: 16
    dir: "./dumped_data"
    import-mode: "logical"
    on-duplicate-logical: "replace"
syncers:                             
  global:                            
    worker-count: 16                 
    batch: 100                       
    safe-mode: false
    safe-mode-duration: "60s"
    compact: false
    multiple-rows: false
# ----------- 实例配置 -----------
mysql-instances:
  -
    source-id: "mysql-01"
    block-allow-list:  "bw-rule-1"
    mydumper-config-name: "global"
    loader-config-name: "global"
    syncer-config-name: "global"
下游tidb同步用户所需权限:
- 待同步库表的SELECT、INSERT、UPDATE、DELETE、CREATE、DROP、ALTER、INDEX权限
- dm元数据库表的 ALL 权限
前置检查
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 check-task ./task01.yaml
创建task
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 start-task ./task01.yaml
查看同步状态
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 query-status test1
四、单实例更换数据源IP
验证不修改task配置,直接更换数据源IP
1. 不修改source-id
Stop 任务和数据源
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 stop-task test1 
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 operate-source stop mysql-01
仅修改数据源IP
source-id: "mysql-01"                                                                                                                                                           
enable-gtid: true                                                                                                                                                               
                                                                                                                                                                                
from:                                                                                                                                                                           
  host: "120.1.1.115"                                                                                                                                                         
  port: 3306                                                                                                                                                                    
  user: "root"                                                                                                                                                                  
  password: "dm_test"
创建数据源和task
tiup dmctl:v7.1.3 --master-addr 172.16.201.4:8261 operate-source create  ./source-01.yaml
tiup dmctl:v7.1.3 --master-addr 172.16.201.4:8261 start-task ./task01.yaml 
tiup dmctl:v7.1.3 --master-addr 172.16.201.4:8261 query-status test1
验证同步无异常
不改变source-id的情况下,dm会去元数据表中找到断点,进行断点续传,不会重新dump数据
2. 修改source-id
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 stop-task test1 
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 operate-source stop mysql-01
修改数据源IP和source-id
source-id: "mysql-02"                                                                                                                                                           
enable-gtid: true                                                                                                                                                               
                                                                                                                                                                                
from:                                                                                                                                                                           
  host: "172.1.1.2"                                                                                                                                                          
  port: 3306                                                                                                                                                                    
  user: "root"                                                                                                                                                                  
  password: "dm_test"
创建数据源和task
需要修改task01.yaml的数据源
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 operate-source create  ./source-01.yaml
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 start-task ./task01.yaml 
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 query-status test1
验证同步无异常
修改了source-id的情况下,会触发重新dump全量数据
3. 更换IP期间新增了表
在停掉task和数据源后,模拟MySQL增加表和数据(只修改数据源IP)
mysql> create table t3(id int primary key,b int);                                                                                                                               
Query OK, 0 rows affected (0.04 sec)                                                                                                                                            
                                                                                                                                                                                
mysql> insert into t3 values (1,1);                                                                                                                                             
Query OK, 1 row affected (0.01 sec)                                                                                                                                             
                                                                                                                                                                                
mysql> insert into t3 values (2,1);                                                                                                                                             
Query OK, 1 row affected (0.01 sec) 
修改数据源IP后,创建task
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 operate-source create  ./source-01.yaml
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 start-task ./task01.yaml
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 query-status test1 
同步无异常,未dump全量数据
检查点分为针对单表的同步位点和数据源的同步位点,如果存在当前表的位点,则基于位点继续同步,如不存在,基于数据源位点往后同步
五、分片集群修改数据源IP
环境准备
基于单实例的环境,新增MySQL节点来测试
数据源配置
source-id: "mysql-04"                                                                                                                                                           
enable-gtid: true                                                                                                                                                               
                                                                                                                                                                                
from:                                                                                                                                                                           
  host: "172.1.1.4"                                                                                                                                                          
  port: 3306                                                                                                                                                                    
  user: "root"                                                                                                                                                                  
  password: "dm_test" 
task配置
name: test2                                                                                                                                                                     
task-mode: all                                                                                                                                                                  
shard-mode: "pessimistic"                                                                                                                                                       
                                                                                                                                                                                
meta-schema: "dm_meta2"                                                                                                                                                         
# timezone: "Asia/Shanghai"                                                                                                                                                     
                                                                                                                                                                                
case-sensitive: false                                                                                                                                                           
online-ddl: true                                                                                                                                                                
clean-dump-file: false           # 是否清理 dump 阶段产生的文件,包括 metadata 文件、建库建表 SQL 文件以及数据导入 SQL 文件                                                     
collation_compatible: "loose"   # 同步 CREATE 语句中缺省 Collation 的方式,可选 "loose" 和 "strict",默认为 "loose"。"loose" 模式不会显式补充上游缺省的 Collation,"strict" 会显
式补充上游缺省的 Collation。当使用 "strict" 模式,但下游不支持上游缺省的 Collation 时,下游可能会报错。                                                                         
ignore-checking-items: []                                                                                                                                                       
                                                                                                                                                                                
target-database:                                                                                                                                                                
  host: "172.1.1.4"                                                                                                                                                          
  port: 4000                                                                                                                                                                    
  user: "dm_test"                                                                                                                                                               
  password: "dm_test"                                                                                                                                                           
                                                                                                                                                                                
block-allow-list:                                                                                                                                                               
  bw-rule-1:                                                                                                                                                                    
    do-dbs: ["dm_test"]                                                                                                                                                      
                                                                                                                                                                                
mydumpers:                                                                                                                                                                      
  global:                                                                                                                                                                       
    threads: 4                                                                                                                                                                  
    chunk-filesize: 64                                                                                                                                                          
    extra-args: "--consistency auto"                                                                                                                                            
                                                                                                                                                                                
loaders:                                                                                                                                                                        
  global:                                                                                                                                                                       
    pool-size: 16                                                                                                                                                               
    dir: "./dumped_data"                                                                                                                                                        
    import-mode: "logical"                                                                                                                                                      
    on-duplicate-logical: "replace"                                                                                                                                             
                                                                                                                                                                                
syncers:                                                                                                                                                                        
  global:                                                                                                                                                                       
    worker-count: 16                                                                                                                                                            
    batch: 100                                                                                                                                                                  
    safe-mode: false                                                                                                                                                            
    safe-mode-duration: "60s"                                                                                                                                                   
    compact: false                                                                                                                                                              
    multiple-rows: false                                                                                                                                                        
# ----------- 实例配置 -----------                                                                                                                                              
mysql-instances:                                                                                                                                                                
  -                                                                                                                                                                             
    source-id: "mysql-04"                                                                                                                                                       
    block-allow-list:  "bw-rule-1"                                                                                                                                              
                                                                                                                                                                                
    mydumper-config-name: "global"                                                                                                                                              
    loader-config-name: "global"                                                                                                                                                
    syncer-config-name: "global"  
创建数据源和任务
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 operate-source create  ./source-02.yaml                                                                                
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 start-task ./task01.yaml                                                                                               
tiup dmctl:v7.1.3 --master-addr 172.1.1.4:8261 query-status test2 
重复单实例数据源IP修改过程,验证结果与单实例一致
六、总结
断点续传来源于dm元数据信息(dm_meta库的表记录信息),主要包含以下几点
- task.yaml的name的值
- task.yaml的meta-schema是否改变
- 数据源配置中source-id是否改变
如有其他变更项,可结合检查点进行分析,通过检查点信息是否改变来判断是否可以断点续传
前提:
-  使用 query-status命令获取当前 binlog replication 处理单元已复制到下游的 binlog 对应的 GTID sets (syncerBinlogGtid),记为gtid-S。
-  在将要切换到的 MySQL 实例上使用 SELECT @@GLOBAL.gtid_purged;获取已经被 purged 的 binlog 对应的 GTID sets,记为gtid-P。
-  在将要切换到的 MySQL 实例上使用 SELECT @@GLOBAL.gtid_executed;获取所有已经执行成功的事务对应的 GTID sets,记为gtid-E。
-  确保满足以下关系,否则不支持将 DM-worker 连接切换到相应的 MySQL 实例: -  gtid-S包含gtid-P(gtid-P可以为空)
-  gtid-E包含gtid-S
 
-  
七、附加测试
1. 测试一
 数据源的配置文件默认  enable-gtid: false  ,现验证同步过程中,是否可修改该参数 
 验证修改后同步正常,在  enable-gtid: false  情况下,检查点会同时携带position信息和gitd信息,修改后可基于位点断点续传 
2. 测试二
 DM配置文件  extra-args: "--consistency none"  默认值为none,none的官网解释是不做一致性保障 
none模式下
2024-06-21T08:23:44.159963Z     18511 Query     SELECT @@max_allowed_packet                                                                                                     
2024-06-21T08:23:44.160052Z     18511 Query     SET time_zone = '+08:00'                                                                                                        
2024-06-21T08:23:44.160149Z     18511 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ                                                                         
2024-06-21T08:23:44.160242Z     18511 Query     START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */                                                                          
2024-06-21T08:23:44.160343Z     18511 Query     SHOW MASTER STATUS                                                                                                              
2024-06-21T08:23:44.160534Z     18511 Query     SHOW SLAVE STATUS                                                                                                               
2024-06-21T08:23:44.160731Z     18511 Query     SHOW DATABASES                                                                                                                  
2024-06-21T08:23:44.161956Z     18511 Query     SELECT COUNT(1) as c FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='SEQUENCE'                                                 
2024-06-21T08:23:44.171027Z     18511 Query     SHOW TABLE STATUS FROM `dm_test`                                                                                             
2024-06-21T08:23:44.174675Z     18511 Query     SHOW MASTER STATUS                                                                                                              
2024-06-21T08:23:44.174826Z     18511 Query     SHOW CREATE DATABASE `dm_test`                                                                                               
2024-06-21T08:23:44.174981Z     18511 Query     SHOW COLUMNS FROM `dm_test`.`customer`                                                                                       
2024-06-21T08:23:44.175584Z     18511 Query     SELECT `c_id`,`c_d_id`,`c_w_id`,`c_first`,`c_middle`,`c_last`,`c_street_1`,`c_street_2`,`c_city`,`c_state`,`c_zip`,`c_phone`,`c_
since`,`c_credit`,`c_credit_lim`,`c_discount`,`c_balance`,`c_ytd_payment`,`c_payment_cnt`,`c_delivery_cnt`,`c_data` FROM `dm_test`.`customer` LIMIT 1                        
2024-06-21T08:23:44.178285Z     18511 Query     SHOW CREATE TABLE `dm_test`.`customer`                                                                                       
2024-06-21T08:23:44.178529Z     18511 Query     SHOW INDEX FROM `dm_test`.`customer`                                                                                         
2024-06-21T08:23:44.178805Z     18511 Query     EXPLAIN SELECT `c_w_id` FROM `dm_test`.`customer`                                                                            
2024-06-21T08:23:44.179002Z     18511 Query     SHOW INDEX FROM `dm_test`.`customer`                                                                                         
2024-06-21T08:23:44.179269Z     18511 Query     SHOW INDEX FROM `dm_test`.`customer`                                                                                         
2024-06-21T08:23:44.179510Z     18511 Query     EXPLAIN SELECT `c_w_id` FROM `dm_test`.`customer`                                                                            
2024-06-21T08:23:44.179748Z     18511 Query     SELECT MIN(`c_w_id`),MAX(`c_w_id`) FROM `dm_test`.`customer` 
2024-06-21T08:23:44.173952Z     18512 Query     SELECT @@max_allowed_packet                                                                                                     
2024-06-21T08:23:44.174104Z     18512 Query     SET time_zone = '+08:00'                                                                                                        
2024-06-21T08:23:44.174281Z     18512 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ                                                                         
2024-06-21T08:23:44.174546Z     18512 Query     START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */                                                                          
2024-06-21T08:23:44.182494Z     18512 Query     SELECT `c_id`,`c_d_id`,`c_w_id`,`c_first`,`c_middle`,`c_last`,`c_street_1`,`c_street_2`,`c_city`,`c_state`,`c_zip`,`c_phone`,`c_
2024-06-21T08:23:45.888538Z     18512 Query     SELECT `d_id`,`d_w_id`,`d_name`,`d_street_1`,`d_street_2`,`d_city`,`d_state`,`d_zip`,`d_tax`,`d_ytd`,`d_next_o_id` FROM `dm_test`.`district` ORDER BY `d_w_id`,`d_id`                                                                                                                                        
2024-06-21T08:23:45.889394Z     18512 Query     SELECT `h_c_id`,`h_c_d_id`,`h_c_w_id`,`h_d_id`,`h_w_id`,`h_date`,`h_amount`,`h_data` FROM `dm_test`.`history` WHERE `h_w_id` IS NULL OR (`h_w_id` >= 1 AND `h_w_id` < 11)                                                                                                                                    
2024-06-21T08:23:46.281664Z     18512 Query     SELECT `i_id`,`i_im_id`,`i_name`,`i_price`,`i_data` FROM `dm_test`.`item` ORDER BY `i_id`                                    
2024-06-21T08:23:46.352202Z     18512 Query     SELECT `no_o_id`,`no_d_id`,`no_w_id` FROM `dm_test`.`new_order` ORDER BY `no_w_id`,`no_d_id`,`no_o_id`                         
 
 
 none模式使用  SESSION RR  隔离级别 和  START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */  来构建一致性视图,不存在非事务引擎表的时候,操作比FTWRL轻量 
注意:
-  备份期间有DDL的话,有几率触发锁等待,原因为DM开启了两个 START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */ SESSION,一个用来看表结构、构造导出执行计划、查看索引等;另外一个用来dump数据,如果期间有DDL,有几率出现等MDL锁的情况(图一)
-  不开启FTWRL的话,那么backupmeta的gtid信息有可能是不准的(show master status获取的是当前值,不受 START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */限制)。备份文件 metadata 记录的位点可能比 dumped data 要早,可以开启safe-mode来规避(不能完全避免),DM会自行记录两次show master status位点信息来判断是否进入safe-mode,以及何时退出safe-mode。
auto模式下
2024-06-21T09:31:56.773773Z     18684 Connect   root@vm10-2-103-3 on  using SSL/TLS                                                                                             
2024-06-21T09:31:56.776319Z     18684 Query     SELECT version()                                                                                                                
2024-06-21T09:31:56.776529Z     18684 Query     FLUSH TABLES WITH READ LOCK                                                                                                     
2024-06-21T09:31:56.778052Z     18684 Query     UNLOCK TABLES                                                                                                                   
2024-06-21T09:31:56.778166Z     18684 Query     SET SESSION time_zone = '+08:00'                                                                                                
2024-06-21T09:31:56.778236Z     18684 Quit                                                                                                                                      
2024-06-21T09:31:56.780010Z     18685 Connect   root@vm10-2-103-3 on  using SSL/TLS                                                                                             
2024-06-21T09:31:56.780202Z     18685 Query     SET time_zone = '+08:00'                                                                                                        
2024-06-21T09:31:56.780405Z     18685 Query     FLUSH TABLES WITH READ LOCK                                                                                                     
2024-06-21T09:31:56.783146Z     18686 Connect   root@vm10-2-103-3 on  using SSL/TLS                                                                                             
2024-06-21T09:31:56.783335Z     18686 Query     SET time_zone = '+08:00'                                                                                                        
2024-06-21T09:31:56.783421Z     18686 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ                                                                         
2024-06-21T09:31:56.783518Z     18686 Query     START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */                                                                          
2024-06-21T09:31:56.783611Z     18686 Query     SHOW MASTER STATUS                                                                                                              
2024-06-21T09:31:56.783755Z     18686 Query     SHOW SLAVE STATUS                                                                                                               
2024-06-21T09:31:56.786107Z     18686 Query     SHOW DATABASES                                                                                                                  
2024-06-21T09:31:56.786563Z     18686 Query     SELECT COUNT(1) as c FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='SEQUENCE'                                                 
2024-06-21T09:31:56.916141Z     18686 Query     SHOW TABLE STATUS FROM `dm_test`                                                                                             
2024-06-21T09:31:56.919220Z     18687 Connect   root@vm10-2-103-3 on  using SSL/TLS                                                                                             
2024-06-21T09:31:56.919398Z     18687 Query     SET time_zone = '+08:00'                                                                                                        
2024-06-21T09:31:56.919483Z     18687 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ                                                                         
2024-06-21T09:31:56.919570Z     18687 Query     START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */                                                                          
2024-06-21T09:31:56.919726Z     18685 Query     UNLOCK TABLES                   
相对于mysqldump少了flush table的步骤(mysqldump在执行FTWRL前会执行flush tables),直接执行了FTWRL,第一次做权限探测,第二次执行备份
结论
结合业务应用情况综合考虑,选择auto/none模式



















