- 文档中心
- 关于 TiDB
- 快速上手
- 部署标准集群
- 数据迁移
- 运维操作
- 监控与告警
- 故障诊断
- 性能调优
- 系统调优
- 软件调优
- SQL 性能调优
- SQL 性能调优概览
- 理解 TiDB 执行计划
- SQL 优化流程
- 控制执行计划
- 教程
- 同城多中心部署
- 两地三中心部署
- 同城两中心部署
- 读取历史数据
- 使用 Stale Read 功能读取历史数据(推荐)
- 使用系统变量
tidb_snapshot
读取历史数据
- 最佳实践
- Placement Rules 使用文档
- Load Base Split 使用文档
- Store Limit 使用文档
- TiDB 工具
- 功能概览
- 适用场景
- 工具下载
- TiUP
- 文档地图
- 概览
- 术语及核心概念
- TiUP 组件管理
- FAQ
- 故障排查
- TiUP 命令参考手册
- 命令概览
- TiUP 命令
- TiUP Cluster 命令
- TiUP Cluster 命令概览
- tiup cluster audit
- tiup cluster check
- tiup cluster clean
- tiup cluster deploy
- tiup cluster destroy
- tiup cluster disable
- tiup cluster display
- tiup cluster edit-config
- tiup cluster enable
- tiup cluster help
- tiup cluster import
- tiup cluster list
- tiup cluster patch
- tiup cluster prune
- tiup cluster reload
- tiup cluster rename
- tiup cluster replay
- tiup cluster restart
- tiup cluster scale-in
- tiup cluster scale-out
- tiup cluster start
- tiup cluster stop
- tiup cluster template
- tiup cluster upgrade
- TiUP DM 命令
- TiUP DM 命令概览
- tiup dm audit
- tiup dm deploy
- tiup dm destroy
- tiup dm disable
- tiup dm display
- tiup dm edit-config
- tiup dm enable
- tiup dm help
- tiup dm import
- tiup dm list
- tiup dm patch
- tiup dm prune
- tiup dm reload
- tiup dm replay
- tiup dm restart
- tiup dm scale-in
- tiup dm scale-out
- tiup dm start
- tiup dm stop
- tiup dm template
- tiup dm upgrade
- TiDB 集群拓扑文件配置
- DM 集群拓扑文件配置
- TiUP 镜像参考指南
- TiUP 组件文档
- PingCAP Clinic 诊断服务
- TiDB Operator
- Dumpling
- TiDB Lightning
- TiDB Data Migration
- 关于 Data Migration
- 快速开始
- 部署 DM 集群
- 入门指南
- 进阶教程
- 运维管理
- 参考手册
- 使用示例
- 异常解决
- 版本发布历史
- Backup & Restore (BR)
- TiDB Binlog
- TiCDC
- TiUniManager
- sync-diff-inspector
- TiSpark
- 参考指南
- 架构
- 监控指标
- 安全加固
- 权限
- SQL
- SQL 语言结构和语法
- SQL 语句
ADD COLUMN
ADD INDEX
ADMIN
ADMIN CANCEL DDL
ADMIN CHECKSUM TABLE
ADMIN CHECK [TABLE|INDEX]
ADMIN SHOW DDL [JOBS|QUERIES]
ADMIN SHOW TELEMETRY
ALTER DATABASE
ALTER INDEX
ALTER INSTANCE
ALTER PLACEMENT POLICY
ALTER TABLE
ALTER USER
ANALYZE TABLE
BACKUP
BEGIN
CHANGE COLUMN
CHANGE DRAINER
CHANGE PUMP
COMMIT
CREATE [GLOBAL|SESSION] BINDING
CREATE DATABASE
CREATE INDEX
CREATE PLACEMENT POLICY
CREATE ROLE
CREATE SEQUENCE
CREATE TABLE LIKE
CREATE TABLE
CREATE USER
CREATE VIEW
DEALLOCATE
DELETE
DESC
DESCRIBE
DO
DROP [GLOBAL|SESSION] BINDING
DROP COLUMN
DROP DATABASE
DROP INDEX
DROP PLACEMENT POLICY
DROP ROLE
DROP SEQUENCE
DROP STATS
DROP TABLE
DROP USER
DROP VIEW
EXECUTE
EXPLAIN ANALYZE
EXPLAIN
FLASHBACK TABLE
FLUSH PRIVILEGES
FLUSH STATUS
FLUSH TABLES
GRANT <privileges>
GRANT <role>
INSERT
KILL [TIDB]
LOAD DATA
LOAD STATS
MODIFY COLUMN
PREPARE
RECOVER TABLE
RENAME INDEX
RENAME TABLE
RENAME USER
REPLACE
RESTORE
REVOKE <privileges>
REVOKE <role>
ROLLBACK
SELECT
SET DEFAULT ROLE
SET [NAMES|CHARACTER SET]
SET PASSWORD
SET ROLE
SET TRANSACTION
SET [GLOBAL|SESSION] <variable>
SHOW [BACKUPS|RESTORES]
SHOW ANALYZE STATUS
SHOW [GLOBAL|SESSION] BINDINGS
SHOW BUILTINS
SHOW CHARACTER SET
SHOW COLLATION
SHOW [FULL] COLUMNS FROM
SHOW CONFIG
SHOW CREATE PLACEMENT POLICY
SHOW CREATE SEQUENCE
SHOW CREATE TABLE
SHOW CREATE USER
SHOW DATABASES
SHOW DRAINER STATUS
SHOW ENGINES
SHOW ERRORS
SHOW [FULL] FIELDS FROM
SHOW GRANTS
SHOW INDEX [FROM|IN]
SHOW INDEXES [FROM|IN]
SHOW KEYS [FROM|IN]
SHOW MASTER STATUS
SHOW PLACEMENT
SHOW PLACEMENT FOR
SHOW PLACEMENT LABELS
SHOW PLUGINS
SHOW PRIVILEGES
SHOW [FULL] PROCESSSLIST
SHOW PROFILES
SHOW PUMP STATUS
SHOW SCHEMAS
SHOW STATS_HEALTHY
SHOW STATS_HISTOGRAMS
SHOW STATS_META
SHOW STATUS
SHOW TABLE NEXT_ROW_ID
SHOW TABLE REGIONS
SHOW TABLE STATUS
SHOW [FULL] TABLES
SHOW [GLOBAL|SESSION] VARIABLES
SHOW WARNINGS
SHUTDOWN
SPLIT REGION
START TRANSACTION
TABLE
TRACE
TRUNCATE
UPDATE
USE
WITH
- 数据类型
- 函数与操作符
- 聚簇索引
- 约束
- 生成列
- SQL 模式
- 表属性
- 事务
- 垃圾回收 (GC)
- 视图
- 分区表
- 临时表
- 缓存表
- 字符集和排序
- Placement Rules in SQL
- 系统表
mysql
- INFORMATION_SCHEMA
- Overview
ANALYZE_STATUS
CLIENT_ERRORS_SUMMARY_BY_HOST
CLIENT_ERRORS_SUMMARY_BY_USER
CLIENT_ERRORS_SUMMARY_GLOBAL
CHARACTER_SETS
CLUSTER_CONFIG
CLUSTER_HARDWARE
CLUSTER_INFO
CLUSTER_LOAD
CLUSTER_LOG
CLUSTER_SYSTEMINFO
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
DATA_LOCK_WAITS
DDL_JOBS
DEADLOCKS
ENGINES
INSPECTION_RESULT
INSPECTION_RULES
INSPECTION_SUMMARY
KEY_COLUMN_USAGE
METRICS_SUMMARY
METRICS_TABLES
PARTITIONS
PLACEMENT_POLICIES
PROCESSLIST
REFERENTIAL_CONSTRAINTS
SCHEMATA
SEQUENCES
SESSION_VARIABLES
SLOW_QUERY
STATISTICS
TABLES
TABLE_CONSTRAINTS
TABLE_STORAGE_STATS
TIDB_HOT_REGIONS
TIDB_HOT_REGIONS_HISTORY
TIDB_INDEXES
TIDB_SERVERS_INFO
TIDB_TRX
TIFLASH_REPLICA
TIKV_REGION_PEERS
TIKV_REGION_STATUS
TIKV_STORE_STATUS
USER_PRIVILEGES
VIEWS
METRICS_SCHEMA
- UI
- CLI
- 命令行参数
- 配置文件参数
- 系统变量
- 存储引擎
- 遥测
- 错误码
- 通过拓扑 label 进行副本调度
- 常见问题解答 (FAQ)
- 版本发布历史
- 术语表
Data Migration 中的 DML 同步机制
本文介绍了 DM 核心处理单元 Sync 如何同步从数据源或 relay log 中读取到的 DML。本文将介绍 DML 事件在 DM 内部的完整处理流程,包括 binlog 读取、过滤、路由、转换、优化以及执行等逻辑,并详细解读 DML 优化逻辑和 DML 执行逻辑。
DML 处理流程
Sync 单元对 DML 的处理步骤如下:
从 MySQL、MariaDB 或 relay log 中,读取 binlog event。
转换读取到的 binlog event:
- Binlog filter:根据 binlog 表达式过滤 binlog event,通过
filters
配置。 - Table routing:根据“库/表”路由规则对“库/表”名进行转换,通过
routes
配置。 - Expression filter:根据 SQL 表达式过滤 binlog event,通过
expression-filter
配置。
- Binlog filter:根据 binlog 表达式过滤 binlog event,通过
优化 DML 执行:
- Compactor:将对同一条记录(主键相同)的多个操作合并成一个操作,通过
syncer.compact
开启。 - Causality:将不同记录(主键不同)进行冲突检测,提升同步并发度。
- Merger:将多条 binlog 合并成一条 DML,通过
syncer.multiple-rows
开启。
- Compactor:将对同一条记录(主键相同)的多个操作合并成一个操作,通过
将 DML 执行到下游。
定期保存 binlog position 或 GTID 到 checkpoint 中。
DML 优化逻辑
Sync 单元通过 Compactor、Causality、Merger 三个步骤,实现对 DML 的优化逻辑。
Compactor
DM 根据上游 binlog 记录,捕获记录的变更并同步到下游。当上游对同一条记录短时间内做了多次变更时(INSERT
/UPDATE
/DELETE
),DM 可以通过 Compactor 将多次变更压缩成一次变更,减少下游压力,提升吞吐。例如:
INSERT + UPDATE => INSERT
INSERT + DELETE => DELETE
UPDATE + UPDATE => UPDATE
UPDATE + DELETE => DELETE
DELETE + INSERT => UPDATE
Compactor 特性默认关闭,如需启用可在迁移任务的 sync
配置模块开启,例如:
syncers: # sync 处理单元的运行配置参数
global: # 配置名称
... # 省略其他配置
compact: true
Causality
MySQL binlog 顺序同步模型要求按照 binlog 顺序依次同步 binlog event,这样的同步模型无法满足高 QPS 低同步延迟的需求。此外,由于不是所有的 binlog 涉及到的操作都存在冲突,顺序同步也是非必要的。
DM 通过冲突检测机制,识别出需要顺序执行的 binlog,确保这些 binlog 顺序执行的同时,最大程度地保持其他 binlog 并发执行,以此提高 binlog 同步的性能。
Causality 采用一种类似并查集的算法,对每一个 DML 进行分类,将相互关联的 DML 分为一组。具体算法可参考并行执行 DML。
Merger
根据 MySQL binlog 协议,每条 binlog 对应一行数据的变更操作。通过 Merger,DM 可以将多条 binlog 合并成一条 DML,再执行到下游,减少网络的交互。例如:
INSERT tb(a,b) VALUES(1,1);
+ INSERT tb(a,b) VALUES(2,2);
= INSERT tb(a,b) VALUES(1,1),(2,2);
UPDATE tb SET a=1, b=1 WHERE a=1;
+ UPDATE tb SET a=2, b=2 WHERE a=2;
= INSERT tb(a,b) VALUES(1,1),(2,2) ON DUPLICATE UPDATE a=VALUES(a), b=VALUES(b)
DELETE tb WHERE a=1
+ DELETE tb WHERE a=2
= DELETE tb WHERE (a) IN (1),(2);
Merger 特性默认关闭,如需启用可在迁移任务的 sync
配置模块开启,例如:
syncers: # sync 处理单元的运行配置参数
global: # 配置名称
... # 省略其他配置
multiple-rows: false
DML 执行逻辑
Sync 单元对 DML 进行优化后,再进行执行逻辑。
DML 生成
DM 内嵌一个 schema tracker,用于记录上下游的 schema 信息:
- 当 DM 收到 DDL 时,DM 更新内部 schema tracker 的表结构。
- 当收到 DML 时,DM 根据 schema tracker 的表结构生成对应的 DML。
生成 DML 的具体逻辑如下:
- Sync 记录上游的初始表结构:
- 当启动全量与增量任务时,Sync 使用上游全量同步时导出的表结构作为上游的初始表结构。
- 当启动增量任务时,由于 MySQL binlog 没有记录表结构信息,Sync 使用下游对应的表的表结构作为上游的初始表结构。
- 由于用户上下游表结构可能不一致,例如下游比上游多了额外的列,或者上下游主键不一致,为了保证数据同步的正确性,DM 记录下游对应表的主键和唯一键信息。
- DM 生成 DML:
- 使用 schema tracker 中记录的上游表结构生成 DML 语句的列名。
- 使用 binlog 中记录的列值生成 DML 语句的列值。
- 使用 schema tracker 中记录的下游主键或唯一键生成 DML 语句中的
WHERE
条件。当表结构无唯一键时,DM 会使用 binlog 中记录的所有列值作为WHERE
条件。
Worker count
Causality 可以通过冲突检测算法将 binlog 分成多个 group 并发地执行到下游。DM 通过设置 worker-count,控制并发的数量。当下游 TiDB 的 CPU 占用不高时,增大并发的数量可以有效地提高数据同步的吞吐量。
你可以通过 syncer.worker-count
配置项,修改并发迁移 DML 的线程数量。
Batch
DM 将多条 DML 积累到一个事务中执行到下游。当 DML Worker 收到 DML 时,将 DML 加入到缓存中。当缓存中 DML 数量达到预定阈值时,或者 DML worker 较长时间没有收到 DML 时,DML worker 将缓存中的 DML 执行到下游。
你可以通过 syncer.batch
配置项,修改每个事务包含的 DML 的数量。
checkpoint
DML 执行和 checkpoint 更新的操作不是原子的。
在 DM 中,checkpoint 默认每 30 秒更新一次。同时,由于存在多个 DML worker 进程,checkpoint 进程会计算所有 DML worker 中同步进度最早的 binlog 位点,将该位点作为当前同步的 checkpoint。所有早于此位点的 binlog,都已保证被成功地执行到下游。
注意事项
事务一致性
DM 是按照“行级别”进行数据同步的,并不保证事务原样同步。在 DM 中,上游的一个事务会被拆成多行,分发到不同的 DML Worker 中并发执行。因此,当 DM 同步任务报错暂停,或者用户手动暂停任务时,下游可能停留在一个中间状态;即上游一个事务中的 DML 语句,可能一部分同步到下游,一部分没有,导致下游处于不一致的状态。
为了尽可能使任务暂停时下游处于一致状态,DM v5.3.0 起,任务暂停时,会等待 10 秒,使正在处理的上游事务全部同步到下游再真正暂停任务。如果上游一个事务在 10 秒内还未全部同步到下游,那么下游仍然可能处于不一致的状态。
安全模式
DML 执行和 checkpoint 写操作不是同步的,并且写 checkpoint 操作和写下游数据也并不能保证原子性。当 DM 因为某些原因异常退出时,checkpoint 可能只记录到退出时刻之前的一个恢复点。因此,当同步任务重启时,DM 可能会重复写入部分数据,也就是说,DM 实际上提供的是“至少一次处理”的逻辑(At-least-once processing),相同的数据可能会被处理一次以上。
为了保证数据是可重入的,DM 在异常重启时会进入安全模式。具体逻辑参阅 DM 安全模式。
开启安全模式期间,为了保证数据可重入,DM 会进行如下转换:
- 将上游
INSERT
语句转换成REPLACE
语句 - 将上游
UPDATE
语句转换成DELETE
+REPLACE
语句。
精确一次处理 (Exactly-Once Processing)
目前 DM 仅保证最终一致性,尚未支持“精确一次处理”及“保持事务原有顺序同步”。