sync-diff数据比对工具
Posted 清风明月li
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sync-diff数据比对工具相关的知识,希望对你有一定的参考价值。
一、概述
sync-diff-inspector 是一个用于校验 mysql/TiDB 中两份数据是否一致的工具。该工具提供了修复数据的功能(适用于修复少量不一致的数据)。
主要功能:
• 对比表结构和数据
• 如果数据不一致,则生成用于修复数据的 SQL 语句
• 支持不同库名或表名的数据校验
• 支持分库分表场景下的数据校验
• 支持 TiDB 主从集群的数据校验
• 支持从 TiDB DM 拉取配置的数据校验
你可通过以下方式下载 sync-diff-inspector:
• Binary 包。点击 tidb-community-toolkit-v5.4.1-linux-amd64 进行下载。
• Docker 镜像。执行以下命令进行下载:
nginx
docker pull pingcap/tidb-enterprise-tools:nightly
二、使用限制
• 对于 MySQL 和 TiDB 之间的数据同步不支持在线校验,需要保证上下游校验的表中没有数据写入,或者保证某个范围内的数据不再变更,通过配置 range 来校验这个范围内的数据。
• 不支持 JSON、BIT、BINARY、BLOB 等类型的数据,在校验时需要设置 ignore-columns 忽略检查这些类型的数据。
• FLOAT、DOUBLE 等浮点数类型在 TiDB 和 MySQL 中的实现方式不同,在计算 checksum 时会分别取 6 位和 15 位有效数字。如果不使用该特性,需要设置 ignore-columns 忽略这些列的检查。
• 支持对不包含主键或者唯一索引的表进行校验,但是如果数据不一致,生成的用于修复的 SQL 可能无法正确修复数据。
三、sync-diff-inspector 所需的数据库权限
sync-diff-inspector 需要获取表结构信息、查询数据,需要的数据库权限如下:
• 上游数据库
○ SELECT(查数据进行对比)
○ SHOW_DATABASES(查看库名)
○ RELOAD(查看表结构)
• 下游数据库
○ SELECT(查数据进行对比)
○ SHOW_DATABASES(查看库名)
○ RELOAD(查看表结构)
四、配置文件说明
sync-diff-inspector 的配置总共分为五个部分:
• Global config: 通用配置,包括校验的线程数量、是否输出修复 SQL 、是否比对数据等。
• Datasource config: 配置上下游数据库实例。
• Routes: 上游多表名通过正则匹配下游单表名的规则。(可选)
• Task config: 配置校验哪些表,如果有的表在上下游有一定的映射关系或者有一些特殊要求,则需要对指定的表进行配置。
• Table config: 对具体表的特殊配置,例如指定范围、忽略的列等等。(可选)
下面是一个完整配置文件的说明:
• 提示:配置名后带 s 的配置项允许拥有多个配置值,因此需要使用方括号 [] 来包含配置值。
SQL
Diff Configuration.
######################### Global config #########################
检查数据的线程数量,上下游数据库的连接数会略大于该值
check-thread-count = 4
如果开启,若表存在不一致,则输出用于修复的 SQL 语句。
export-fix-sql = true
只对比表结构而不对比数据
check-struct-only = false
######################### Datasource config #########################
[data-sources]
[data-sources.mysql1] # mysql1 是该数据库实例唯一标识的自定义 id,用于下面 task.source-instances/task.target-instance 中
host = "127.0.0.1"
port = 3306
user = "root"
password = ""
#(可选)使用映射规则来匹配上游多个分表,其中 rule1 和 rule2 在下面 Routes 配置栏中定义
route-rules = ["rule1", "rule2"]
[data-sources.tidb0]
host = "127.0.0.1"
port = 4000
user = "root"
password = ""
#(可选)使用 TiDB 的 snapshot 功能,如果开启的话会使用历史数据进行对比
snapshot = "386902609362944000"
########################### Routes ###########################
如果需要对比大量的不同库名或者表名的表的数据,或者用于校验上游多个分表与下游总表的数据,可以通过 table-rule 来设置映射关系
可以只配置 schema 或者 table 的映射关系,也可以都配置
[routes]
[routes.rule1] # rule1 是该配置的唯一标识的自定义 id,用于上面 data-sources.route-rules 中
schema-pattern = "test" # 匹配数据源的库名,支持通配符 "" 和 "?"
table-pattern = "t" # 匹配数据源的表名,支持通配符 "" 和 "?"
target-schema = "test" # 目标库名
target-table = "t" # 目标表名
[routes.rule2]
schema-pattern = "test2" # 匹配数据源的库名,支持通配符 "" 和 "?"
table-pattern = "t2" # 匹配数据源的表名,支持通配符 "" 和 "?"
target-schema = "test2" # 目标库名
target-table = "t2" # 目标表名
######################### Task config #########################
配置需要对比的目标数据库中的表
[task]
output-dir 会保存如下信息
# 1 sql: 检查出错误后生成的修复 SQL 文件,并且一个 chunk 对应一个文件
# 2 log: sync-diff.log 保存日志信息
# 3 summary: summary.txt 保存总结
# 4 checkpoint: a dir 保存断点续传信息
output-dir = "./output"
# 上游数据库,内容是 data-sources 声明的唯一标识 id
source-instances = ["mysql1"]
# 下游数据库,内容是 data-sources 声明的唯一标识 id
target-instance = "tidb0"
# 需要比对的下游数据库的表,每个表需要包含数据库名和表名,两者由 `.` 隔开
# 使用 ? 来匹配任意一个字符;使用 * 来匹配任意;详细匹配规则参考 golang regexp pkg: https://github.com/google/re2/wiki/Syntax
target-check-tables = ["schema*.table*", "!c.*", "test2.t2"]
#(可选)对部分表的额外配置,其中 config1 在下面 Table config 配置栏中定义
target-configs = ["config1"]
######################### Table config #########################
对部分表进行特殊的配置,配置的表必须包含在 task.target-check-tables 中
[table-configs.config1] # config1 是该配置的唯一标识自定义 id,用于上面 task.target-configs 中
目标表名称,可以使用正则来匹配多个表,但不允许存在一个表同时被多个特殊配置匹配。
target-tables = ["schema.test", "test2.t2"]
#(可选)指定检查的数据的范围,需要符合 sql 中 where 条件的语法
range = "age > 10 AND age < 20"
#(可选)指定用于划分 chunk 的列,如果不配置该项,sync-diff-inspector 会选取一些合适的列(主键/唯一键/索引)
index-fields = ["col1","col2"]
#(可选)忽略某些列的检查,例如 sync-diff-inspector 目前还不支持的一些类型(json,bit,blob 等),
或者是浮点类型数据在 TiDB 和 MySQL 中的表现可能存在差异,可以使用 ignore-columns 忽略检查这些列
ignore-columns = ["",""]
#(可选)指定划分该表的 chunk 的大小,若不指定可以删去或者将其配置为 0。
chunk-size = 0
#(可选)指定该表的 collation,若不指定可以删去或者将其配置为空字符串。
collation = ""
五、运行sync-diff-inspector
执行如下命令:
Bash
./bin/sync_diff_inspector --config=./config.toml
该命令最终会在 config.toml 中的 output-dir 输出目录输出本次比对的检查报告 summary.txt 和日志 sync_diff.log。在输出目录下还会生成由 config.toml 文件内容哈希值命名的文件夹,该文件夹下包括断点续传 checkpoint 结点信息以及数据存在不一致时生成的 SQL 修复数据。
前台输出
sync-diff-inspector 在执行过程中会往 stdout 发送进度信息。进度信息包括表的结构比较结果、表的数据比较结果以及进度条。
输出文件
输出文件目录结构如下:
Go output/ |
-- checkpoint # 保存断点续传信息 |
-- bbfec8cc8d1f58a5800e63aa73e5 # config hash 占位文件,标识该输出目录(output/)对应的配置文件 │ |
-- DO_NOT_EDIT_THIS_DIR │ └-- sync_diff_checkpoints.pb # 断点续传信息 |
|
---|---|---|---|---|
-- fix-on-target # 保存用于修复不一致的 SQL 文件 | ||||
-- xxx.sql | ||||
-- xxx.sql | ||||
└-- xxx.sql | ||||
-- summary.txt # 保存校验结果的总结 |
└-- sync_diff.log # 保存 sync-diff-inspector 执行过程中输出的日志信息
日志
sync-diff-inspector 的日志存放在 $output/sync_diff.log 中,其中 $output 是 config.toml 文件中 output-dir 的值。
校验进度
sync-diff-inspector 会在运行时定期(间隔 10s)输出校验进度到checkpoint中(位于 $output/checkpoint/sync_diff_checkpoints.pb 中,其中 $output 是 config.toml 文件中 output-dir 的值。
校验结果
当校验结束时,sync-diff-inspector 会输出一份校验报告,位于 $output/summary.txt 中,其中 $output 是 config.toml 文件中 output-dir 的值。
Go
+---------------------+--------------------+----------------+
| TABLE | STRUCTURE EQUALITY | DATA DIFF ROWS |
+---------------------+--------------------+----------------+
| sbtest
.sbtest99
| true | +97/-97 |
| sbtest
.sbtest96
| true | +0/-101 |
+---------------------+--------------------+----------------+
Time Cost: 16.75370462s
Average Speed: 113.277149MB/s
• TABLE: 该列表示对应的数据库及表名
• STRUCTURE EQUALITY: 表结构是否相同
• DATA DIFF ROWS: 即 rowAdd / rowDelete ,表示该表修复需要增加/删除的行数
SQL 修复
校验过程中遇到不同的行,会生成修复数据的 SQL 语句。一个chunk如果出现数据不一致,就会生成一个以 chunk.Index 命名的 SQL 文件。文件位于 $output/fix-on-$instance 文件夹下。其中 $instance 为 config.toml 中 task.target-instance 的值。
一个 SQL 文件会包含该 chunk 的所属表以及表示的范围信息。对每个修复 SQL 语句,有三种情况:
• 下游数据库缺失行,则是 REPLACE 语句
• 下游数据库冗余行,则是 DELETE 语句
• 下游数据库行部分数据不一致,则是 REPLACE 语句,但会在 SQL 文件中通过注释的方法标明不同的列
SQL
-- table: sbtest.sbtest99
-- range in sequence: (3690708) < (id) <= (3720581)
/
DIFF COLUMNS ╏ K
╏ C
╏ PAD
╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍
source data ╏ 2501808 ╏ hello ╏ world
╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍
target data ╏ 5003616 ╏ 0709824117-9809973320-4456050422 ╏ 1714066100-7057807621-1425865505
╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╋╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍
/
REPLACE INTO sbtest
.sbtest99
(id
,k
,c
,pad
) VALUES (3700000,2501808,hello,world);
注意事项
• sync-diff-inspector 在校验数据时会消耗一定的服务器资源,需要避免在业务高峰期间校验。
• 在数据对比前,需要注意表中的 collation 设置。如果表的主键或唯一键为 varchar 类型,且上下游数据库中 collation 设置不同,可能会因为排序问题导致最终校验结果不正确,需要在 sync-diff-inspector 的配置文件中增加 collation 设置。
• sync-diff-inspector 会优先使用 TiDB 的统计信息来划分 chunk,需要尽量保证统计信息精确,可以在业务空闲期手动执行 analyze table table_name。
• table-rule 的规则需要特殊注意,例如设置了 schema-pattern="test1",table-pattern = "t_1",target-schema="test2",target-table = "t_2",会对比 source 中的表 test1.t_1 和 target 中的表 test2.t_2。sync-diff-inspector 默认开启 sharding,如果 source 中还有表 test2.t_2,则会把 source 端的表 test1.t_1 和表 test2.t_2 作为 sharding 与 target 中的表 test2.t_2 进行一致性校验。
• 生成的 SQL 文件仅作为修复数据的参考,需要确认后再执行这些 SQL 修复数据。
六、常用数据的比对
1、不同的库名或表名的数据校验
查看相关的配置和执行命令
SQL
[root@k8s-master tidb-community-toolkit-v5.4.1-linux-amd64]# cat config.toml
[data-sources]
######################### Datasource config #########################
[data-sources.mysql1]
host = "172.16.6.130"
port = 3306
user = "root"
password = "mysql"
route-rules = ["rule1"]
[data-sources.tidb0]
host = "172.16.5.122"
port = 4000
user = "root"
password = "123456"
########################### Routes ###########################
[routes.rule1]
schema-pattern = "test_20220520" # 匹配数据源的库名,支持通配符 "" 和 "?"
table-pattern = "sbtest1" # 匹配数据源的表名,支持通配符 "" 和 "?"
target-schema = "test_20220520" # 目标库名
target-table = "sbtest1" # 目标表名
[task]
output-dir = "./output"
source-instances = ["mysql1"]
target-instance = "tidb0"
target-check-tables = ["schema.table", "!c.*", "test_20220520.sbtest1"]
2、执行命令
[root@k8s-master tidb-community-toolkit-v5.4.1-linux-amd64]# ./bin/sync_diff_inspector --config=./config.toml
A total of 1 tables need to be compared
Comparing the table structure of test_20220520`.`sbtest1
... equivalent
Comparing the table data of test_20220520`.`sbtest1
... equivalent
Progress [============================================================>] 100% 0/0
A total of 1 table have been compared and all are equal.
You can view the comparision details through ./output/sync_diff.log
3、查看执行结果
[root@k8s-master tidb-community-toolkit-v5.4.1-linux-amd64]# cat output/sync_diff.log
[2022/05/21 12:23:21.628 +08:00] [INFO] [printer.go:46] ["Welcome to sync_diff_inspector"] ["Release Version"=v5.4.1] ["Git Commit Hash"=b870b1b22028998ea3da8212b21e447193742c66] ["Git Branch"=heads/refs/tags/v5.4.1] ["UTC Build Time"="2022-04-28 02:08:50"] ["Go Version"=go1.16.4]
[2022/05/21 12:23:21.629 +08:00] [INFO] [main.go:101] [config="\\"check-thread-count\\":1,\\"export-fix-sql\\":true,\\"check-struct-only\\":false,\\"dm-addr\\":\\"\\",\\"dm-task\\":\\"\\",\\"data-sources\\":\\"mysql1\\":\\"host\\":\\"172.16.6.130\\",\\"port\\":3306,\\"user\\":\\"root\\",\\"password\\":\\"mysql\\",\\"sql-mode\\":\\"\\",\\"snapshot\\":\\"\\",\\"route-rules\\":[\\"rule1\\"],\\"Router\\":\\"Selector\\":,\\"Conn\\":null,\\"tidb0\\":\\"host\\":\\"172.16.5.122\\",\\"port\\":4000,\\"user\\":\\"root\\",\\"password\\":\\"123456\\",\\"sql-mode\\":\\"\\",\\"snapshot\\":\\"\\",\\"route-rules\\":null,\\"Router\\":\\"Selector\\":,\\"Conn\\":null,\\"routes\\":\\"rule1\\":\\"schema-pattern\\":\\"test_20220520\\",\\"table-pattern\\":\\"sbtest1\\",\\"target-schema\\":\\"test_20220520\\",\\"target-table\\":\\"sbtest1\\",\\"table-configs\\":null,\\"task\\":\\"source-instances\\":[\\"mysql1\\"],\\"source-routes\\":null,\\"target-instance\\":\\"tidb0\\",\\"target-check-tables\\":[\\"schema.table\\",\\"!c.*\\",\\"test_20220520.sbtest1\\"],\\"target-configs\\":null,\\"output-dir\\":\\"./output\\",\\"SourceInstances\\":[\\"host\\":\\"172.16.6.130\\",\\"port\\":3306,\\"user\\":\\"root\\",\\"password\\":\\"mysql\\",\\"sql-mode\\":\\"\\",\\"snapshot\\":\\"\\",\\"route-rules\\":[\\"rule1\\"],\\"Router\\":\\"Selector\\":,\\"Conn\\":null],\\"TargetInstance\\":\\"host\\":\\"172.16.5.122\\",\\"port\\":4000,\\"user\\":\\"root\\",\\"password\\":\\"123456\\",\\"sql-mode\\":\\"\\",\\"snapshot\\":\\"\\",\\"route-rules\\":null,\\"Router\\":\\"Selector\\":,\\"Conn\\":null,\\"TargetTableConfigs\\":null,\\"TargetCheckTables\\":[,,],\\"FixDir\\":\\"output/fix-on-tidb0\\",\\"CheckpointDir\\":\\"output/checkpoint\\",\\"HashFile\\":\\"\\",\\"ConfigFile\\":\\"./config.toml\\",\\"PrintVersion\\":false"]
[2022/05/21 12:23:22.193 +08:00] [INFO] [mysql_shard.go:349] ["will increase connection configurations for DB of instance"] ["connection limit"=2]
[2022/05/21 12:23:22.193 +08:00] [INFO] [source.go:352] ["table match check passed!!"]
[2022/05/21 12:23:22.194 +08:00] [INFO] [tidb.go:195] ["find router for tidb source"]
[2022/05/21 12:23:22.201 +08:00] [INFO] [source.go:352] ["table match check passed!!"]
[2022/05/21 12:23:22.202 +08:00] [INFO] [diff.go:361] ["The downstream is TiDB. pick it as work source first"]
[2022/05/21 12:23:22.218 +08:00] [INFO] [client.go:392] ["[pd] create pd client with endpoints"] [pd-address="[172.16.5.146:2379,172.16.6.236:2379,172.16.5.122:2379]"]
[2022/05/21 12:23:22.226 +08:00] [INFO] [base_client.go:332] ["[pd] update member urls"] [old-urls="[http://172.16.5.146:2379,http://172.16.6.236:2379,http://172.16.5.122:2379]"] [new-urls="[http://172.16.5.122:2379,http://172.16.5.146:2379,http://172.16.6.236:2379]"]
[2022/05/21 12:23:22.226 +08:00] [INFO] [base_client.go:350] ["[pd] switch leader"] [new-leader=http://172.16.5.122:2379] [old-leader=]
[2022/05/21 12:23:22.226 +08:00] [INFO] [base_client.go:105] ["[pd] init cluster id"] [cluster-id=7094800466639767512]
[2022/05/21 12:23:22.226 +08:00] [INFO] [client.go:687] ["[pd] tso dispatcher created"] [dc-location=global]
[2022/05/21 12:23:22.228 +08:00] [INFO] [pd.go:190] ["tidb support auto gc safepoint"] [version=4.0.12]
[2022/05/21 12:23:22.228 +08:00] [INFO] [diff.go:347] ["start update service to keep GC stopped automatically"]
[2022/05/21 12:23:22.228 +08:00] [INFO] [diff.go:193] ["not found checkpoint file, start from beginning"]
[2022/05/21 12:23:22.229 +08:00] [INFO] [pd.go:205] ["generate dumpling gc safePoint id"] [id=Sync_diff_1653107002229226078]
[2022/05/21 12:23:22.235 +08:00] [INFO] [diff.go:711] ["start writeSQLs goroutine"]
[2022/05/21 12:23:22.235 +08:00] [INFO] [diff.go:375] ["start handleCheckpoint goroutine"]
[2022/05/21 12:23:22.248 +08:00] [INFO] [bucket.go:174] ["get chunk size for table"] ["chunk size"=50000] [db=test_20220520] [table=sbtest1]
[2022/05/21 12:23:22.248 +08:00] [INFO] [bucket.go:98] ["close chunks channel for table"] [schema=test_20220520] [table=sbtest1]
[2022/05/21 12:23:22.248 +08:00] [INFO] [diff.go:282] ["global consume chunk info"] ["chunk index"="\\"table-index\\":0,\\"bucket-index-left\\":0,\\"bucket-index-right\\":180,\\"chunk-index\\":0,\\"chunk-count\\":1"] ["chunk bound"="[]"]
[2022/05/21 12:23:22.285 +08:00] [INFO] [diff.go:722] ["write sql channel closed"]
[2022/05/21 12:23:22.286 +08:00] [INFO] [diff.go:713] ["close writeSQLs goroutine"]
[2022/05/21 12:23:22.286 +08:00] [INFO] [diff.go:403] ["Stop do checkpoint"]
[2022/05/21 12:23:22.286 +08:00] [INFO] [checkpoints.go:225] ["save checkpoint"] [chunk="\\"state\\":\\"success\\",\\"chunk-range\\":\\"index\\":\\"table-index\\":0,\\"bucket-index-left\\":0,\\"bucket-index-right\\":180,\\"chunk-index\\":0,\\"chunk-count\\":1,\\"type\\":1,\\"bounds\\":[],\\"is-first\\":false,\\"is-last\\":false,\\"where\\":\\"((TRUE) AND (TRUE))\\",\\"args\\":null,\\"index-id\\":0"] [state=success]
[2022/05/21 12:23:22.286 +08:00] [INFO] [diff.go:377] ["close handleCheckpoint goroutine"]
[2022/05/21 12:23:22.301 +08:00] [INFO] [main.go:114] ["check data finished"] [cost=667.558558ms]
[2022/05/21 12:23:22.301 +08:00] [INFO] [main.go:108] ["check pass!!!"]
[root@k8s-master tidb-community-toolkit-v5.4.1-linux-amd64]# cat output/summary.txt
Summary
Source Database
host = "172.16.6.130"
port = 3306
user = "root"
Target Databases
host = "172.16.5.122"
port = 4000
user = "root"
Comparison Result
The table structure and data in following tables are equivalent
The following tables contains inconsistent data
+------------------+--------------------+----------------+---------+-----------+
| TABLE | STRUCTURE EQUALITY | DATA DIFF ROWS | UPCOUNT | DOWNCOUNT |
+------------------+--------------------+----------------+---------+-----------+
| test
.sbtest1
| true | +0/-988931 | 11497 | 1000428 |
+------------------+--------------------+----------------+---------+-----------+
Time Cost: 13.060266802s
Average Speed: 14.537384MB/s
2、TIDB主从集群的数据校验
2.1、获取ts-map获取下游的ts-map信息
Lua
MySQL [(none)]> select * from tidb_binlog.checkpoint;
+---------------------+-------------------------------------------------------------------------------------+
| clusterID | checkPoint |
+---------------------+-------------------------------------------------------------------------------------+
| 7094800466639767512 | "consistent":false,"commitTS":433356050585092097,"ts-map":,"schema-version":119 |
+---------------------+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
2.2、配置snapshot
使用上边获取的ts-map信息来配置上下游数据库的snapshot信息,其中配置如下:
Haskell
[data-sources]
######################### Datasource config #########################
[data-sources.mysql1]
host = "172.16.6.130"
port = 3306
user = "root"
password = "mysql"
snapshot = "409621863377928345"
[data-sources.tidb0]
host = "172.16.5.122"
port = 4000
user = "root"
password = "123456"
snapshot = "409621863377928345"
注意事项
• Drainer 的 db-type 需要设置为 tidb,这样才会在 checkpoint 中保存 ts-map。
• 需要调整 TiKV 的 GC 时间,保证在校验时 snapshot 对应的历史数据不会被执行 GC。建议调整为 1 个小时,在校验后再还原 GC 设置。
• 以上配置只展示 Datasource config 部分,并不完全。完整配置请参考 sync-diff-inspector 用户文档。
TiDB 主从集群的数据校验更新
3、分库分表场景下的数据校验
sync-diff-inspector 支持对分库分表场景进行数据校验。例如有多个 MySQL 实例,当你使用同步工具 TiDB DM 同步到一个 TiDB 时,可以使用 sync-diff-inspector 对上下游数据进行校验。
使用 datasource config 进行配置
使用 Datasource config 对 table-0 进行特殊配置,设置对应 rules,配置上游表与下游表的映射关系。这种配置方式需要对所有分表进行设置,适合上游分表数量较少,且分表的命名规则没有规律的场景。场景如图所示:
相关配置如下:
SQL
Diff Configuration.
######################### Global config #########################
检查数据的线程数量,上下游数据库的连接数会略大于该值
check-thread-count = 4
如果开启,若表存在不一致,则输出用于修复的 SQL 语句
export-fix-sql = true
只对比表结构而不对比数据
check-struct-only = false
######################### Datasource config #########################
[data-sources.mysql1]
host = "127.0.0.1"
port = 3306
user = "root"
password = ""
route-rules = ["rule1"]
[data-sources.mysql2]
host = "127.0.0.1"
port = 3306
user = "root"
password = ""
route-rules = ["rule2"]
[data-sources.tidb0]
host = "127.0.0.1"
port = 4000
user = "root"
password = ""
########################### Routes ###########################
[routes.rule1]
schema-pattern = "test" # 匹配数据源的库名,支持通配符 "" 和 "?"
table-pattern = "table-[1-2]" # 匹配数据源的表名,支持通配符 "" 和 "?"
target-schema = "test" # 目标库名
target-table = "table-0" # 目标表名
[routes.rule2]
schema-pattern = "test" # 匹配数据源的库名,支持通配符 "" 和 "?"
table-pattern = "table-3" # 匹配数据源的表名,支持通配符 "" 和 "?"
target-schema = "test" # 目标库名
target-table = "table-0" # 目标表名
######################### Task config #########################
[task]
output-dir = "./output"
source-instances = ["mysql1", "mysql2"]
target-instance = "tidb0"
# 需要比对的下游数据库的表,每个表需要包含数据库名和表名,两者由 `.` 隔开
target-check-tables = ["test.table-0"]
当上游分表较多,且所有分表的命名都符合一定的规则时,则可以使用 table-rules 进行配置。场景如图所示:
SQL
Diff Configuration.
######################### Global config #########################
检查数据的线程数量,上下游数据库的连接数会略大于该值
check-thread-count = 4
如果开启,若表存在不一致,则输出用于修复的 SQL 语句
export-fix-sql = true
只对比表结构而不对比数据
check-struct-only = false
######################### Datasource config #########################
[data-sources.mysql1]
host = "127.0.0.1"
port = 3306
user = "root"
password = ""
route-rules = ["rule1"]
[data-sources.mysql2]
host = "127.0.0.1"
port = 3306
user = "root"
password = ""
route-rules = ["rule1"]
[data-sources.tidb0]
host = "127.0.0.1"
port = 4000
user = "root"
password = ""
########################### Routes ###########################
[routes.rule1]
schema-pattern = "test" # 匹配数据源的库名,支持通配符 "" 和 "?"
table-pattern = "table-" # 匹配数据源的表名,支持通配符 "*" 和 "?"
target-schema = "test" # 目标库名
target-table = "table-0" # 目标表名
######################### Task config #########################
[task]
output-dir = "./output"
source-instances = ["mysql1", "mysql2"]
target-instance = "tidb0"
# 需要比对的下游数据库的表,每个表需要包含数据库名和表名,两者由 `.` 隔开
target-check-tables = ["test.table-0"]
备注
如果上游数据库有 test.table-0 也会被下游数据库匹配到。
4、基于DM同步场景下的数据校验
当在使用 TiDB DM 等同步工具时,需要校验 DM 同步后数据的一致性。你可以从 DM-master 拉取指定 task-name 的配置,进行数据校验。
SQL
Diff Configuration.
######################### Global config #########################
检查数据的线程数量,上下游数据库的连接数会略大于该值
check-thread-count = 4
如果开启,若表存在不一致,则输出用于修复的 SQL 语句
export-fix-sql = true
只对比表结构而不对比数据
check-struct-only = false
dm-master 的地址, 格式为 "http://127.0.0.1:8261"
dm-addr = "http://127.0.0.1:8261"
指定 DM 的 task-name
dm-task = "test"
######################### Task config #########################
[task]
output-dir = "./output"
# 需要比对的下游数据库的表,每个表需要包含数据库名和表名,两者由 `.` 隔开
target-check-tables = ["hb_test.*"]
该配置在 dm-task = "test" 中,会对该任务下 hb_test 库的所有表进行检验,自动从 DM 配置中获取上游对下游库名的正则匹配,以校验 DM 同步后数据的一致性。
以上是关于sync-diff数据比对工具的主要内容,如果未能解决你的问题,请参考以下文章