2.4. blade执行脚本集成多发

2.4.1. blade执行脚本集成多发简介

在blade执行测试用例过程中多个信创库执行sql脚本存在以下问题:

  • 1.操作繁琐重复:执行测试用例前,需针对 Oracle、dm、ocean_base_oracle 等不同数据库手动单独执行 SQL 脚本同步数据,存在大量重复劳动。

  • 2.缺乏数据校验机制:没有统一的数据校验机制,无法快速排查不同数据库间的数据差异,影响测试效率和数据一致性保障。。

2.4.2. 优化后的整体流程图:

../_images/arch_ukagent_blade_sql_scripts_forward_2025-11-03_19-22-35.png

2.4.3. 提前在blade配置http脚本

  1. 项目设置-项目连接设置(开通权限),新增http_config类型

  2. 测试执行->测试环境(引用项目连接设置中的http_config),给测试环境添加执行机(执行机,配置执行机授权码,授权码来自项目设置)

  3. 测试脚本(http)引用项目连接的设置

  4. 测试用例中引用测试脚本(http)

  5. 调试测试用例,按照步骤,发起http(依赖执行机)

  6. http api 参考下方接口内容

部分截图如下:

设置项目连接,新增http_config类型

../_images/blade_config_project_connection_2025-11-11_15-57-46.png

设置测试环境,引用项目连接设置中的http_config, 设置http接口,参考下方接口内容,添加执行机

../_images/blade_config_test_environment_2025-11-11_16-04-36.png

测试http脚本引用项目连接的设置

../_images/blade_config_reference_project_connection_2025-11-11_16-06-56.png

2.4.4. 服务部署

  1. 下载并解压uk_agent发布包

  • 访问Hundsun Artifactory制品库指定地址,下载包含uk_agent压缩包,若存在访问问题,需联系制品库维护人员。具体见下方截图:

    ../_images/%E5%88%B6%E5%93%81%E5%BA%93%E4%B8%8B%E8%BD%BDuk_agent_2025-11-27_15-09-00.png
  • 上传uk_agent到服务器(linux环境),将压缩包解压至uk_agent指定工作目录(示例路径:/data/lightdb/xxxxxx/uk_agent),解压后需包含以下核心目录/文件:

    • config:配置目录,含数据源、多发参数等配置文件和待执行的sql脚本,具体参考下面说明

    • start.sh/stop.sh:服务启停脚本

    • uk_agent-25.3.1.jar:服务执行jar包,这里是25.3.1版本

  1. 配置目标库数据源 - 进入uk_agent配置目录:uk_agent/config,编辑数据源配置文件 application.properties,配置所有目标库数据源,示例如下:

# 第一个数据源配置(mysql的一个具体数据库)
agent.datasource.sources[0].name=mysql # 数据库类型,不区分大小写,
agent.datasource.sources[0].alias=mysql_xxxxxx # 具体数据库名称,对应下方请求中参数targetDbs内容
agent.datasource.sources[0].url=jdbc:mysql://10.20.30.199:2306/xxxxxx  # 数据库url
agent.datasource.sources[0].username=lightdb     # 数据库用户名称
agent.datasource.sources[0].password=${password} # 数据库用户密码
agent.datasource.sources[0].driver-class-name=com.mysql.cj.jdbc.Driver # 数据库所需的驱动类,这里是mysql的驱动
agent.datasource.sources[0].initial-size=5  # 连接池初始大小
agent.datasource.sources[0].max-active=20  # 连接池最大活跃数
agent.datasource.sources[0].min-idle=5  # 连接池最小空闲数
agent.datasource.sources[0].max-wait=60000  # 最大等待时间(毫秒)
agent.datasource.sources[0].validation-query=select 1  # 连接校验SQL

# 第二个数据源配置(lightdb_mysql的一个具体数据库)
agent.datasource.sources[1].name=LIGHTDB_MYSQL
agent.datasource.sources[1].alias=lightdb_mysql_yyyyyy
agent.datasource.sources[1].url=jdbc:postgresql://10.20.30.193:5440/yyyyyy?options=-c%20search_path=public,mysql,lt_catalog
agent.datasource.sources[1].username=lightdb
agent.datasource.sources[1].password=${password}
agent.datasource.sources[1].driver-class-name=org.postgresql.Driver
agent.datasource.sources[1].initial-size=5
agent.datasource.sources[1].max-active=20
agent.datasource.sources[1].min-idle=5
agent.datasource.sources[1].max-wait=10000
agent.datasource.sources[1].validation-query=select 1
  1. 配置多发关联参数

  • 为确保服务能正常关联比对服务,需在 config 目录下配置多发参数文件:

#1.  ``config/unisql.conf`` 文件,关键配置:
unisql.lib.full-path=uk_agent/config/unisql.linux.x86_64.so  # 统一SQL动态库路径,需与uk_agent部署环境匹配
unisql.skip=1  # 全局透传开关,按基础配置设置

