- 关于 TiDB
- 快速上手
- 应用开发
- 概览
- 快速开始
- 示例程序
- 连接到 TiDB
- 数据库模式设计
- 数据写入
- 数据读取
- 事务
- 优化 SQL 性能
- 故障诊断
- 引用文档
- 云原生开发环境
- 部署标准集群
- 数据迁移
- 运维操作
- 监控与告警
- 故障诊断
- 性能调优
- 优化手册
- 配置调优
- 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 诊断服务 (Technical Preview)
- 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 TABLE COMPACT
ALTER USER
ANALYZE TABLE
BACKUP
BATCH
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
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 模式
- 表属性
- 事务
- 视图
- 分区表
- 临时表
- 缓存表
- 字符集和排序
- 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)
- 版本发布历史
- 术语表
sync-diff-inspector 用户文档
sync-diff-inspector 是一个用于校验 MySQL/TiDB 中两份数据是否一致的工具。该工具提供了修复数据的功能(适用于修复少量不一致的数据)。
主要功能:
- 对比表结构和数据
- 如果数据不一致,则生成用于修复数据的 SQL 语句
- 支持不同库名或表名的数据校验
- 支持分库分表场景下的数据校验
- 支持 TiDB 主从集群的数据校验
- 支持从 TiDB DM 拉取配置的数据校验
你可通过以下方式下载 sync-diff-inspector:
Binary 包。sync-diff-inspector 的安装包位于 TiDB 离线工具包中。下载方式,请参考 TiDB 工具下载。
Docker 镜像。执行以下命令进行下载:
docker pull pingcap/tidb-enterprise-tools:nightly
sync-diff-inspector 的使用限制
对于 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
的配置项允许拥有多个配置值,因此需要使用方括号[]
来包含配置值。
# 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
执行如下命令:
./sync_diff_inspector --config=./config.toml
该命令最终会在 config.toml
中的 output-dir
输出目录输出本次比对的检查报告 summary.txt
和日志 sync_diff.log
。在输出目录下还会生成由 config.toml
文件内容哈希值命名的文件夹,该文件夹下包括断点续传 checkpoint 结点信息以及数据存在不一致时生成的 SQL 修复数据。
前台输出
sync-diff-inspector 在执行过程中会往 stdout
发送进度信息。进度信息包括表的结构比较结果、表的数据比较结果以及进度条。
为了达成显示效果,请保持显示窗口宽度在80字符以上。
A total of 2 tables need to be compared
Comparing the table structure of ``sbtest`.`sbtest96`` ... equivalent
Comparing the table structure of ``sbtest`.`sbtest99`` ... equivalent
Comparing the table data of ``sbtest`.`sbtest96`` ... failure
Comparing the table data of ``sbtest`.`sbtest99`` ...
_____________________________________________________________________________
Progress [==========================================================>--] 98% 193/200
A total of 2 tables need to be compared
Comparing the table structure of ``sbtest`.`sbtest96`` ... equivalent
Comparing the table structure of ``sbtest`.`sbtest99`` ... equivalent
Comparing the table data of ``sbtest`.`sbtest96`` ... failure
Comparing the table data of ``sbtest`.`sbtest99`` ... failure
_____________________________________________________________________________
Progress [============================================================>] 100% 0/0
The data of `sbtest`.`sbtest99` is not equal
The data of `sbtest`.`sbtest96` is not equal
The rest of tables are all equal.
The patch file has been generated in
'output/fix-on-tidb2/'
You can view the comparision details through 'output/sync_diff.log'
输出文件
输出文件目录结构如下:
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
的值。
+---------------------+--------------------+----------------+
| 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 文件中通过注释的方法标明不同的列
-- 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 修复数据。