openGauss5.1:MySQL数据校验
功能介绍
数据校验工具 gs_datacheck,分为check服务和extract服务。check服务用于数据校验,extract服务用于数据抽取和规整。
原理介绍
全量校验:
在全量数据迁移完成后,由extract服务对源端和目标端数据通过JDBC方式进行数据抽取然后规整计算,并将计算后的中间数据推送到kafka中。最后由check服务提取kafka中的中间数据,构建默克尔树,通过默克尔树比对实现表数据校验且输出校验结果。
增量校验:
由debezium服务侦听源端数据库的增量数据,到指定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,可实现全量迁移的安装、启动、停止、卸载整个过程。
根据系统版本下载对应版本的portal(这里以centos系统x86架构为例)
wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/tools/centos7/PortalControl-5.1.0-x86_64.tar.gz
不同系统版本和架构对应的portal下载链接详见portal下载链接
解压,并进入portal对应目录
tar -zxvf PortalControl-5.1.0-x86_64.tar.gz cd portal
修改gs_rep_portal配置文件
配置文件位于config目录内,数据校验相关的配置文件主要包含如下三个,相关参数含义简要说明如下:
- application.yml
#校验服务配置 修改application.yml文件 server: port: 9000 # 为校验服务web端口,默认可不修改 logging: config: config/log4j2.xml 设置校验服务日志路径为config/log4j2.xml文件绝对路径 spring: kafka: bootstrap-servers: localhost:9092 # 为kafka工作地址,默认安装可不修改 check: core-pool-size: 1 # 校验并发线程池-核心线程数 maximum-pool-size: 4 # 校验并发线程池-最大线程数 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 1. 提供三种过滤规则,分别是表级、行级、列级。规则是以列表集合的形式配置的。 rules: enable: false # 过滤规则开关:enable=true启用过滤规则,enable=false关闭过滤规则 1. 表级过滤规则:通过配置黑白列表来过滤当前数据库表。 1. 黑白列表配置是互斥的,即不能同时配置黑白列表,如果同时配置黑名单和白名单,则只有白名单才会生效。 1. 黑名单和白名单配置规则必须遵守: 1. 配置的name属性必须是white或black,否则规则无效,我们将自动过滤无效规则 1. 如果配置的text属性不不符合正则表达式,或者为空,则该规则无效,将自动丢弃该规则 1. 如果配置的TEXT重复,则规则项将自动筛选重复项。 table: 1. - name: white 1. text: ^[a-zA-Z][a-zA-Z_]+$ 1. - name: black 1. text: ^[a-zA-Z][a-zA-Z_]+$ 1. 行级过滤是通过添加规则来过滤所有表中需要验证的记录。 1. 根据主键对表数据进行升序排序,并根据用户配置的抽取范围来进行数据抽取。 1. 如果表规则和行规则同时配置,则行规则将根据表规则进行适配。 1. 行级规则配置规则 例如:10,100 1. 如果表名为table_name,主键为id,给当前表添加该行级过滤规则,则SQL等效为select * from table_name order by id asc limit 10 , 100 1. 行配置规则必须遵守: 1. 如果配置的文本与正则表达式^\d+(\,\d+)不匹配,则该规则无效,将自动筛选 1. 如果配置的名称不不符合正则表达式,或者为空,则该规则无效,将自动筛选 1. 如果配置的名称重复,则规则项将自动筛选重复的名称 1. 行过滤规则配置 row: 1. - name: ^[a-zA-Z][a-zA-Z_]+$ 1. text: 10,100 1. - name: ^[a-zA-Z][a-zA-Z_]+$ 1. text: 100,100 1. - name: ^[a-zA-Z]+$a-zA-Z_]+$ 1. text: 100,300 1. - name: ^[a-zA-Z]+$ 1. text: 10a,100 1. - name: ^[a-zA-Z][a-zA-Z0-9_]+$ 1. text: 10,100 1. 列级过滤是通过添加的规则来过滤当前表中需要校验的字段列。列级过滤分为两类:包含规则和排他规则。它们之间是互斥的。 1. 包含规则只校验已配置的字段列表,排他规则不校验已配置字段列表。由于我们进行数据校验时,要求待校验表必须包含主键。因此,如果包含规则中没有配置主键字段,包含规则将自动添加主键列。此外,如果排它规则中配置了主键字段,则排它规则将自动删除主键列 1. 列级规则配置 1. name: 表名称 表名称不能为空,会自动过滤重复表配置 1. text: field1,field2,...field 1. attribute: include 表示包含规则 或者 exclude表示排它规则 column: 1. - name: t_test_1 1. text: id,portal_id,func_id,name,width,last_upd_time 1. attribute: include 1. - name: t_test_2 1. text: id,portal_id,func_id,name 1. attribute: include 1. - name: t_test_2 1. text: name,height,last_upd_time,last_upd_time 1. attribute: include 1. - name: t_test_4 1. text: name,height,last_upd_time 1. attribute: exclude
- application-source.yml
源端服务配置 修改application-source.yml文件 server: port: 9001 # 为源端抽取服务web端口,默认可不修改 logging: config: config/log4j2.xml 设置校验服务日志路径为 config/log4j2.xml文件绝对路径 spring: check: server-uri: http://127.0.0.1:9000 # 校验服务请求地址,默认配置可不修改 core-pool-size: 1 # 校验并发线程池-核心线程数 maximum-pool-size: 5 # 校验并发线程池-最大线程数 maximum-topic-size: 5 # 校验并发Topic数量 maximum-table-slice-size: 100000 # 大表分片数量,例如设置为10万,则将含有100万记录的表分割为10个分片,进行独立抽取 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工作地址,默认安装可不修改 1. 数据源配置,工具默认采用druid数据源,用户可以自定义配置连接池参数,可根据当前校验数据库任务数量(表数量)进行调整 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.0.114:13306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowPublicKeyRetrieval=true username: password: 'xxxx' # druid: initial-size: 5 # 默认初始连接大小 minIdle: 10 # 默认最小连接池数量 maxActive: 50 # 最大连接数 maxActive 大于query-dop 一般为query-dop 的2-3倍 test-while-idle: true test-on-borrow: true validation-query: "SELECT 1 FROM DUAL" validation-query-timeout: 10000 connection-error-retry-attempts: 0 break-after-acquire-failure: true max-wait: 6000 keep-alive: true min-evictable-idle-time-millis: 600000
- application-sink.yml
# 目标端服务配置 修改application-sink.yml文件 server: port: 9002 # 为目标端抽取服务web端口,默认可不修改 logging: config: config/log4j2.xml 设置校验服务日志路径为config/log4j2.xml文件绝对路径 spring: check: server-uri: http://127.0.0.1:9000 # 校验服务请求地址,默认配置可不修改 core-pool-size: 1 # 校验并发线程池-核心线程数 maximum-pool-size: 5 # 校验并发线程池-最大线程数 maximum-topic-size: 5 # 校验并发Topic数量 maximum-table-slice-size: 100000 # 大表分片数量,例如设置为10万,则将含有100万记录的表分割为10个分片,进行独立抽取 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工作地址,默认安装可不修改 1. 数据源配置,工具默认采用druid数据源,用户可以自定义配置连接池参数,可根据当前校验数据库任务数量(表数量)进行调整 datasource: driver-class-name: org.opengauss.Driver url: jdbc:opengauss://192.168.0.114:25432/test_check?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: password: 'xxxxxx' # The password text may contain special characters, which need to be enclosed in quotation marks 1. Configure initialization connection pool size, minimum number of connections, and maximum number of connections 1. Users can make appropriate adjustments according to the number of current database tables druid: initial-size: 5 # 默认初始连接大小 min-idle: 10 # 默认最小连接池数量 max-active: 50 # 最大连接数 maxActive 大于query-dop 一般为query-dop 的2-3倍 test-while-idle: true test-on-borrow: true validation-query: "select 1" validation-query-timeout: 10000 connection-error-retry-attempts: 0 break-after-acquire-failure: true max-wait: 6000 keep-alive: true min-evictable-idle-time-millis: 600000
安装
# 全量校验 sh gs_datacheck.sh install full workspace.id 1. 增量校验 sh gs_datacheck.sh install incremental workspace.id
其中workspace.id表示迁移任务id,取值为一个整数,不同的id区分不同的校验任务,不同校验任务可并行启动。full 表示全量校验 ,incremental 表示增量校验
启动
# 全量校验 sh gs_datacheck.sh start full workspace.id 1. 增量校验 sh gs_datacheck.sh start incremental workspace.id
停止
# 全量校验 sh gs_datacheck.sh stop full workspace.id 1. 增量校验 sh gs_datacheck.sh stop incremental workspace.id
卸载
# 全量校验 sh gs_datacheck.sh uninstall full workspace.id 1. 增量校验 sh gs_datacheck.sh uninstall incremental workspace.id
注意事项
- JDK版本要求JDK11+。
- 当前版本仅支持对源端MySQL或openGauss,目标端也是MySQL或openGauss的数据校验。
- 当前版本仅支持数据校验,不支持表对象校验。
- MYSQL需要5.7+版本。
- 当前版本对地理位置几何图形类型的校验只在openGauss到openGauss的校验场景下支持。
- 校验工具当前不支持校验中断(网络故障、kill进程等)自动恢复。
- 数据校验行级过滤规则配置,只支持[offset,count]指定范围内抽取,不支持排除[offset,count]范围之内的数据过滤。
- 行过滤规则抽取中间范围内数据(例如:[10,100]),如果源端在该范围之前的数据[0,10]发生删除操作,则会导致该表在指定范围内数据发生偏移,从而导致数据校验结果产生差异。此时需要扩大前置下标范围,以及增加相应的抽取数量。即[3,107]。
- 当对主键的update语句没有通过增量迁移同步到目的端 或 主键同步发生错误的时候,进行数据校验,源端update后的新数据和目标端的旧数据是两条独立的数据,对校验差异进行处理时,会生成两条语句,即对旧数据进行删除,对新数据做插入。此场景会将一条主键update语句拆分为两条语(insert+delete)来执行,且分解到两个事务中执行,无法保证原子性。
- 增量校验不支持表级规则。
- 增量校验不支持行级规则。
- 增量校验目前只支持数据增删改校验,暂时不支持表结构(对象)校验(包括多表少表)。