#2. ``config/jrescloud.properties``文件,关键配置(确保数据可发送到比对服务进行比对):
multi.run.what=2  # 执行多发,按基础配置设置
multi.sendCompareService=1  # 开启数据发送至比对服务
multi.compareServiceUrl=http://10.20.30.199:2043/em  # 比对服务地址
multi.send.change.data.http.url=http://10.20.30.199:2043/em/compare/upload/change/data  # 数据上传URL,与比对服务地址匹配
  1. 需在 config/scripts 目录下,配置sql脚本(基于步骤2中具体数据库名称alias分层存储)

  • 基于具体数据库名称的sql脚本分层目录如下:

config
└── scripts
    ├── lightdb_mysql_yyyyyy
    │   └── xx
    │       └── yy
    │           └── test.sql
    └── mysql_xxxxxx
        └── xx
            └── yy
                └── test.sql
  • 其中一个具体数据库例如mysql_xxxxxx的sql脚本test.sql内容示例:

-- 创建表
CREATE TABLE user_info (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
);

-- 插入数据
INSERT INTO user_info (name) VALUES ('张三');
INSERT INTO user_info (name) VALUES ('李四');
INSERT INTO user_info (name) VALUES ('王五');

-- 更新数据
UPDATE user_info
SET name = '李小四'
WHERE id = 2;

--查询数据
SELECT id, name
FROM user_info
ORDER BY id ASC
LIMIT 2;

-- 删除数据
DELETE FROM user_info
WHERE id = 3;

-- 删除表
DROP TABLE user_info;
  • oracle系(oracle,dm,gaussdb_oracle,ocean_base_oracle)支持plsql,sql脚本示例如下:

-- 这是文件级单行注释(会被跳过)
prompt 开始执行PL/SQL块(带注释);

-- 场景1:匿名PL/SQL块,含单行注释
begin
    -- 单行注释:声明变量
    declare
v_name varchar2(50); -- 用户名变量(行尾注释)
        v_age number;
begin
        v_name := '张三--测试字符串'; -- 字符串内的--不是注释
        v_age := 30;
        dbms_output.put_line('姓名:' || v_name || ', 年龄:' || v_age);
end; -- 内层end
end;
/

-- 场景2:存储过程(含注释)
create or replace procedure test_procedure(p_id number) is
    v_desc varchar2(100);
begin
select 'ID=' || p_id || '--描述' into v_desc from dual; -- 字符串内的--
dbms_output.put_line('描述:' || v_desc);
exception
    when no_data_found then
        dbms_output.put_line('无数据(注释:异常处理)');
end test_procedure;
/

-- 场景3:普通SQL(带行尾注释)
insert into t_user (name, age) values ('李四', 25); -- 插入测试数据
commit;

2.4.5. 接口说明

2.4.5.1. 简介

http-api,接收测试用例数据同步请求,根据参数动态执行源库及指定目标信创库的脚本,sql执行变化发送到比对服务进行生成比对报告,并返回sql脚本执行结果

2.4.5.2. 接口请求地址

http://ip:port/api/exec/sql

2.4.5.3. 请求方式

POST

2.4.5.4. Content-Type

application/json;charset=UTF-8

2.4.5.5. 接口请求参数

参数名

类型

是否必须

说明

取值范围

示例

scriptName

String

脚本相对目录和名称,如 “xxx/xxx/init.sql”(对应服务端脚本路径的子目录及文件名)

sourceDb

String

源数据库类型,不区分大小写

取值范围[oracle,mysql]

targetDbs

Array<String>

集合中每个元素是数据库的某个具体数据库或者schema的名称,对应数据源配置项agent.datasource.sources[i].alias, 也标识sql脚本目录中不同的数据库

示例[“dm_fund60x”,”ora_test”,”gaussdb_abc”]

2.4.5.6. 接口响应参数

参数名

类型

是否必须

说明

取值范围

示例

status

String

整体执行状态

success:所有库执行成功,partial_success:部分库执行成功,failed:所有库执行失败

traceId

String

标识一次操作,sql脚本在源库和目标库执行

details

Array<DetailInfo>

各数据库执行详情数组,每个元素对应一个库的执行结果

DetailInfo对象结构如下:

参数名

类型

是否必须

说明

示例

name

String

数据库名称,对应的是入参中targetDbs这个数组中的具体数据库或者schema的名字

status

String

该库执行状态:success(成功)、failed(失败)

error

String

可选字段,仅当 status=failed 时返回,描述错误原因(如 “表不存在”“权限不足” 等)

sqlCount

String

执行的sql数量

executeDuration

String

执行sql总耗时,单位毫秒(ms)

failedSqlDetails

DailedSqlDetails

可选对象,执行sql失败,打印行号,sql,失败原因

DailedSqlDetails对象结构如下:

参数名

类型

是否必须

说明

示例

lineNumber

String

sql行号

sql

String

失败SQL内容

error

String

失败原因

executeTime

String

执行耗时(毫秒)

2.4.5.7. 请求和响应示例

请求示例1(成功)

