jobfile使用场景
为何需要采用jobfile方式?主要适用于表数量众多的情况,而我们实际上并不需要比对所有表。在DMFM平台上逐一勾选不仅繁琐,而且可能会遇到一个令人头疼的问题—辛苦勾选表半天后,保存时提示勾选的表数量超出上限。此外,在未部署DMDFM平台的情况下,可以利用SQL语句批量生成配置文件,这种方法既简便又快捷,并且可以设置定时作业自动执行比对任务。接下来,我将详细讲解jobfile作业的具体使用方法。
作业文件jobfile参数
可通过配置作业文件来指定需要校验的表组、列名、列映射关系以及行过滤条件,以简化校验命令。作业文件jobfile对应元素,作业文件为独立的配置文件,在执行校验作业时使用,不可配置在DMDVS的配置文件中。
作业文件jobfile的参数包括作业名、校验表组、校验列名以及行过滤条件等。
作业文件jobfile的参数值的字符集需与XML配置文件中encoding参数指定的字符集保持一致。
<?xml version="1.0" encoding="GB18030"?><job> <name>CMP_PERSON</name> <table_list> <table_info> <table_name>PERSON.ADDRESS==PERSON.ADDRESS</table_name> <col_map_flag>3</col_map_flag> <tab_cmp_flag>0</tab_cmp_flag> <row_partition_src><![CDATA["C1"<1000]]></row_partition_src> <row_partition_dest><![CDATA["C1"<1000]]></row_partition_dest> <key_list> <col>C1==C1</col> </key_list> <col_list> <col>C1==C1</col> <col>C2==D2</col> <col>C3==D3</col> </col_list> </table_info> </table_list></job>
常用参数
执行静态数据校验
执行静态数据校验作业
命令格式
首次执行静态数据校验作业。
CMP JOB [JOBNAME=<job_name>] <db_info_name_source> <db_info_name_dest> "<pair_name>" [EXCEPT_TABLES="<table_name>"] [<mask>]
重复执行静态数据校验作业。
CMP JOB JOBNAME=<job_name>
使用jobfile作业文件执行静态数据校验。
CMP JOB <db_info_name_source> <db_info_name_dest> jobfile="<jobfile_name>" [<mask>]
重复使用jobfile作业文件执行静态数据校验。
CMP JOB JOBNAME=<job_name> jobfile="<jobfile_name>"
使用DMDRS配置文件中的映射关系执行静态数据校验。
CMP JOB JOBNAME=<job_name> <db_info_name_source> <db_info_name_dest> [CPT_NAME=<cpt_name>] MAP="<drs.xml>" [<mask>]
重复使用DMDRS配置文件中的映射关系执行静态数据校验。
CMP JOB JOBNAME=<job_name> [CPT_NAME=<cpt_name>] MAP="<drs.xml>"
注意
若首次执行校验作业时使用掩码,重复执行该校验作业时这些掩码同样生效。例如,首次执行校验时使用校验规则与快速校验,重复执行时,如果不想使用规则,可以使用USERULE|NULL;如果不想使用快速校验,可以使用FAST|0。
jobfile实战
配置jobfile文件
使用jobfile对scott用户进行比对,编写测试文件
<?xml version="1.0" encoding="UTF-8"?><job> <name>CMP_SCOTT</name> <table_list> <table_info> <table_name>SCOTT.ADDRESS==SCOTT.ADDRESS</table_name> <table_name>SCOTT.ADDRESS==SCOTT.ADDRESS</table_name> </table_info> </table_list></job>
使用sql拼接处理
SELECT '<?xml version="1.0" encoding="UTF-8"?><job> <name>CMP_SCOTT</name> <table_list> <table_info>' || LISTAGG('<table_name>SCOTT.' || TABLE_NAME || '==SCOTT.' || TABLE_NAME || '</table_name>', CHR(10) || ' ') WITHIN GROUP (ORDER BY TABLE_NAME) || '</table_info> </table_list></job>' AS xml_resultFROM SYS.DBA_TABLES WHERE OWNER = 'SCOTT';
说明:
- 使用
<font >LISTAGG</font>函数将所有表名按指定格式拼接 <font >CHR(10)</font>用于添加换行符,保持格式整洁- 按照
<font >TABLE_NAME</font>排序确保输出顺序一致 - 最终输出符合您要求的XML格式
结果如下:
<?xml version="1.0" encoding="UTF-8"?><job> <name>CMP_SCOTT</name> <table_list> <table_info><table_name>SCOTT.BONUS==SCOTT.BONUS</table_name> <table_name>SCOTT.DEPT==SCOTT.DEPT</table_name> <table_name>SCOTT.EMP==SCOTT.EMP</table_name> <table_name>SCOTT.SALGRADE==SCOTT.SALGRADE</table_name> <table_name>SCOTT.T1==SCOTT.T1</table_name> <table_name>SCOTT.T2==SCOTT.T2</table_name> <table_name>SCOTT.测试==SCOTT.测试</table_name> <table_name>SCOTT.测试1==SCOTT.测试1</table_name></table_info> </table_list></job>
不支持 <font >LISTAGG</font>函数
SELECT '<?xml version="1.0" encoding="UTF-8"?><job> <name>CMP_SCOTT</name> <table_list> <table_info>' AS part1 FROM DUALUNION ALLSELECT ' <table_name>SCOTT.' || TABLE_NAME || '==SCOTT.' || TABLE_NAME || '</table_name>' FROM SYS.DBA_TABLES WHERE OWNER = 'SCOTT'UNION ALLSELECT ' </table_info> </table_list></job>' AS part2 FROM DUAL;
处理后结果如下,使用sqlark复制出来多了""手工处理即可
<?xml version="1.0" encoding="UTF-8"?><job> <name>CMP_SCOTT</name> <table_list> <table_info>" <table_name>SCOTT.DEPT==SCOTT.DEPT</table_name> <table_name>SCOTT.EMP==SCOTT.EMP</table_name> <table_name>SCOTT.SALGRADE==SCOTT.SALGRADE</table_name> <table_name>SCOTT.T1==SCOTT.T1</table_name> <table_name>SCOTT.T2==SCOTT.T2</table_name> <table_name>SCOTT.测试==SCOTT.测试</table_name> <table_name>SCOTT.测试1==SCOTT.测试1</table_name> <table_name>SCOTT.BONUS==SCOTT.BONUS</table_name> </table_info> </table_list></job>
参考以下方式
[dmdba@OADB1 bin]$ vi jobfile.xml[dmdba@OADB1 bin]$ cat jobfile.xml <?xml version="1.0" encoding="UTF-8"?><job> <name>CMP_SCOTT</name> <table_list> <table_info>" <table_name>SCOTT.DEPT==SCOTT.DEPT</table_name> <table_name>SCOTT.EMP==SCOTT.EMP</table_name> <table_name>SCOTT.SALGRADE==SCOTT.SALGRADE</table_name> <table_name>SCOTT.T1==SCOTT.T1</table_name> <table_name>SCOTT.T2==SCOTT.T2</table_name> <table_name>SCOTT.测试==SCOTT.测试</table_name> <table_name>SCOTT.测试1==SCOTT.测试1</table_name> <table_name>SCOTT.BONUS==SCOTT.BONUS</table_name> </table_info> </table_list></job>[dmdba@OADB1 bin]$
使用jobfile进行校验
cmp job db1 db2 jobfile="jobfile.xml"
执行成功后信息如下所示:
CSL> cmp job db1 db2 job jobfile="jobfile.xml"CSL[INFO]: [INPUT CMD: cmp job db1 db2 jobfile="jobfile.xml"]CMP[INFO]: [INPUT CMD: CMP JOB db1 db2 jobfile="jobfile.xml"]MGR[INFO]: CMP JOB NAME IS: CMP_SCOTT, TASK ID IS: 5CMP[CMP000005][INFO]: CMP JOB NAME IS: CMP_SCOTT, TASK ID IS: 5命令执行成功 CSL>
查看验证结果
使用show job 查询任务名称
CSL> show jobCSL[INFO]: [INPUT CMD: show job]+----------------------------------------------------------------------------+| 【作业信息】 |+----------------------------------------------------------------------------+| 作业名 | 源数据库名 | 目标数据库名 | 校验表组 | 校验掩码 |+------------+------------+--------------+------------------------+----------+| CMP_PERSON | DB1 | DB2 | SYSDBA.*==SYSDBA.* | NULL || CMP_SCOTT | DB1 | DB2 | SCOTT.DEPT==SCOTT.DEPT | NULL |+------------+------------+--------------+------------------------+----------+命令执行成功 CSL>
查看比对结果
CSL> SHOW REPORT CMP_SCOTTCSL[INFO]: [INPUT CMD: SHOW REPORT CMP_SCOTT]+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 【校验作业报告】 |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 作业名 | 校验任务ID | 已完成校验的表个数 | 待完成校验的表个数 | 表一致数 | 表差异数 | 表失败数 | 表停止数 | 表总个数 |+------------------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+| CMP_SCOTT | 5 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |+------------------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+| 【校验详细信息】 |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 校验表组 | 源表行数/差异列名 | 目标表行数/差异列类型 | 相同行数 | 不同行数 | 总耗时(毫秒) | 源表读取耗时(毫秒) | 目标表读取耗时(毫秒) | 校验结果 |+------------------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+| SCOTT.DEPT==SCOTT.DEPT | 4 | 4 | 4 | 0 | 20 | 19 | 14 | 校验成功 - 数据一致 |+------------------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+命令执行成功 CSL>
带条件比对实践
数据一致情况下比对
- 配置jobif.xml 文件信息,本次以 CS 表为案例,信息如下
<?xml version="1.0" encoding="GB18030"?><job> <name>CMP_CSTAB</name> <table_list> <table_info> <table_name>CS.CS==CS.CS</table_name> <col_map_flag>0</col_map_flag> <tab_cmp_flag>0</tab_cmp_flag> <row_partition_src><![CDATA["ID"=1]]></row_partition_src> <row_partition_dest><![CDATA["ID"=1]]></row_partition_dest> </table_info> </table_list></job>
- 登录 DVS 进行数据比对
./drcsl dvs.xmlcmp job db1 db2 jobfile="jobif.xml"
结果如下所示:
[dmdba@OADB1 bin]$ ./drcsl dvs.xmlCSL[INFO]: CONSOLE TOOL DRS5: V5.2.5.1-Build(2025.10.11-201427_trunc)_64CSL[WARN]: 未能检测到key文件,将使用默认生成的临时key CSL[WARN]: mem_size参数配置过大,超过系统剩余内存大小 mem_size: 16G, total_free_size: 1GCSL> connectCSL[INFO]: [INPUT CMD: connect]CSL> cmp job db1 db2 jobfile="jobif.xml"CSL[INFO]: [INPUT CMD: cmp job db1 db2 jobfile="jobif.xml"]CMP[INFO]: [INPUT CMD: CMP JOB db1 db2 jobfile="jobif.xml"]MGR[INFO]: CMP JOB NAME IS: CMP_CSTAB, TASK ID IS: 98CMP[CMP000098][INFO]: CMP JOB NAME IS: CMP_CSTAB, TASK ID IS: 98命令执行成功 CSL>
- 如不不记得配置的 JOB 名称,可以使用 show job查看 JOB信息
CSL[INFO]: [INPUT CMD: show job]+------------------------------------------------------------------------+| 【作业信息】 |+------------------------------------------------------------------------+| 作业名 | 源数据库名 | 目标数据库名 | 校验表组 | 校验掩码 |+------------+------------+--------------+--------------------+----------+| CMP_CS | DB1 | DB2 | CS.CS==CS.CS | NULL || CMP_CSTAB | DB1 | DB2 | CS.CS==CS.CS | NULL || CMP_PERSON | DB1 | DB2 | SYSDBA.*==SYSDBA.* | NULL || CMP_SCOTT | DB1 | DB2 | SCOTT.*==SCOTT.* | NULL |+------------+------------+--------------+--------------------+----------+命令执行成功 CSL>
- 查看比对信息,结果如下所示
CSL> show report CMP_CSTABCSL[INFO]: [INPUT CMD: show report CMP_CSTAB]+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 【校验作业报告】 |+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 作业名 | 校验任务ID | 已完成校验的表个数 | 待完成校验的表个数 | 表一致数 | 表差异数 | 表失败数 | 表停止数 | 表总个数 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+| CMP_CSTAB | 98 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+| 【校验详细信息】 |+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 校验表组 | 源表行数/差异列名 | 目标表行数/差异列类型 | 相同行数 | 不同行数 | 总耗时(毫秒) | 源表读取耗时(毫秒) | 目标表读取耗时(毫秒) | 校验结果 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+| CS.CS==CS.CS | 1 | 1 | 1 | 0 | 428 | 388 | 427 | 校验成功 - 数据一致 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+---------------------+命令执行成功 CSL>
通过日志文件查看详细信息
[dmdba@OADB1 bin]$ cat report/CMP_CSTAB_99/report.txt ******************************************************版本 : V5.2.5.1-Build(2025.10.11-201427_trunc)_64执行时间 : 2025-10-30 15:52:32结束时间 : 2025-10-30 15:52:34 ******************************************************[OK] CS.CS==CS.CS源端表总行数 : 1目的表总行数 : 1同步成功 : 1同步失败 : 0[dmdba@OADB1 bin]$
数据不一致情况下比对
接下来去目标环境删除id=1的数据,继续比对
目标查询数据库位空了
重复之前的命令进行比对数据
cmp job db1 db2 jobfile="jobif.xml"
输出信息如下:
[dmdba@OADB1 bin]$ ./drcsl dvs.xmlCSL[INFO]: CONSOLE TOOL DRS5: V5.2.5.1-Build(2025.10.11-201427_trunc)_64CSL[WARN]: 未能检测到key文件,将使用默认生成的临时key CSL[WARN]: mem_size参数配置过大,超过系统剩余内存大小 mem_size: 16G, total_free_size: 1GCSL> connectCSL[INFO]: [INPUT CMD: connect]CSL> cmp job db1 db2 jobfile="jobif.xml"CSL[INFO]: [INPUT CMD: cmp job db1 db2 jobfile="jobif.xml"]CMP[INFO]: [INPUT CMD: CMP JOB db1 db2 jobfile="jobif.xml"]MGR[INFO]: CMP JOB NAME IS: CMP_CSTAB, TASK ID IS: 100CMP[CMP000100][INFO]: CMP JOB NAME IS: CMP_CSTAB, TASK ID IS: 100命令执行成功 CSL>
查看比对结果,可以看到提示数据不一致
CSL> show report CMP_CSTABCSL[INFO]: [INPUT CMD: show report CMP_CSTAB]+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 【校验作业报告】 |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 作业名 | 校验任务ID | 已完成校验的表个数 | 待完成校验的表个数 | 表一致数 | 表差异数 | 表失败数 | 表停止数 | 表总个数 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+-----------------------+| CMP_CSTAB | 100 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+-----------------------+| 【校验详细信息】 |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| 校验表组 | 源表行数/差异列名 | 目标表行数/差异列类型 | 相同行数 | 不同行数 | 总耗时(毫秒) | 源表读取耗时(毫秒) | 目标表读取耗时(毫秒) | 校验结果 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+-----------------------+| CS.CS==CS.CS | 1 | 0 | 0 | 1 | 144 | 40 | 144 | 校验成功 - 数据不一致 |+--------------+-------------------+-----------------------+---------------------+----------+--------------+--------------------+----------------------+-----------------------+命令执行成功 CSL>
使用命令查看查看详细报告差异数据
show detail CMP_CSTAB "CS.CS"
参数说明:
| 参数 | 说明 |
|---|---|
| job_name | 校验作业的名称。 |
| “<table_name>” | 校验作业中源数据库的表信息,格式为模式名.表名。具体格式为 “sch.tab”。 |
| mask | 查看详细报告的掩码。默认掩码的格式如下: SRC |
查询结果如下所示:
CSL> show detail CMP_CSTAB "CS.CS"CSL[INFO]: [INPUT CMD: show detail CMP_CSTAB "CS.CS"]+--------------------------------------------------------------------------------------------------+| 【详细报告差异数据】 |+--------------------------------------------------------------------------------------------------+| 序号-0 | A1 | A2 | A3 | ID | ###ROWID | ###FLAG |+--------+-----------------+-----------------+-----------------+----+--------------------+---------+| 1-1 | JQ2EQYNaoYaG522 | tsXVsuAULWoQKZ3 | SkGt2O2qWBDH0Gs | 1 | AAAAAAAAAAAAAAAAAL | 1 |+--------+-----------------+-----------------+-----------------+----+--------------------+---------+| 查询完毕 |+--------------------------------------------------------------------------------------------------+命令执行成功 CSL>
详细报告列数不定,由校验表的列数决定。分别显示源数据库与目标数据库的详细差异数据信息。
| 参数 | 说明 |
|---|---|
| 序号 | 校验配对信息的编号。如10-1与10-2分别为一组来自源表与目标表的详细信息。 |
| ###ROWID | 当前数据的rowid。 |
| ###FLAG | 用于区分当前数据来自源表或目标表。 |
查看校验历史记录
SHOW HISTORY ["<table_name>"] [tab_state="state"]show history "CS.CS" tab_state="DONE"
参数说明
| 参数 | 说明 |
|---|---|
| “<table_name>” | 校验表信息,可以为源数据库表或目标数据库表,格式为模式名.表名。可以为单张或多张表,具体格式为 “sch.tab1[,sch.tab2,…]”。如果不配置该参数,则查看所有校验表。 |
| state | 校验表的状态。可筛选出指定状态的表,如果不配置该参数,则默认显示所有状态。具体如下: DONE:校验完成。 RUN:校验未完成。 |
结果如下所示:
CSL> show history "CS.CS" tab_state="DONE"CSL[INFO]: [INPUT CMD: show history "CS.CS" tab_state="DONE"]+--------------------------------------------------------------------------------------------+| 【表校验历史】 |+--------------------------------------------------------------------------------------------+| 校验表名 | 作业名 | 校验任务ID | 源数据库 | 目标数据库 | 创建时间 | 校验状态 |+----------+-----------+------------+----------+------------+---------------------+----------+| CS.CS | CMP_CSTAB | 100 | DB1 | DB2 | 2025-10-30 16:00:21 | 校验完成 || CS.CS | CMP_CSTAB | 99 | DB1 | DB2 | 2025-10-30 15:52:32 | 校验完成 || CS.CS | CMP_CSTAB | 98 | DB1 | DB2 | 2025-10-30 15:37:20 | 校验完成 || CS.CS | CMP_CS | 97 | DB1 | DB2 | 2025-10-30 15:32:24 | 校验完成 || CS.CS | CMP_CS | 96 | DB1 | DB2 | 2025-10-29 18:25:00 | 校验完成 || CS.CS | CMP_CS | 95 | DB1 | DB2 | 2025-10-29 18:20:00 | 校验完成 || CS.CS | CMP_CS | 94 | DB1 | DB2 | 2025-10-29 18:15:00 | 校验完成 || CS.CS | CMP_CS | 93 | DB1 | DB2 | 2025-10-29 18:10:01 | 校验完成 || CS.CS | CMP_CS | 92 | DB1 | DB2 | 2025-10-29 18:05:00 | 校验完成 || CS.CS | CMP_CS | 91 | DB1 | DB2 | 2025-10-29 18:00:00 | 校验完成 || CS.CS | CMP_CS | 90 | DB1 | DB2 | 2025-10-29 17:55:00 | 校验完成 || CS.CS | CMP_CS | 89 | DB1 | DB2 | 2025-10-29 17:50:00 | 校验完成 |......| CS.CS | CMP_CS | 12 | DB1 | DB2 | 2025-10-28 17:05:01 | 校验完成 || CS.CS | CMP_CS | 11 | DB1 | DB2 | 2025-10-28 16:14:13 | 校验完成 || CS.CS | CMP_CS | 10 | DB1 | DB2 | 2025-10-28 16:06:01 | 校验完成 || CS.CS | CMP_CS | 9 | DB1 | DB2 | 2025-10-28 15:58:57 | 校验完成 || CS.CS | CMP_CS | 8 | DB1 | DB2 | 2025-10-28 15:26:52 | 校验完成 || CS.CS | CMP_CS | 7 | DB1 | DB2 | 2025-10-28 15:13:14 | 校验完成 |+----------+-----------+------------+----------+------------+---------------------+----------+命令执行成功 CSL>
带条件比对XML文件生产
-- 1SELECT '<?xml version="1.0" encoding="GB18030"?>' || CHR(10) || '<job>' || CHR(10) || ' <name>CMP_' || OWNER ||'</name>' || CHR(10) || ' <table_list>' || CHR(10) || LISTAGG( ' <table_info>' || CHR(10) || ' <table_name>' || OWNER || '.' || TABLE_NAME || '</table_name>' || CHR(10) || ' <col_map_flag>0</col_map_flag>' || CHR(10) || ' <tab_cmp_flag>0</tab_cmp_flag>' || CHR(10) || ' <row_partition_src><![CDATA["ID"=1]]></row_partition_src>' || CHR(10) || ' <row_partition_dest><![CDATA["ID"=1]]></row_partition_dest>' || CHR(10) || ' </table_info>', CHR(10) ) WITHIN GROUP (ORDER BY TABLE_NAME) || CHR(10) || ' </table_list>' || CHR(10) || '</job>'AS generated_xmlFROM ALL_TABLES WHERE OWNER = 'SCOTT' AND TABLE_NAME IN (SELECT TABLE_NAME FROM USER_TABLES)GROUP BY OWNER;
115