gt-checksum v4.0.0 新功能解读系列文章(2):自定义数据类型映射——异构迁移不再手工对齐

发布时间:2026/6/29 21:20:16
gt-checksum v4.0.0 新功能解读系列文章(2):自定义数据类型映射——异构迁移不再手工对齐 功能简介dTypeMappingFile是 gt-checksum v4.0.0 在checkObjectstruct结构校验模式下新增的核心参数用于指定用户自定义的数据类型映射规则文件。参数说明参数默认值说明dTypeMappingFile空使用内置规则指定 YAML 或 JSON 格式的映射规则文件路径--preview-dtype-mapping-CLI 参数加载规则后输出映射预览表并退出便于调试验证在配置文件gc.conf中添加一行即可启用dTypeMappingFile/path/to/dtype-mapping.yaml支持的迁移场景映射规则按迁移场景分组gt-checksum 会根据源端和目标端的数据库类型及版本自动选择对应的规则组场景键名适用场景说明oracle_to_mysqlOracle → MySQL 异构迁移处理 NUMBER、VARCHAR2、DATE 等 Oracle 特有类型mysql_upgradeMySQL 跨版本升级处理 5.6/5.7 → 8.0/8.4 等版本间的类型差异mariadb_to_mysqlMariaDB → MySQL 迁移处理 MariaDB 特有的类型别名和属性差异二、功能作用及使用场景深入解读2.1 为什么需要自定义数据类型映射在真实的迁移项目中数据类型映射远比一对一替换复杂场景一Oracle NUMBER 类型的多义性Oracle 的NUMBER类型是一个万能数值类型可以表示整数、定点数、浮点数取决于precision和scale的组合NUMBER(10,0)→ 应映射为BIGINT整数NUMBER(10,2)→ 应映射为DECIMAL(10,2)定点数NUMBER无精度 → 应映射为DECIMAL或保持原样不同业务场景对同一个NUMBER可能有不同的映射策略内置规则无法覆盖所有情况。场景二MySQL 跨版本的类型漂移MySQL 5.7 到 8.0 升级过程中部分类型的默认行为发生了变化如utf8mb4的默认 collation 从utf8mb4_general_ci变为utf8mb4_0900_ai_ci某些旧类型在新版本中有更合适的替代。升级校验时需要明确告诉工具这些差异是预期的。场景三MariaDB 到 MySQL 的类型别名MariaDB 引入了一些类型别名如INET6、UUID这些类型在 MySQL 中并不存在。迁移到 MySQL 时需要将INET6映射为VARCHAR(39)、UUID映射为CHAR(36)等。虽然 gt-checksum 内置了这些基础映射但用户可能需要更精细的控制如指定nullable、default等属性。场景四同名类型的不同属性要求即使是同一种类型不同列可能需要不同的属性配置。例如迁移后的某些列要求NOT NULL DEFAULT 而另一些列允许NULL。这种列级别的精细控制需要通过自定义规则来实现。2.2 规则文件格式gt-checksum 支持 YAML 和 JSON 两种格式。推荐使用 YAML 格式可读性更好。YAML 格式结构dTypeMapping:oracle_to_mysql:- source_type: NUMBERtarget_type: BIGINTcondition: p 19 and s 0description: 整数小于等于19位映射为BIGINT- source_type: NUMBERtarget_type: DECIMALdescription: 其余NUMBER映射为DECIMAL(p,s)mariadb_to_mysql:- source_type: CHARtarget_type: VARCHARmysql_upgrade:- source_type: CHARtarget_type: VARCHAR顶层键固定为dTypeMapping下面按场景分组每个场景包含一组规则列表。JSON 格式{dTypeMapping: {oracle_to_mysql: [{source_type: NUMBER, target_type: BIGINT, condition: p 19 and s 0}]}}2.3 规则字段详解每条规则支持以下字段字段必填类型说明source_type是string源端类型名大小写不敏感如NUMBER、VARCHAR2target_type是string目标端类型名可含精度如BIGINT、DECIMAL(10,2)condition否string条件表达式用于精细匹配见下文object否string对象级匹配模式支持schema.*、schema.table、schema.table.columncolumn_pattern否string列名正则匹配如^id_、_type$nullable否bool覆盖目标端列的 NULL/NOT NULL 属性unsigned否bool覆盖目标端列的 UNSIGNED 属性仅数值类型autoinc否bool过滤条件仅匹配源端列是否具有 AUTO_INCREMENT 属性default否any覆盖目标端列的默认值description否string规则说明纯文档不影响匹配逻辑2.4 条件表达式condition字段支持一个轻量级的条件表达式引擎用于根据列的精度属性精细匹配。支持的变量变量含义示例p精度PrecisionNUMBER(10,2)中p10s小数位ScaleNUMBER(10,2)中s2nullable是否允许 NULL1表示允许0表示不允许unsigned是否无符号1表示 UNSIGNEDautoinc是否自增1表示 AUTO_INCREMENT支持的运算符比较、!、、、、逻辑and优先级高、or条件表达式示例# NUMBER 精度 19 且小数位为 0 → 整数映射为 BIGINTcondition: p 19 and s 0# 精度 19 或有小数位 → 映射为 DECIMALcondition: p 19 or s 0# 仅匹配源端为 UNSIGNED 的列condition: unsigned 1设计要点nullable、unsigned、default是覆盖属性override不是过滤条件。也就是说一条规则不会因为源端列的nullable状态不同而不匹配——它匹配后会覆盖目标端的对应属性。如果需要按源端unsigned状态过滤应使用condition: unsigned 1而非unsigned: true。2.5 对象级精细匹配object 字段object字段支持三个层级的精细匹配格式为schema.table.column格式示例匹配范围schema.*mydb.*mydb下所有表的所有列schema.tablemydb.ordersmydb.orders表的所有列schema.table.columnmydb.orders.order_id精确匹配单个列匹配过程大小写不敏感。object可以与condition、column_pattern组合使用实现多维度的精细控制。使用示例mariadb_to_mysql:# 案例1schema 级 — sbtest 下所有表的 CHAR 都映射为 VARCHAR- object: sbtest.*source_type: CHARtarget_type: VARCHARnullable: falsedefault: # 案例2表级 — 只映射 sbtest.t9 的 INT 列- object: sbtest.t9source_type: INTtarget_type: BIGINTunsigned: trueautoinc: true# 案例3列级 — 只映射 sbtest.t9 的 c 列- source_type: CHARtarget_type: VARCHARobject: sbtest.t9.cnullable: falsedefault: 2.6 匹配语义First-Match规则采用first-match首次匹配语义在规则列表中先定义的规则优先匹配。一旦某条规则匹配成功后续规则不再检查。这意味着在编写规则时更具体的规则应放在前面更通用的兜底规则放在后面oracle_to_mysql:# 具体规则在前NUMBER 精度 19 且无小数位 → BIGINT- source_type: NUMBERtarget_type: BIGINTcondition: p 19 and s 0# 通用规则在后其余 NUMBER → DECIMAL- source_type: NUMBERtarget_type: DECIMAL如果顺序反过来所有NUMBER类型都会被第一条无条件规则匹配为DECIMAL后面的条件规则永远不会生效。2.7 规则如何影响校验和修复自定义映射规则在两个阶段发挥作用比较阶段Struct Comparison在校验源端和目标端的表结构时gt-checksum 会先根据映射规则将源端列的类型翻译为期望的目标端类型然后再与目标端的实际类型比较。如果目标端的实际类型与映射后的期望类型一致就认为这是一个已知可接受的迁移转换不标记为差异。修复阶段Repair SQL Generation当检测到结构差异需要生成修复 SQL 时映射规则中的覆盖属性nullable、unsigned、autoinc、default会被写入ALTER TABLE ... MODIFY COLUMN语句中确保修复后的列属性符合预期。三、功能使用演示3.1 编写映射规则文件以 Oracle → MySQL 迁移为例创建dtype-mapping.yamldTypeMapping:oracle_to_mysql:# NUMBER 精度 19 且无小数位 → BIGINT- source_type: NUMBERtarget_type: BIGINTcondition: p 19 and s 0description: 整数 19位映射为BIGINT# NUMBER 精度 19 且有小数位 → DECIMAL- source_type: NUMBERtarget_type: DECIMALcondition: s 0description: 有小数位的NUMBER映射为DECIMAL(p,s)# 其余 NUMBER → DECIMAL兜底- source_type: NUMBERtarget_type: DECIMALdescription: 其余NUMBER映射为DECIMAL# VARCHAR2 → VARCHAR- source_type: VARCHAR2target_type: VARCHARdescription: VARCHAR2映射为VARCHAR# DATE → DATETIME- source_type: DATEtarget_type: DATETIMEdescription: Oracle DATE包含时间映射为DATETIME3.2 配置文件集成在gc.conf中设置checkObjectstructtablessrcdb.*srcDSNuser:ENC[...]tcp(10.0.0.1:1521)/orcldstDSNuser:ENC[...]tcp(10.0.0.2:3306)/dstdbdTypeMappingFile./dtype-mapping.yaml3.3 预览映射规则使用--preview-dtype-mapping参数可以在正式运行前验证规则文件的解析结果$ gt-checksum -c gc.conf --preview-dtype-mapping[dTypeMapping] Scenario: oracle_to_mysql (5 rules)No. source_type target_type object autoinc condition description---- -------------------- -------------------- -------------------- -------- ------------------------------ -----------1 NUMBER BIGINT (any) - p 19 and s 0 整数 19位映射为BIGINT2 NUMBER DECIMAL (any) - s 0 有小数位的NUMBER映射为DECIMAL(p,s)3 NUMBER DECIMAL (any) - (any) 其余NUMBER映射为DECIMAL4 VARCHAR2 VARCHAR (any) - (any) VARCHAR2映射为VARCHAR5 DATE DATETIME (any) - (any) Oracle DATE包含时间映射为DATETIME预览输出后程序直接退出不会连接数据库或执行校验适合在编写规则后快速验证格式和匹配逻辑。3.4 正常运行校验$ gt-checksum -c gc.confInitializing gt-checksumReading configuration filesOpening log filesChecking configuration options[STRUCT] Comparing: srcdb.orders ↔ dstdb.orders[DIFF] srcdb.orders.created_at: sourceDATE, destDATETIME → covered by dTypeMapping rule #5, skipped[OK] srcdb.orders.order_id: sourceNUMBER(19,0) → BIGINT, destBIGINT, matched[DIFF] srcdb.orders.status: sourceVARCHAR2(10), destVARCHAR(10) → covered by dTypeMapping rule #4, skipped