{
  "scriptName": "xx/yy/test.sql",
  "sourceDb": "oracle",
  "targetDbs": [
    "lightdb_mysql_xxxxxx",
    "mysql_xxxxxx"
  ]
}

响应示例1(成功)

{
  "traceId": "uk_agent_b7569552c45945d2b5f2ec2d9607c8b1",
  "status": "success",
  "details": [
        {
          "name": "lightdb_mysql_liangdong30629",
          "status": "success",
          "error": null,
          "sqlCount": 8,
          "executeDuration": 5274,
          "failedSqlDetails": null
        },
        {
          "name": "mysql_liangdong30629",
          "status": "success",
          "error": null,
          "sqlCount": 8,
          "executeDuration": 5289,
          "failedSqlDetails": null
        }
  ]
}

请求示例2(失败)

{
  "scriptName": "xx/yy/test2.sql",
  "sourceDb": "mysql",
  "targetDbs": [
        "lightdb_mysql_liangdong30629",
        "mysql_liangdong30629"
  ]
}

响应示例2(失败原因是脚本不存在)

{
  "traceId": "uk_agent_ca7515c1a676443f938f43d436bfa4bb",
  "status": "failed",
  "details": [
        {
          "name": "lightdb_mysql_liangdong30629",
          "status": "failed",
          "error": "脚本文件不存在:C:\\Users\\T14s\\idea_workspace\\unisql_trunk_develop\\config\\scripts\\lightdb_mysql_liangdong30629\\xx/yy/test2.sql",
          "sqlCount": 0,
          "executeDuration": 0,
          "failedSqlDetails": null
        },
        {
          "name": "mysql_liangdong30629",
          "status": "failed",
          "error": "脚本文件不存在:C:\\Users\\T14s\\idea_workspace\\unisql_trunk_develop\\config\\scripts\\mysql_liangdong30629\\xx/yy/test2.sql",
          "sqlCount": 0,
          "executeDuration": 0,
          "failedSqlDetails": null
        }
  ]
}

请求示例3(失败)

{
  "scriptName": "xx/yy/test.sql",
  "sourceDb": "mysql",
  "targetDbs": [
        "lightdb_mysql_liangdong30629",
        "mysql_liangdong30629"
  ]
}

响应示例3(失败,部分SQL执行失败,可查看失败的sql和失败原因)

{
  "traceId": "uk_agent_a24d43bf64c443c2bdd10660a81edafb",
  "status": "partial_success",
  "details": [
        {
          "name": "lightdb_mysql_liangdong30629",
          "status": "failed",
          "error": "部分SQL执行失败:总SQL数=8,成功数=7,失败数=1",
          "sqlCount": 8,
          "executeDuration": 5620,
          "failedSqlDetails": [
                {
                  "lineNumber": 22,
                  "sql": "SELECT id, name\nFROM user_info2\nORDER BY id ASC\nLIMIT 2;",
                  "error": "多发源端[MYSQL]到目标[LIGHTDB_MYSQL]业务SQL串行执行失败,traceId [uk_agent_a24d43bf64c443c2bdd10660a81edafb] 多发消息 [{\"appName\":\"autoTest\",\"appType\":\"OTHER\",\"bizBindVarReplacedSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"bizSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"bizSqlAffectedRows\":0,\"bizSqlExecutionTime\":\"2025-11-10 15:15:27\",\"bizSqlOperationType\":\"SELECT\",\"bizSqlSequence\":6,\"bizSqlTableName\":\"user_info2\",\"compareKind\":\"RAW_BIZ_QUERY\",\"compareReportGenerated\":false,\"errorReason\":\"多发源端[MYSQL]到目标[LIGHTDB_MYSQL]业务SQL执行失败,traceId [uk_agent_a24d43bf64c443c2bdd10660a81edafb],业务SQL[SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;],异常信息[com.tencentcloud.tdsql.pg.util.PSQLException: ERROR: relation \\\"user_info2\\\" does not exist\\n  位置:22\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2678)\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2368)\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeInternal(PgStatement.java:513)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:431)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:348)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeCachedSql(PgStatement.java:334)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:310)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:305)\\r\\n\\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:818)\\r\\n\\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\\r\\n\\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:564)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:514)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:381)\\r\\n\\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\\r\\n\\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\\r\\n\\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\\r\\n\\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\\r\\n\\tat java.base/java.lang.Thread.run(Thread.java:834)\\r\\n]\",\"functionId\":\"\",\"multiAppHostIp\":\"10.188.129.216\",\"multiQueryResultSet\":{},\"multiQueryRowCount\":0,\"multiQuerySql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"multiTargetDialects\":[\"LIGHTDB_MYSQL\",\"MYSQL\"],\"rawBizBindVarReplacedSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"realMultiplex\":false,\"schemaName\":\"liangdong30629\",\"sourceDialect\":\"MYSQL\",\"sourceMessage\":false,\"state\":\"BIZ_SQL_EXECUTE_FAIL\",\"syncConnectionInfo\":{\"password\":\"lightdb@123\",\"url\":\"jdbc:postgresql://10.20.30.193:5440/liangdong30629?options=-c%20search_path=public,mysql,lt_catalog&sourceDialect=mysql&targetDialect=lightdb_mysql&multiplexTargetDialects=lightdb_mysql,mysql\",\"username\":\"lightdb\"},\"targetDialect\":\"LIGHTDB_MYSQL\",\"tenantName\":\"autoTest\",\"traceId\":\"uk_agent_a24d43bf64c443c2bdd10660a81edafb\",\"transformedBizSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"url\":\"xx/yy/test.sql\",\"username\":\"autoTest\"}] 错误信息 [com.tencentcloud.tdsql.pg.util.PSQLException: ERROR: relation \"user_info2\" does not exist\n  位置:22\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2678)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2368)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeInternal(PgStatement.java:513)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:431)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:348)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeCachedSql(PgStatement.java:334)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:310)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:305)\r\n\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:818)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:564)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:514)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:381)\r\n\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\r\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\n]",
                  "executeTime": 620
                }
          ]
        },
        {
          "name": "mysql_liangdong30629",
          "status": "success",
          "error": null,
          "sqlCount": 8,
          "executeDuration": 5612,
          "failedSqlDetails": null
        }
  ]
}

