数据校验
功能介绍
数据校验工具 gs_datacheck,分为check服务和extract服务。check服务用于数据校验,extract服务用于数据抽取和规整。
原理介绍
全量校验:
在全量数据迁移完成后,由extract服务对MySQL源端和openGauss目标端数据通过JDBC方式进行数据抽取然后规整计算,并将计算后的中间数据推送到kafka中。最后由check服务提取kafka中的中间数据,构建默克尔树,通过默克尔树比对实现表数据校验且输出校验结果。
增量校验:
由debezium服务侦听源端MySQL数据库的增量数据,到指定topic。再由源端extract服务处理该topic增量数据,触发check增量校验。
环境准备
- ARM+openEuler 20.03 或 X86+CentOS 5.7
- JDK : JDK11+
- MYSQL:要求5.7+版本
- openGauss:openGauss3.0.0+
操作步骤
全量校验 gs_datacheck 依赖MySQL一键式迁移工具gs_rep_portal,可实现全量迁移的安装、启动、停止、卸载整个过程。
下载gs_rep_portal
wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/tools/portal/PortalControl-5.0.0.tar.gz
解压,并进入portal对应目录
tar -zxvf PortalControl-5.0.0.tar.gz
cd portal
修改gs_rep_portal配置文件
配置文件位于config目录内,数据校验相关的配置文件主要包含如下三个,相关参数含义简要说明如下:
- application.yml
#校验服务配置 修改application.yml文件
server:
port: 9000 # 为校验服务web端口,默认可不修改
logging:
config: # absolute_path/config/log4j2.xml 设置校验服务日志路径为config/log4j2.xml文件绝对路径
spring:
kafka:
bootstrap-servers: localhost:9092 # 为kafka工作地址,默认安装可不修改
data:
check:
data-path: ./check_result # 校验结果输出地址,默认配置可不修改
source-uri: http://127.0.0.1:9001 # server.port=9001 源端服务请求地址,默认配置可不修改
sink-uri: http://127.0.0.1:9002 # server.port=9002 目标端服务请求地址,默认配置可不修改
auto-delete-topic: 2 #配置是否自动删除Topic,0不删除,1校验全部完成后删除,2表校验完
成后删除,默认值为2
increment-max-diff-count: 10 #增量校验表最大处理差异数,超过则暂停校验,差异降低则重新自动开启增量校验
core-pool-size: 10 #并发线程数设置,根据当前环境配置,可不修改,默认10,设置为0则系统自动分配
max-retry-times: 1000 # 心跳等最大尝试次数,默认1000
retry-interval-times: 10000 # 心跳、进度等最大间隔时间单位毫秒 默认10000
# 提供三种过滤规则,分别是表级、行级、列级。规则是以列表集合的形式配置的。
rules:
enable: false # 过滤规则开关:enable=true启用过滤规则,enable=false关闭过滤规则
# 表级过滤规则:通过配置黑白列表来过滤当前数据库表。
# 黑白列表配置是互斥的,即不能同时配置黑白列表,如果同时配置黑名单和白名单,则只有白名单才会生效。
# 黑名单和白名单配置规则必须遵守:
# 配置的name属性必须是white或black,否则规则无效,我们将自动过滤无效规则
# 如果配置的text属性不不符合正则表达式,或者为空,则该规则无效,将自动丢弃该规则
# 如果配置的TEXT重复,则规则项将自动筛选重复项。
table:
# - name: white
# text: ^[a-zA-Z][a-zA-Z_]+$
# - name: black
# text: ^[a-zA-Z][a-zA-Z_]+$
# 行级过滤是通过添加规则来过滤所有表中需要验证的记录。
# 根据主键对表数据进行升序排序,并根据用户配置的抽取范围来进行数据抽取。
# 如果表规则和行规则同时配置,则行规则将根据表规则进行适配。
# 行级规则配置规则 例如:10,100
# 如果表名为table_name,主键为id,给当前表添加该行级过滤规则,则SQL等效为select * from table_name order by id asc limit 10 , 100
# 行配置规则必须遵守:
# 如果配置的文本与正则表达式^\d+(\,\d+)不匹配,则该规则无效,将自动筛选
# 如果配置的名称不不符合正则表达式,或者为空,则该规则无效,将自动筛选
# 如果配置的名称重复,则规则项将自动筛选重复的名称
# 行过滤规则配置
row:
# - name: ^[a-zA-Z][a-zA-Z_]+$
# text: 10,100
# - name: ^[a-zA-Z][a-zA-Z_]+$
# text: 100,100
# - name: ^[a-zA-Z]+$a-zA-Z_]+$
# text: 100,300
# - name: ^[a-zA-Z]+$
# text: 10a,100
# - name: ^[a-zA-Z][a-zA-Z0-9_]+$
# text: 10,100
# 列级过滤是通过添加的规则来过滤当前表中需要校验的字段列。列级过滤分为两类:包含规则和排他规则。它们之间是互斥的。
# 包含规则只校验已配置的字段列表,排他规则不校验已配置字段列表。由于我们进行数据校验时,要求待校验表必须包含主键。因此,如果包含规则中没有配置主键字段,包含规则将自动添加主键列。此外,如果排它规则中配置了主键字段,则排它规则将自动删除主键列
# 列级规则配置
# name: 表名称 表名称不能为空,会自动过滤重复表配置
# text: field1,field2,...field
# attribute: include 表示包含规则 或者 exclude表示排它规则
column:
# - name: t_test_1
# text: id,portal_id,func_id,name,width,last_upd_time
# attribute: include
# - name: t_test_2
# text: id,portal_id,func_id,name
# attribute: include
# - name: t_test_2
# text: name,height,last_upd_time,last_upd_time
# attribute: include
# - name: t_test_4
# text: name,height,last_upd_time
# attribute: exclude
- application-source.yml
源端服务配置 修改application-source.yml文件
server:
port: 9001 # 为源端抽取服务web端口,默认可不修改
logging:
config: # absolute_path/log4j2source.xml 设置校验服务日志路径为config/log4j2source.xml文件绝对路径
spring:
check:
server-uri: http://127.0.0.1:9000 # 校验服务请求地址,默认配置可不修改
max-core-pool-size: 10 # 并发线程数设置,可不修改,默认10,设置为0则系统自动分配
max-retry-times: 1000 # 最大尝试次数
retry-interval-times: 10000 # 最大间隔时间单位毫秒 默认10000
extract:
schema: test # 当前校验数据schema,mysql 数据库名称
databaseType: MS # 当前校验数据库类型 mysql MS , opengauss OG
query-dop: 8 # 表JDBC并行查询度,当表数据量超过百万时自动生效,默认为8,最大64
debezium-enable: false # 是否开启增量配置
debezium-topic: data_check_avro_inc_topic_w1 # debezium topic
debezium-serializer: AvroSerializer # 序列化类型 StringSerializer or AvroSerializer
debezium-avro-registry: http://localhost:8081 # avro schema 注册地址
debezium-groupId: debezium-extract-group # debezium topic groupId
debezium-time-period: 1 # 增量校验配置周期(单位分钟): 24 * 60 unit: Min
debezium-num-period: 1000 # 增量校验数量周期,最小值100,默认1000
kafka:
bootstrap-servers: localhost:9092 # 为kafka工作地址,默认安装可不修改
# 数据源配置,工具默认采用druid数据源,用户可以自定义配置连接池参数,可根据当前校验数据库任务数量(表数量)进行调整
datasource:
druid:
dataSourceOne:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/mysql?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowPublicKeyRetrieval=true
username:
password: 'xxxx' #
initialSize: 5 # 默认初始连接大小
minIdle: 10 # 默认最小连接池数量
maxActive: 20 # 最大连接数 maxActive 大于query-dop 一般为query-dop 的2-3倍
- application-sink.yml
# 目标端服务配置 修改application-sink.yml文件
server:
port: 9002 # 为目标端抽取服务web端口,默认可不修改
logging:
config: # absolute_path/log4j2sink.xml 设置校验服务日志路径为config/log4j2sink.xml文件绝对路径
spring:
check:
server-uri: http://127.0.0.1:9000 # 校验服务请求地址,默认配置可不修改
max-core-pool-size: 10 # 并发线程数设置,可不修改,默认10,设置为0则系统自动分配
max-retry-times: 1000 # 最大尝试次数
retry-interval-times: 10000 # 最大间隔时间单位毫秒 默认10000
extract:
schema: test # 当前校验数据schema,mysql 数据库名称
databaseType: OG # 当前校验数据库类型 mysql MS , opengauss OG
query-dop: 8 # 表JDBC并行查询度,当表数据量超过百万时自动生效,默认为8,最大64
debezium-enable: false # debezium相关配置,在sink 端无需配置
debezium-topic: data_check_avro_inc_topic_w1 # debezium topic
debezium-serializer: AvroSerializer # 序列化类型 StringSerializer or AvroSerializer
debezium-avro-registry: http://localhost:8081 # avro schema 注册地址
debezium-groupId: debezium-extract-group # debezium topic groupId
debezium-time-period: 1 # 增量校验配置周期(单位分钟): 24 * 60 unit: Min
debezium-num-period: 1000 # 增量校验数量周期,最小值100,默认1000
kafka:
bootstrap-servers: localhost:9092 # 为kafka工作地址,默认安装可不修改
# 数据源配置,工具默认采用druid数据源,用户可以自定义配置连接池参数,可根据当前校验数据库任务数量(表数量)进行调整
datasource:
druid:
dataSourceOne:
driver-class-name: org.opengauss.Driver
url: jdbc:opengauss://xxxxx:xxx/xxxx?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username:
password: 'xxxx' #
initialSize: 5 # 默认初始连接大小
minIdle: 10 # 默认最小连接池数量
maxActive: 20 # 最大连接数 maxActive 大于query-dop 一般为query-dop 的2-3倍
安装
# 全量校验
sh gs_datacheck.sh install full workspace.id
# 增量校验
sh gs_datacheck.sh install incremental workspace.id
其中workspace.id表示迁移任务id,取值为一个整数,不同的id区分不同的校验任务,不同校验任务可并行启动。full 表示全量校验 ,incremental 表示增量校验
启动
# 全量校验
sh gs_datacheck.sh start full workspace.id
# 增量校验
sh gs_datacheck.sh start incremental workspace.id
停止
# 全量校验
sh gs_datacheck.sh stop full workspace.id
# 增量校验
sh gs_datacheck.sh stop incremental workspace.id
卸载
# 全量校验
sh gs_datacheck.sh uninstall full workspace.id
# 增量校验
sh gs_datacheck.sh uninstall incremental workspace.id
注意事项
- JDK版本要求JDK11+
- 当前版本仅支持对源端MySQL,目标端openGauss数据校验
- 当前版本仅支持数据校验,不支持表对象校验
- MYSQL需要5.7+版本
- 当前版本不支持地理位置几何图形数据校验
- 校验工具当前不支持校验中断(网络故障、kill进程等)自动恢复。
- 数据校验行级过滤规则配置,只支持[offset,count]指定范围内抽取,不支持排除[offset,count]范围之内的数据过滤。
- 行过滤规则抽取中间范围内数据(例如:[10,100]),如果源端在该范围之前的数据[0,10]发生删除操作,则会导致该表在指定范围内数据发生偏移,从而导致数据校验结果产生差异。此时需要扩大前置下标范围,以及增加相应的抽取数量。即[3,107]。
- 当对主键的update语句没有通过增量迁移同步到目的端 或 主键同步发生错误的时候,进行数据校验,源端update后的新数据和目标端的旧数据是两条独立的数据,对校验差异进行处理时,会生成两条语句,即对旧数据进行删除,对新数据做插入。此场景会将一条主键update语句拆分为两条语句(insert+delete)来执行,且分解到两个事务中执行,无法保证原子性。
- 增量校验不支持表级规则
- 增量校验不支持行级规则
- 增量校验目前只支持数据增删改校验,暂时不支持表结构(对象)校验(包括多表少表)