请求示例4(失败)

{
  "scriptName": "xx/yy/test.sql",
  "sourceDb": "mysql",
  "targetDbs": [
        "lightdb_mysql_liangdong30629",
        "mysql_liangdong30629"
  ]
}

响应示例4(失败,两个数据库均有sql执行失败,可查看失败的sql和失败原因)

{
  "traceId": "uk_agent_3b2caececdf343f99c97f593861e8067",
  "status": "failed",
  "details": [
        {
          "name": "lightdb_mysql_liangdong30629",
          "status": "failed",
          "error": "部分SQL执行失败:总SQL数=8,成功数=7,失败数=1",
          "sqlCount": 8,
          "executeDuration": 5576,
          "failedSqlDetails": [
                {
                  "lineNumber": 22,
                  "sql": "SELECT id, name\nFROM user_info2\nORDER BY id ASC\nLIMIT 2;",
                  "error": "多发源端[MYSQL]到目标[LIGHTDB_MYSQL]业务SQL串行执行失败,traceId [uk_agent_3b2caececdf343f99c97f593861e8067] 多发消息 [{\"appName\":\"autoTest\",\"appType\":\"OTHER\",\"bizBindVarReplacedSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"bizSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"bizSqlAffectedRows\":0,\"bizSqlExecutionTime\":\"2025-11-10 16:06:45\",\"bizSqlOperationType\":\"SELECT\",\"bizSqlSequence\":6,\"bizSqlTableName\":\"user_info2\",\"compareKind\":\"RAW_BIZ_QUERY\",\"compareReportGenerated\":false,\"errorReason\":\"多发源端[MYSQL]到目标[LIGHTDB_MYSQL]业务SQL执行失败,traceId [uk_agent_3b2caececdf343f99c97f593861e8067],业务SQL[SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;],异常信息[com.tencentcloud.tdsql.pg.util.PSQLException: ERROR: relation \\\"user_info2\\\" does not exist\\n  位置:22\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2678)\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2368)\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeInternal(PgStatement.java:513)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:431)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:348)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeCachedSql(PgStatement.java:334)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:310)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:305)\\r\\n\\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:818)\\r\\n\\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\\r\\n\\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:564)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:514)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:381)\\r\\n\\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\\r\\n\\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\\r\\n\\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\\r\\n\\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\\r\\n\\tat java.base/java.lang.Thread.run(Thread.java:834)\\r\\n]\",\"functionId\":\"\",\"multiAppHostIp\":\"10.188.129.216\",\"multiQueryResultSet\":{},\"multiQueryRowCount\":0,\"multiQuerySql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"multiTargetDialects\":[\"LIGHTDB_MYSQL\",\"MYSQL\"],\"rawBizBindVarReplacedSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"realMultiplex\":false,\"schemaName\":\"liangdong30629\",\"sourceDialect\":\"MYSQL\",\"sourceMessage\":false,\"state\":\"BIZ_SQL_EXECUTE_FAIL\",\"syncConnectionInfo\":{\"password\":\"lightdb@123\",\"url\":\"jdbc:postgresql://10.20.30.193:5440/liangdong30629?options=-c%20search_path=public,mysql,lt_catalog&sourceDialect=mysql&targetDialect=lightdb_mysql&multiplexTargetDialects=lightdb_mysql,mysql\",\"username\":\"lightdb\"},\"targetDialect\":\"LIGHTDB_MYSQL\",\"tenantName\":\"autoTest\",\"traceId\":\"uk_agent_3b2caececdf343f99c97f593861e8067\",\"transformedBizSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"url\":\"xx/yy/test.sql\",\"username\":\"autoTest\"}] 错误信息 [com.tencentcloud.tdsql.pg.util.PSQLException: ERROR: relation \"user_info2\" does not exist\n  位置:22\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2678)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2368)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeInternal(PgStatement.java:513)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:431)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:348)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeCachedSql(PgStatement.java:334)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:310)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:305)\r\n\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:818)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:564)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:514)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:381)\r\n\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\r\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\n]",
                  "executeTime": 561
                }
          ]
        },
        {
          "name": "mysql_liangdong30629",
          "status": "failed",
          "error": "部分SQL执行失败:总SQL数=8,成功数=7,失败数=1",
          "sqlCount": 8,
          "executeDuration": 5565,
          "failedSqlDetails": [
                {
                  "lineNumber": 31,
                  "sql": "DELETE FROM user_info3\nWHERE id = 3;",
                  "error": "多发源端[MYSQL]到目标[MYSQL]业务SQL串行执行失败,traceId [uk_agent_3b2caececdf343f99c97f593861e8067] 多发消息 [{\"appName\":\"autoTest\",\"appType\":\"OTHER\",\"bizBindVarReplacedSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"bizSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"bizSqlAffectedRows\":0,\"bizSqlExecutionTime\":\"2025-11-10 16:06:46\",\"bizSqlOperationType\":\"DELETE\",\"bizSqlSequence\":7,\"bizSqlTableName\":\"user_info3\",\"compareKind\":\"AFTER_QUERY\",\"compareReportGenerated\":false,\"functionId\":\"\",\"messageType\":\"http\",\"multiAppHostIp\":\"10.188.129.216\",\"multiQueryResultSet\":{},\"multiQuerySql\":\"SELECT * FROM user_info3 WHERE id=3 ORDER BY id\",\"multiTargetDialects\":[\"LIGHTDB_MYSQL\",\"MYSQL\"],\"rawBizBindVarReplacedSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"realMultiplex\":false,\"schemaName\":\"liangdong30629\",\"sourceDialect\":\"MYSQL\",\"sourceMessage\":true,\"syncConnectionInfo\":{\"password\":\"lightdb123456\",\"url\":\"jdbc:mysql://10.20.30.199:2306/liangdong30629?sourceDialect=mysql&targetDialect=mysql&multiplexTargetDialects=lightdb_mysql,mysql\",\"username\":\"lightdb\"},\"targetDialect\":\"MYSQL\",\"tenantName\":\"autoTest\",\"traceId\":\"uk_agent_3b2caececdf343f99c97f593861e8067\",\"transformedBizSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"url\":\"xx/yy/test.sql\",\"username\":\"autoTest\"}] 错误信息 [java.sql.SQLSyntaxErrorException: Table 'liangdong30629.user_info3' doesn't exist\r\n\tat com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121)\r\n\tat com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)\r\n\tat com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:770)\r\n\tat com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:653)\r\n\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:855)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:564)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:514)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:381)\r\n\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\r\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\n]",
                  "executeTime": 570
                }
          ]
        }
  ]
}

响应示例5(失败,两个数据库均有sql执行失败,其中一个具体数据库有多个sql执行失败,可查看失败的sql和失败原因)

{
  "traceId": "uk_agent_729ea0c3a9334e1b9da0edb0fabac355",
  "status": "failed",
  "details": [
        {
          "name": "lightdb_mysql_liangdong30629",
          "status": "failed",
          "error": "部分SQL执行失败:总SQL数=8,成功数=6,失败数=2",
          "sqlCount": 8,
          "executeDuration": 5693,
          "failedSqlDetails": [
                {
                  "lineNumber": 22,
                  "sql": "SELECT id, name\nFROM user_info2\nORDER BY id ASC\nLIMIT 2;",
                  "error": "多发源端[MYSQL]到目标[LIGHTDB_MYSQL]业务SQL串行执行失败,traceId [uk_agent_729ea0c3a9334e1b9da0edb0fabac355] 多发消息 [{\"appName\":\"autoTest\",\"appType\":\"OTHER\",\"bizBindVarReplacedSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"bizSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"bizSqlAffectedRows\":0,\"bizSqlExecutionTime\":\"2025-11-10 16:36:33\",\"bizSqlOperationType\":\"SELECT\",\"bizSqlSequence\":6,\"bizSqlTableName\":\"user_info2\",\"compareKind\":\"RAW_BIZ_QUERY\",\"compareReportGenerated\":false,\"errorReason\":\"多发源端[MYSQL]到目标[LIGHTDB_MYSQL]业务SQL执行失败,traceId [uk_agent_729ea0c3a9334e1b9da0edb0fabac355],业务SQL[SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;],异常信息[com.tencentcloud.tdsql.pg.util.PSQLException: ERROR: relation \\\"user_info2\\\" does not exist\\n  位置:22\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2678)\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2368)\\r\\n\\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeInternal(PgStatement.java:513)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:431)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:348)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeCachedSql(PgStatement.java:334)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:310)\\r\\n\\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:305)\\r\\n\\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:818)\\r\\n\\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\\r\\n\\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:682)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:613)\\r\\n\\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:474)\\r\\n\\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\\r\\n\\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\\r\\n\\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\\r\\n\\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\\r\\n\\tat java.base/java.lang.Thread.run(Thread.java:834)\\r\\n]\",\"functionId\":\"\",\"multiAppHostIp\":\"10.188.129.216\",\"multiQueryResultSet\":{},\"multiQueryRowCount\":0,\"multiQuerySql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"multiTargetDialects\":[\"LIGHTDB_MYSQL\",\"MYSQL\"],\"rawBizBindVarReplacedSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"realMultiplex\":false,\"schemaName\":\"liangdong30629\",\"sourceDialect\":\"MYSQL\",\"sourceMessage\":false,\"state\":\"BIZ_SQL_EXECUTE_FAIL\",\"syncConnectionInfo\":{\"password\":\"lightdb@123\",\"url\":\"jdbc:postgresql://10.20.30.193:5440/liangdong30629?options=-c%20search_path=public,mysql,lt_catalog&sourceDialect=mysql&targetDialect=lightdb_mysql&multiplexTargetDialects=lightdb_mysql,mysql\",\"username\":\"lightdb\"},\"targetDialect\":\"LIGHTDB_MYSQL\",\"tenantName\":\"autoTest\",\"traceId\":\"uk_agent_729ea0c3a9334e1b9da0edb0fabac355\",\"transformedBizSql\":\"SELECT id, name\\nFROM user_info2\\nORDER BY id ASC\\nLIMIT 2;\",\"url\":\"xx/yy/test.sql\",\"username\":\"autoTest\"}] 错误信息 [com.tencentcloud.tdsql.pg.util.PSQLException: ERROR: relation \"user_info2\" does not exist\n  位置:22\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2678)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2368)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeInternal(PgStatement.java:513)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:431)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:348)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeCachedSql(PgStatement.java:334)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:310)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:305)\r\n\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:818)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:682)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:613)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:474)\r\n\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\r\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\n]",
                  "executeTime": 624
                },
                {
                  "lineNumber": 31,
                  "sql": "DELETE FROM user_info1\nWHERE id = 3;",
                  "error": "多发源端[MYSQL]到目标[LIGHTDB_MYSQL]业务SQL串行执行失败,traceId [uk_agent_729ea0c3a9334e1b9da0edb0fabac355] 多发消息 [{\"appName\":\"autoTest\",\"appType\":\"OTHER\",\"bizBindVarReplacedSql\":\"DELETE FROM user_info1\\nWHERE id = 3;\",\"bizSql\":\"DELETE FROM user_info1\\nWHERE id = 3;\",\"bizSqlAffectedRows\":0,\"bizSqlExecutionTime\":\"2025-11-10 16:36:34\",\"bizSqlOperationType\":\"DELETE\",\"bizSqlSequence\":7,\"bizSqlTableName\":\"user_info1\",\"compareKind\":\"AFTER_QUERY\",\"compareReportGenerated\":false,\"functionId\":\"\",\"messageType\":\"http\",\"multiAppHostIp\":\"10.188.129.216\",\"multiQueryResultSet\":{},\"multiQuerySql\":\"SELECT * FROM user_info1 WHERE id=3 ORDER BY id\",\"multiTargetDialects\":[\"LIGHTDB_MYSQL\",\"MYSQL\"],\"rawBizBindVarReplacedSql\":\"DELETE FROM user_info1\\nWHERE id = 3;\",\"realMultiplex\":false,\"schemaName\":\"liangdong30629\",\"sourceDialect\":\"MYSQL\",\"sourceMessage\":false,\"syncConnectionInfo\":{\"password\":\"lightdb@123\",\"url\":\"jdbc:postgresql://10.20.30.193:5440/liangdong30629?options=-c%20search_path=public,mysql,lt_catalog&sourceDialect=mysql&targetDialect=lightdb_mysql&multiplexTargetDialects=lightdb_mysql,mysql\",\"username\":\"lightdb\"},\"targetDialect\":\"LIGHTDB_MYSQL\",\"tenantName\":\"autoTest\",\"traceId\":\"uk_agent_729ea0c3a9334e1b9da0edb0fabac355\",\"transformedBizSql\":\"DELETE FROM user_info1\\nWHERE id = 3;\",\"url\":\"xx/yy/test.sql\",\"username\":\"autoTest\"}] 错误信息 [com.tencentcloud.tdsql.pg.util.PSQLException: ERROR: relation \"user_info1\" does not exist\n  位置:13\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2678)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2368)\r\n\tat com.tencentcloud.tdsql.pg.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeInternal(PgStatement.java:513)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:431)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:348)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeCachedSql(PgStatement.java:334)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.executeWithFlags(PgStatement.java:310)\r\n\tat com.tencentcloud.tdsql.pg.jdbc.PgStatement.execute(PgStatement.java:305)\r\n\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:855)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:682)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:613)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:474)\r\n\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\r\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\n]",
                  "executeTime": 625
                }
          ]
        },
        {
          "name": "mysql_liangdong30629",
          "status": "failed",
          "error": "部分SQL执行失败:总SQL数=8,成功数=7,失败数=1",
          "sqlCount": 8,
          "executeDuration": 5917,
          "failedSqlDetails": [
                {
                  "lineNumber": 31,
                  "sql": "DELETE FROM user_info3\nWHERE id = 3;",
                  "error": "多发源端[MYSQL]到目标[MYSQL]业务SQL串行执行失败,traceId [uk_agent_729ea0c3a9334e1b9da0edb0fabac355] 多发消息 [{\"appName\":\"autoTest\",\"appType\":\"OTHER\",\"bizBindVarReplacedSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"bizSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"bizSqlAffectedRows\":0,\"bizSqlExecutionTime\":\"2025-11-10 16:36:34\",\"bizSqlOperationType\":\"DELETE\",\"bizSqlSequence\":7,\"bizSqlTableName\":\"user_info3\",\"compareKind\":\"AFTER_QUERY\",\"compareReportGenerated\":false,\"functionId\":\"\",\"messageType\":\"http\",\"multiAppHostIp\":\"10.188.129.216\",\"multiQueryResultSet\":{},\"multiQuerySql\":\"SELECT * FROM user_info3 WHERE id=3 ORDER BY id\",\"multiTargetDialects\":[\"LIGHTDB_MYSQL\",\"MYSQL\"],\"rawBizBindVarReplacedSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"realMultiplex\":false,\"schemaName\":\"liangdong30629\",\"sourceDialect\":\"MYSQL\",\"sourceMessage\":true,\"syncConnectionInfo\":{\"password\":\"lightdb123456\",\"url\":\"jdbc:mysql://10.20.30.199:2306/liangdong30629?sourceDialect=mysql&targetDialect=mysql&multiplexTargetDialects=lightdb_mysql,mysql\",\"username\":\"lightdb\"},\"targetDialect\":\"MYSQL\",\"tenantName\":\"autoTest\",\"traceId\":\"uk_agent_729ea0c3a9334e1b9da0edb0fabac355\",\"transformedBizSql\":\"DELETE FROM user_info3\\nWHERE id = 3;\",\"url\":\"xx/yy/test.sql\",\"username\":\"autoTest\"}] 错误信息 [java.sql.SQLSyntaxErrorException: Table 'liangdong30629.user_info3' doesn't exist\r\n\tat com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121)\r\n\tat com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)\r\n\tat com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:770)\r\n\tat com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:653)\r\n\tat com.hundsun.lightdb.unisql.model.MultiplexContext.execute(MultiplexContext.java:855)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:159)\r\n\tat com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlStatement.execute(UnisqlStatement.java:100)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.executeSingleSql(DataSyncServiceImpl.java:682)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.processSingleTargetDbInternal(DataSyncServiceImpl.java:613)\r\n\tat com.hundsun.lightdb.ukagent.service.impl.DataSyncServiceImpl.lambda$createSingleDbTask$6(DataSyncServiceImpl.java:474)\r\n\tat java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)\r\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\n]",
                  "executeTime": 861
                }
          ]
        }
  ]
}

2.4.6. 支持在比对服务页面查看具体报错信息

../_images/uk_agent_failed_report_in_comparison_page_2025-11-10_16-44-21.png

2.4.7. 常见问题

2.4.7.1. 解析sql脚本支持哪些sql

  1. 普通SQL(分号/斜杠结尾,非PL/SQL)

  • 支持类型:DML(增删改查)、DDL(建表/索引/视图等)、DCL(授权/回收),需满足“分号结尾”或“独立斜杠结尾”。

  • 注释兼容:自动过滤单行注释、多行注释、不误判字符串内的单行注释,见下方sql示例:

-- 分号结尾的普通SQL(支持)
SELECT * FROM user_info WHERE name = '张三--测试'; -- 行尾注释
INSERT INTO dept (deptno, dname) VALUES (10, '研发部');

-- 独立斜杠结尾的普通SQL(支持,代码会移除结尾/)
CREATE TABLE test (id INT);
/
  1. Oracle系PL/SQL块(自动移除结尾独立/)

  • 支持的PL/SQL类型(通过正则识别): 匿名块(begin/declare … end;) ,存储过程/函数(create or replace procedure/function …) ,包/包体(create or replace package …)

  • 关键特性:仅识别独立一行的/为结束符,自动移除该/,保留PL/SQL主体(适配JDBC执行)。

  • 注释/嵌套兼容:支持PL/SQL内的单行/多行注释、嵌套begin-end块,注释中含end关键字不影响结束判断。 注意: plsql内嵌套多行注释,jdbc执行报错

-- 处理前(带独立/结尾)
begin
        declare
                v_name varchar2(50) := '张三';
        begin
                /* 注释含end:end不算结束 */
                dbms_output.put_line(v_name);
        end; -- 内层end
end;
/

-- 处理后(自动移除/,保留主体)
begin
        declare
                v_name varchar2(50) := '张三';
        begin
                /* 注释含end:end不算结束 */
                dbms_output.put_line(v_name);
        end; -- 内层end
end;
  1. Prompt提示语句(仅Oracle系支持)

  • 识别以prompt开头的语句(忽略大小写),注意: JDBC执行报错。

PROMPT 开始执行初始化SQL...
prompt 执行建表语句

2.4.7.2. 解析sql脚本不能处理哪些sql

  1. 非Oracle系数据库的PL/SQL/特有语法

  • 限制原因:限定仅支持Oracle系数据库,其他数据库的PL/SQL或特有语法会被跳过或报错。

  • MySQL的存储过程(用DELIMITER $$切换结束符)

  • PostgreSQL的DO $$ … $$匿名块

  1. 未以“独立/”结尾的PL/SQL块

  • 限制原因:判定PL/SQL结束的唯一条件是“独立一行的/”,若PL/SQL块仅以end;结尾(无/),会被当作“未结束SQL”存入,执行时可能因语法不完整报错。

-- 无/结尾的PL/SQL块(代码会视为未结束,存入后执行可能报错)
begin
        dbms_output.put_line('无/结尾');
end;
  1. 非独立/结尾的PL/SQL块

  • 限制原因:仅匹配严格独立一行,前后无空格/字符,若/前后有空格或其他字符,不会被识别为PL/SQL结束符。

begin
        dbms_output.put_line('非独立/');
end;
/  -- 末尾有空格
  1. PL/SQL块内包含独立/(非结束符)

  • 限制原因:若PL/SQL主体内有独立一行的/(如动态SQL、注释外的/),会被误判为PL/SQL结束符,导致后续内容被截断。

begin
        -- 主体内的独立/(会被误判为结束符,后续内容被丢弃)
        execute immediate 'select 1/2 from dual';
        /
        dbms_output.put_line('被截断的内容'); -- 不会被执行
end;
/
  1. 带绑定变量的SQL/PL/SQL

  • 限制原因:未处理Oracle绑定变量(如`:v1`),JDBC执行时会因“未设置绑定变量值”报错。

SELECT * FROM user_info WHERE id = :v_id; -- 绑定变量:v_id未处理
  1. 其他数据库特有语法/结束符

  • 不支持MySQL的DELIMITER、PostgreSQL的$$等特有结束符。

  • 不支持非Oracle系的存储过程/函数语法。

2.4.7.3. 服务端执行过程中的限制

以下限制均基于实际执行流程(从请求校验→脚本解析→任务执行→结果处理):

  1. 源库类型固定限制:仅支持 MySQL 和 Oracle 两种源库类型(不区分大小写),其他数据库类型(如 PostgreSQL、DB2、SQL Server 等)直接判定为不支持,同步流程终止。

  2. 目标库配置强依赖限制:目标库必须在数据源配置文件application.properties定义别名(alias),未配置别名或别名重复(重复时保留原有配置)的目标库无法执行同步,会直接记录配置缺失错误。

  3. sql脚本路径不可自定义限制:SQL 脚本存放路径固定为「用户工作目录/config/scripts/目标库别名/脚本名」。

  4. sql脚本有效性强制校验限制:目标库对应的脚本文件必须存在且为有效文件(非目录),若脚本文件不存在、为空,或解析后无有效 SQL(全是注释/空行),会直接终止该目标库同步,抛出“脚本不存在”或“无有效 SQL”异常。

  5. 任务超时时间固定限制:并行执行,是所有任务的 “整体等待时间”(不管并行 / 串行,最多等30 分钟)。

  6. 并发同步无冲突控制限制:多目标库同步任务并行执行,无并发控制机制(如分布式锁、乐观锁、目标库级别的串行控制),同一目标库若被多次触发同步,可能导致数据一致性冲突。

  7. SQL 执行方式安全与性能限制:每条 SQL 都会单独创建 JDBC 连接和 Statement。

  8. 事务支持缺失限制:SQL 执行默认自动提交,无事务管理机制(无手动提交、回滚逻辑),一条 SQL 执行失败不会影响其他 SQL 执行。

  9. 无自动重试机制限制:SQL 执行失败、任务超时、线程中断等场景下,无自动重试逻辑,失败后仅记录错误详情,需手动重新触发同步流程,不支持失败重试策略(如重试次数、重试间隔配置)。

  10. 动态数据源不支持限制:仅支持数据源配置文件application.properties中预定义的目标库,无法动态添加新的目标库(如通过接口传入临时数据源配置)进行同步。

  11. 批量 SQL 执行不支持限制:不支持 JDBC 批量执行,每条 SQL 单独执行。

  12. sql语句中包含–注释,可能会引起jdbc执行报错:示例如下:

    SELECT * FROM --users
    WHERE id = 1;
    --注释了原本的表名users,导致FROM子句后无表名,SQL 语法不完整。
    
    
    SELECT * FROM users WHERE id = 1--
    AND name = 'test';
    --注释了第一行末尾,第二行的AND name = 'test'成为独立的无效语句(AND不能单独存在)。