本章节介绍LightDB多发比对的整体架构及快速入门。

9.2.1. 多发+比对代理模式的架构(1对1伪多发)

9.2.1.1. 架构图

../_images/arch_mock_multiplex_2024-07-19_11-42-08.jpg

9.2.1.2. 场景说明

该场景主要用于多个微服务同时集成多发代理程序(sql-convert-runtime)后,每个微服务执行sql(DQL/DML)操作时,代理程序会拦截SQL执行, 如果是DML,则代理程序会获取DML执行前预计影响的数据行,和DML执行后实际影响的数据行,并发送到消息队列中;如果是DQL,则代理程序会获取其查询结果集,并发送到消息队列中。 之后,比对服务会以指定的mysql/oracle为基准库,与其他微服务传送到消息队列中的不同信创库的查询结果集进行一一比对,并记录比对差异,以比对报告的形式展示给用户查看。

注意

伪多发场景下,每个微服务配置的JDBC连接中需要包含multiplexTargetDialects属性,值为所有微服务的目标数据库方言类型,多个之间用英文逗号连接。

如伪多发场景为oracle、dm、gaussdb_oracle环境,以dm为例,配置如下:

hs.datasource.default.driver-class-name=com.hundsun.lightdb.unisql.proxy.Driver
hs.datasource.default.url=jdbc:unisql:dm://ip:port/dbname?sourceDialect=oracle&targetDialect=dm&multiplexTargetDialects=oracle,dm,gaussdb_oracle
hs.datasource.default.username=username
hs.datasource.default.password=password

9.2.2. 多发+比对代理模式的架构(1对多真多发)

9.2.2.1. 架构图

../_images/arch_real_multiplex_2024-07-19_11-42-08.jpg

9.2.2.2. 场景说明

该场景主要用于单个微服务集成多发代理程序(sql-convert-runtime)后,该微服务执行sql(DQL/DML)操作时,代理程序会拦截SQL执行,并将该SQL多发到多个信创数据库执行。 如果是DML,则代理程序会获取多个信创库DML执行前预计影响的数据行,和DML执行后实际影响的数据行,并发送到消息队列中;如果是DQL,则代理程序会获取多个信创库的查询结果集,并发送到消息队列中。 之后,比对服务会以指定的mysql/oracle为基准库,与不同信创库的查询结果集进行一一比对,并记录比对差异,以比对报告的形式展示给用户查看。

9.2.3. 微服务集成多发代理(SEE2.0多发比对配置样例)

下面以SEE2.0 MariaDB–>GaussDB500的多发比对为例进行展示。

前提:

  • 已经安装好SEE2.0、多发比对服务(如未安装,请参照 消息队列安装(可选)比对服务安装 进行安装)

  • 从官网下载最新的统一sql包,例如: 统一sql-下载(动态库),下载LightDB1.0-unisql-VXXXXXX-XX-000.zip包。 从zip里中获取 unisql.linux.aarch64.sosql-convert-runtime-fat-XX.X.jar ,用于后面的配置。

  • 从官网下载最新的统一sql比对服务包,例如: 多发比对-比对服务下载,下载LightDB1.0-comparison-VXXXXXX-XX-000.zip包。 从LightDB1.0-comparison-VXXXXXX-XX-000.zip中获取 unisql-compare-client-fat-XX.X.jar 包,用于后面的配置。

9.2.3.1. 第一步:明确业务应用相关目录

和多发比对相关的工作目录有下面几类:

1. java进程的工作目录:/home/see/tomcat/bin

该目录用于存放unisql.conf、jrescloud.properties配置文件,用于配置统一sql参数、多发参数。

如何确定微服务的工作目录(微服务是个java进程)?

  • 确定微服务进程ID:通过 ps 命令或 jps -l 命令确定微服务的进程ID,以 see 为例

    ../_images/%E9%80%9A%E8%BF%87%E5%BE%AE%E6%9C%8D%E5%8A%A1%E5%90%8D%E7%A7%B0%E7%A1%AE%E5%AE%9A%E8%BF%9B%E7%A8%8BID.png
  • 确定进程的工作目录:通过系统默认安装的或服务自带的 jinfo 命令确定 java 工作目录,以 see 为例

    ../_images/%E9%80%9A%E8%BF%87jinfo%E5%91%BD%E4%BB%A4%E7%A1%AE%E5%AE%9A%E5%BE%AE%E6%9C%8D%E5%8A%A1%E7%9A%84%E7%94%A8%E6%88%B7%E7%9B%AE%E5%BD%95.png

2. 多发比对java依赖包的配置目录

以下目录用于存放多发比对的jar包。

  • acm服务lib目录:/home/see/tomcat/webapps/acm/WEB-INF/lib/

  • cas服务lib目录:/home/see/tomcat/webapps/cas/WEB-INF/lib/

  • server服务lib目录:/home/see/server/lib

3. 多发数据源源库配置目录

以下目前用于配置多发比对的数据源信息

  • acm源库配置路径:/home/see/tomcat/webapps/acm/WEB-INF/conf/jdbc.properties

  • cas源库配置路径:home/see/tomcat/webapps/cas/WEB-INF/classes/application.properties

4. 日志文件目录

以下是see及统一sql的日志信息,用于多发比对的对接调试。

  • app日志:/home/see/tomcat/logs/app.log

  • cas日志:/home/see/tomcat/logs/cas.log

  • 多发日志:/home/see/tomcat/logs/unisql.log

  • 统一SQL日志:/home/see/tomcat/bin/unisql.log

5、SEE应用启动目录、命令

  • 启动目录:/home/see/tomcat/bin ./startup.sh

    上面5步信息确定之后,就可以开始正式多发比对的应用对接了。

9.2.3.2. 第二步:配置统一sql、多发文件信息

在/home/see/tomcat/bin创建config文件夹,分别将unisql.conf、jrescloud.properties拷入到文件夹下,并根据实际情况进行配置,下面是see的一个参数配置例子:

1. unisql.conf参数配置

../_images/%E7%BB%9F%E4%B8%80sql%E5%A4%9A%E5%8F%91%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9B%AE%E5%BD%95.png
# 全局透传开关 0关 1开
unisql.skip = 0
# 全局异常透传开关 0关 1开
unisql.error.skip = 0
# 缓存开关 0关 1开
unisql.cache = 0
# 缓存改写sql最大条数,默认 10000条。统一 SQL 会将 SQL 转换结果进行缓存,可通过本参数配置缓存最大条数
unisql.cache.maximumSize = 10000
# 缓存过期时长,默认 900秒
unisql.cache.expireSeconds = 900
# DEBUG 日志开关 0关 1开
unisql.debug = 0
# 统一 SQL 对比 http请求的url
unisql.compare.server.url =
# 在配置项`unisql.compare.server.url`(统一 SQL 对比 http请求的url)有值的情况下,配置项`unisql.skipUnisqlRuntimeConvert` (表示是否跳过统一sql运行时sql转换,默认0表示不跳过),0关 1开
unisql.skipUnisqlRuntimeConvert = 0
# 在配置项`unisql.compare.server.url`(统一 SQL 对比 http请求的url)有值的情况下,配置项`unisql.collectMicroServiceParametersEnabled`表示是否采集微服务参数,默认0表示不采集微服务参数,0关 1开
unisql.collectMicroServiceParametersEnabled = 0
# charset 默认0 [0 utf8 1 gbk]
unisql.charset = 0
# 统一SQL自定义函数脚本执行所在的schema或database; 默认unisql
unisql.schema = unisql
# 移除列上的双引号 0 不移除 1移除
unisql.removeDoubleQuoted = 0
#gaussdb decode函数的参数为下列函数,函数之间用英文逗号分割,则decode的参数都转化为text类型
unisql.decode.parameters.funcnames =
# 是否将MySQL的create database替换成create schema,0不替换,1替换
unisql.change.database.to.schema = 1
# 转换后的sql中自定义表或字段名称结尾是否使用随机数0不随机,1随机 默认1随机
unisql.table.column.name.random = 1
# 配置关键字,对象名如果匹配到了此配置参数中配置的关键字则使用双引号包裹,每个关键字之间用逗号分隔
unisql.keyword.doublequotes = group,desc,sort,collation,order,ref
# 兼容mysqlToGuassDB [ON UPDATE current_timestamp()]列,这种属性的列需要通过配置指定,update语句根据语义处理指定列;格式:tableName:column1,column2
unisql.on.update.currentimestamp.columns =
#全局替换SQL,用于处理类似 alter table XX move tablespace XX 语法,该语法目标库不支持
unisql.global.replace.sql = select 1
#是否开启打印内存信息,0:不开启,1:开启 (注意:本参数仅适合在开发/测试环境开启观察内存使用情况,不允许在生产环境开启)
unisql.print.sysinfo = 0
# 每隔多少分钟打印一次内存dump信息(在unisql.print.sysinfo=1时生效)
unisql.print.logMemMinute = 10
# 源库是mysql时,是否识别'\'为转义字符,0:不识别,1:识别
unisql.mysql.backslash.escapes= 1
#兼容mysqlToGuassDB [auto_increment]列,这种属性的列需要通过配置指定,insert into语句会自增列截断处理,不插入自增列的值;格式:tableName1:column1;tableName2:column2;
unisql.auto.increment.column = tb_cdm_class_attrib:id;tb_rpa_flow_reference:id;tb_rpa_job_reference:id;tb_cdm_attrib_values_relation:id;tb_cdm_attrib_values:id;tb_operate_log:id;tb_see_subsystem_components:id;tb_see_id:id;tb_job_reference:id;tb_jobnet_reference:id;tb_jobnet_sched_ref:id;tb_jobnet_snapshot:id;tb_job_log:id;tb_see_candle_maintain:id;tb_influxdb_sync:id;tb_see_event_report:id;
#配置获取元数据的schema,多个用逗号隔开,如果代码里调用接口指定schemas,以代码中为准
unisql.table.column.metadata.schemas =
#定时拉取最新元数据更新到缓存中开关,开启之后会周期性的去系统表拉取最新的元数据信息缓存到本地,0:关闭,1:开启;默认关闭
unisql.table.metadata.schedule.switch = 1
#用于设置周期性拉取元数据更新到缓存的频率,当开启拉取缓存定时任务后会根据设置频率周期性拉取元数据更新到缓存,单位分钟,默认一天
unisql.table.metadata.schedule.frequency = 1440
# 源库是mysql时,指定表中字段转换后的数据类型(如果create table.../alter table ... add | modify | change...语句中表的字段和配置匹配,则使用指定的数据类型,否则使用统一SQL正常转换数据类型,见数据类型章节),格式:tableName:columnName:datatype;...,tableName为表名,columnName为字段名,datatype为数据类型,如int、varchar(100);表名,字段名大小写敏感(需要填写数据库中创建后真实名称);表名、字段名、数据类型不能为空;原始语句使用时不支持反引号中带双引号,例如: `"object"`
unisql.table.column.replace.datatype = tb_rpa_flow_params_define:default_value:text;tb_rpa_flow_params_instance:value:text;
unisql.on.update.currentimestamp.columns = tb_dssp_product_stack:update_time;tb_dssp_product_stack_config:update_time;tb_dssp_app_install_db_log:update_time;tb_dssp_product_stack_build_log:updateTime;tb_dssp_app_monitor:update_time;tb_dssp_disaster_log:update_time;tb_dssp_auto_recovery_log:update_time;tb_dssp_rcm_history:updateTime;tb_dssp_application_script:update_time;tb_canary_release_log:occurred_time;
# 适配的统一SQL目标数据库版本号,主要用于做逻辑分支判断,相同的数据库不同的版本可能会走不同的解析转换逻辑,默认为空,走默认逻辑。
unisql.target.database.version=
# 源库是mysql,查询语句中,指定表名和列名后,主要解决列名的绑定变量值为空的转化问题,会将where columnName = ? 转化成 where (columnName =? or (cast ? as dataType) is null and columnName is null),格式为: 表名1:列名1,列名2;表名2:列名1;表名3:*; 其中列名为*,指表中所有列,例如:tableName1:column1,column2;tableName2:column2;tableName3:*;
unisql.null.table.columns=
# 源库为mysql,目标库为gaussdb_oracle时。指定表的字段查询大小写不敏感,查询时会将字段和条件内容通过UPPER函数包裹。表名,字段名大小写敏感(需要填写数据库中创建后真实名称);格式为:表名1:列名1,列名2;表名2:列名1; 例如:tableName1:column1,column2;tableName2:column2;同时会在统一SQL配置目录下生成create_index.sql文件
unisql.table.column.upper.case =
# 如果配置了unisql.table.column.upper.case参数,指定表的字段查询大小写不敏感时,此参数才会生效,用于提示业务手动创建统一SQL配置目录下生成的create_index.sql文件中的索引,0 提示且不启动统一SQL ,1 提示并启动统一SQL。 默认0 提示且不启动。
unisql.table.column.upper.case.print.sql.switch = 0
unisql.lib.full-path=/home/see/unisql/unisql.linux.aarch64.so

其中,unisql.lib.full-path=/home/see/unisql/unisql.linux.aarch64.so 为统一SQL链接库,路径自定义即可。

2. jrescloud.properties参数配置

../_images/%E7%BB%9F%E4%B8%80sql%E5%A4%9A%E5%8F%91%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9B%AE%E5%BD%95.png
# 是否发送到比对服务(总开关),默认0不发送到比对服务,取值范围[0,1]
multi.sendCompareService=1
# 在发送比对服务的前提下(即配置项unisql.multi.sendCompareService=1),默认1表示采集dml前后数据变化并发送到pulsar,取值范围[0,1]
multi.onlyCompare=1
# 在发送比对服务的前提下(即配置项unisql.multi.sendCompareService=1),用于是否从线程threadlocal变量(微服务使用t3协议通讯且开启全链路日志开关)中获取全链路trace_id,默认为0表示关闭,取值范围[0,1]
multi.collect.trace.info=0
# Pulsar服务端地址,样例数据:pulsar://10.20.47.203:6650
#multi.pulsarServiceUrl=pulsar://10.20.xx.xx:6650
# Pulsar的持久化主题,主题格式:persistent://<tenant>/<namespace>/<topic>,样例数据为:persistent://public/default/recordMonitorJingji
#multi.topicName=persistent://public/default/see_develop_zxd
# 在Pulsar中,订阅(Subscription)是用于消费主题消息的标识符。订阅名称是用来标识不同消费者或消费组在订阅相同主题时的唯一标识。合法字符串即可,比如jingjiTest
#multi.subscriptionName=see_develop
# 上传数据库比对结果报告到手工的blade平台的URL(业务场景:【数风基】,联系人@李吉凯),URL格式为http://{ip}:{port}/share/v1/shareInterFace/setCompatDelivery.json
# unisql.multi.upload.manual.url=http://10.20.xx.xx:8010/share/v1/shareInterFace/setCompatDelivery.json
# http请求上送sql执行前后数据变化到到比对服务的url,默认值为空,url格式为http://ip:port/em/compare/upload/change/data
multi.send.change.data.http.url=http://10.20.xx.xx:17334/em/compare/upload/change/data

multiplex.datasource.gaussdb500_oracle.url=jdbc:opengauss://10.20.xx.xx:30100/see_duofa?currentSchema=acm&sourceDialect=mysql&targetDialect=gaussdb500_oracle&options=-c%20search_path=public,acm,acm_job
multiplex.datasource.gaussdb500_oracle.username=unisqlxx
multiplex.datasource.gaussdb500_oracle.password=unisql@123xx

其中,jrescloud.properties,需要配置以下信息:

  • 需要配置消息队列或者http请求的url(二选一),见上面例子。本次采用http的方式进行配置:multi.send.change.data.http.url=http://IP地址:端口/em/compare/upload/change/data。

  • 配置目标库的信息gaussdb500_oracle,包含url、数据库用户名、密码,详见上面。

9.2.3.3. 第三步:引入多发比对代理包(外挂方式)

需要将多发比对的依赖包分别放到下面三个文件夹目录:

../_images/%E5%A4%9A%E5%8F%91%E6%AF%94%E5%AF%B9%E4%BE%9D%E8%B5%96%E5%8C%85.png
  • acm服务lib目录:/home/see/tomcat/webapps/acm/WEB-INF/lib/

  • cas服务lib目录:/home/see/tomcat/webapps/cas/WEB-INF/lib/

  • server服务lib目录:/home/see/server/lib

9.2.3.4. 第四步:配置源库url

分别在下面两个文件下,配置多发源库的url信息、数据库用户名、密码信息、驱动类信息,具体如下:

  • acm源库配置路径:/home/see/tomcat/webapps/acm/WEB-INF/conf/jdbc.properties

  • cas源库配置路径:home/see/tomcat/webapps/cas/WEB-INF/classes/application.properties

因为acm、cas里面源库修改的地方是一致的,就以acm为例进行展示

cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/acm?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=E1(K7LbV0uh2nbJ6S5isMckkw==)
cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver

需要将SEE之前的url信息,修改为接多发的配置信息,如下所示

cas.authn.jdbc.query[0].url=jdbc:unisql:mysql://localhost:3306/acm?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false&mode=MULTIPLEX&sourceDialect=mysql&targetDialect=mysql
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=E1(K7LbV0uh2nbJ6S5isMckkw==)
cas.authn.jdbc.query[0].driverClass=com.hundsun.lightdb.unisql.proxy.Driver

9.2.3.5. 第五步:启动业务应用

经过前面的三个步骤,已经成功配置了多发比对的目录及参数、多发比对的jar包,接下来启动SEE应用。

../_images/SEE%E5%BA%94%E7%94%A8%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC.png

9.2.3.6. 第六步:通过日志查看多发比对的运行情况

SEE应用启动后,会产生统一SQL、多发日志,用于判断配置参数是否正确、执行情况是否正常。

1、 自动会在java进程的工作目录:/home/see/tomcat/bin下生成 unisql-yymmdd-hhmmss.log日志,统一sql日志。

../_images/%E7%BB%9F%E4%B8%80SQL%E5%8A%A0%E8%BD%BD%E6%97%A5%E5%BF%97.png

通过该日志,可以看到已经加载在unisql.conf、jrescloud.properties文件,并能确认加载的包的版本号如24.3。

  1. 会在/home/see/tomcat/logs/unisql.log中生产多发日志

    ../_images/%E5%A4%9A%E5%8F%91%E9%83%A8%E5%88%86%E6%97%A5%E5%BF%97%E5%B1%95%E7%A4%BA.png

若多发成功,会出现红框、绿框的消息发送成功的日志。至此,基于SEE2.0的多发比对服务对接就全部完成了。

9.2.3.7. 可选模式,引用代理包(代理模式)

目前可支持两种方式来引用多发代理包(代理模式或外挂模式),外挂模式见上面第步的配置方式;如选择代理模式,通过Maven依赖引入 sql-convert-runtime

引用方法:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <properties>
        <sql-convert-runtime.version>24.3</sql-convert-runtime.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.hundsun.lightdb</groupId>
            <artifactId>sql-convert-runtime</artifactId>
            <version>${sql-convert-runtime.version}</version>
        </dependency>
    </dependencies>

</project>

9.2.3.8. 消息队列安装(可选)

9.2.3.8.1. 下载消息队列(Pulsar)

9.2.3.8.2. 启动消息队列(Pulsar)

上传apache-pulsar-2.10.5-bin.tar.gz包到指定linux服务器进行解压安装,服务器需要预先安装1.8或以上版本JDK环境:

[lightdb@hs-10-20-30-217 ~]$tar -xzvf apache-pulsar-2.10.5-bin.tar.gz -C /usr/local/
[lightdb@hs-10-20-30-217 ~]$cd /usr/local/
[lightdb@hs-10-20-30-217 ~]$mv apache-pulsar-2.10.5/ pulsar

[lightdb@hs-10-20-30-217 ~]$vi /root/.bashrc
  export PULSAR_HOME=/usr/local/pulsar
  export PATH=$PATH:$PULSAR_HOME/bin
[lightdb@hs-10-20-30-217 ~]$source /root/.bashrc
#后台服务运行
[lightdb@hs-10-20-30-217 ~]$pulsar-daemon start standalone

9.2.3.9. 多发消息通过http方式推送到比对服务

多发消息通过http方式推送到比对服务时 不需要安装消息队列 。如需使用该模式参考多发配置项 multi.send.change.data.http.url 多发配置管理

9.2.3.10. 比对服务安装

9.2.3.10.1. 下载比对服务(comparison)

  • 从官网下载最新的统一sql比对服务包: 下载使用-LightDB中间件-多发比对-比对服务下载

  • 比对服务的jar包(可独立启动) comparison-xx.xx.xx.jar,在比对服务包中路径为:LightDB1.0-comparison-Vxxxxxx-xx-xxx/comparison-xx.xx.xx.jar。

  • 解压到目标服务器的自定义目录下

9.2.3.10.2. 执行比对服务数据库初始化

  • 安装LightDB数据库(版本号需<=23.4) 下载LightDB 安装LightDB

    首先获取<=LightDB 23.4 版本的安装包,解压后,参考 LightDB安装手册, 在机器上安装一个单机版实例。

    为了便于操作,安装程序会在 ~/.bashrc 中写入LightDB相关的环境变量,可以重新登录一下shell,或者执行 source ~/.bashrc 使得环境变量生效。

    我们演示环境把数据库实例安装在 /data/lightdb 目录下,您在具体操作时可以安装到其他目录下,只要lightdb用户有对应目录的权限即可。

    安装完成后,可以查看 LTHOMELTDATA 环境变量确定实际安装目录和实例目录:

    [lightdb@0b3770c2d30a ~]$ echo $LTHOME
    /data/lightdb/lightdb-x/13.8-22.4
    [lightdb@0b3770c2d30a ~]$ echo $LTDATA
    /data/lightdb/lightdb-x/13.8-22.4/data/defaultCluster/
    
  • 2.数据库初始化

    LightDB分布式功能是在 canopy 插件中实现的,在单机版环境中是没有启用``canopy``插件,需要在每台机器上手工启用一下。 首先编辑 $LTDATA/lightdb.conf 文件, 修改GUC参数 shared_preload_libraries ,在参数最开头加上 canopy

    # 原始值
    shared_preload_libraries='lt_stat_statements,lt_stat_activity,lt_prewarm,lt_cron,lt_hint_plan,lt_show_plans'
    
    # 修改后(注意要在开头加canopy,不能加在其他位置)
    shared_preload_libraries='canopy,lt_stat_statements,lt_stat_activity,lt_prewarm,lt_cron,lt_hint_plan,lt_show_plans'
    

    添加完成后,重启一下数据库让参数生效: lt_ctl restart。

    使用 ltsql 工具登录数据库,创建比对服务数据库 em 和 canopy 插件。

    [lightdb@0b3770c2d30a ~]$ ltsql
    ltsql (13.8-22.4)
    Type "help" for help.
    
    # 注: 创建em库用于测试
    lightdb@postgres=# create role em;
    CREATE ROLE
    lightdb@postgres=# create database em with owner em LIGHTDB_SYNTAX_COMPATIBLE_TYPE Oracle;
    NOTICE:  Canopy partially supports CREATE DATABASE for distributed databases
    DETAIL:  Canopy does not propagate CREATE DATABASE command to workers
    HINT:  You can manually create a database and its extensions on workers.
    CREATE DATABASE
    
    # 注: 切换到刚创建的em库中,(后续可以使用ltsql -d em直接登录到em库中)
    lightdb@postgres=# \c em
    You are now connected to database "em" as user "lightdb".
    
    # 注: 创建canopy插件
    lightdb@em=# CREATE EXTENSION canopy;
    CREATE EXTENSION
    

    在LightDB安装服务器上执行 comparison_init.sh 脚本即可完成比对服务数据库的初始化。

9.2.3.10.3. 修改比对服务配置文件(comparison)

  • 修改微服务配置文件 LightDB1.0-comparison-Vxxxxxx-xx-xxx/config/jrescloud.properties

app.web.domain=${IP}                   //换成应用所在机器ip
app.web.home=http://${IP}:17333/em     //换成应用所在机器ip

dyn.spring.datasources[0].url=jdbc:postgresql://${IP}:${PORT}/em     //换成实际的lightdb数据库ip、端口
dyn.spring.datasources[0].username=${USERNAME}                       //换成实际的lightdb数据库用户名
dyn.spring.datasources[0].password=${PASSWORD}                       //换成实际的lightdb数据库密码

jrescloud.properties中除以上罗列的参数外,其余参数按照默认配置

  • 修改统一sql配置文件 LightDB1.0-comparison-Vxxxxxx-xx-xxx/config/jrescloud.properties

multi.pulsarServiceUrl=pulsar://${IP}:${PORT}            //Pulsar服务端地址,样例数据:pulsar://10.20.47.203:6650
multi.topicName=persistent://public/default/${TOPIC}     //Pulsar的持久化主题,主题格式:persistent://<tenant>/<namespace>/<topic>,样例数据为:persistent://public/default/recordMonitorJingji
multi.subscriptionName=${SUBSCRIPTION}                   //在Pulsar中,订阅(Subscription)是用于消费主题消息的标识符。订阅名称是用来标识不同消费者或消费组在订阅相同主题时的唯一标识。合法字符串即可,比如jingjiTest
multi.dingding.accessToken=                              //钉钉机器人Webhook的accessToken
multi.dingding.secret=                                   //钉钉机器人消息的secret,安全设置选择加签时产生
multi.dingding.url=                                      //在消息中增加比对服务页面url方便跳转

9.2.3.10.4. 启动比对服务(comparison)

  • 执行启动脚本 comparison_start.sh 启动比对服务

  • 查看比对服务启动成功标志,日志文件comparison.log中包含关键字 server started

# 进入解压目录 LightDB1.0-comparison-Vxxxxxx-xx-xxx
[lightdb@hs-10-20-30-217 comparison]$ pwd
/home/lightdb/LightDB1.0-comparison-Vxxxxxx-xx-xxx
[lightdb@hs-10-20-30-217 comparison]$ sh comparison_start.sh  --help
修改多发配置文件jrescloud.properties中Pulsar消费者配置multi.pulsarServiceUrl(Pulsar服务端地址), multi.topicName(Pulsar的持久化主题), multi.subscriptionName(在Pulsar中客户端消费者订阅名称),multi.run.what(是否执行多发的总开关)
使用: sh comparison_start.sh 启动比对服务
[lightdb@hs-10-20-30-217 comparison]$ sh comparison_start.sh

9.2.4. 基于JRESCloud3.X开发框架 + mybatis(IDEA开发模式集成为例)

9.2.4.1. 修改统一sql配置文件:${当前工作目录}/config/jrescloud.properties

multi.run.what=2                                          // 0:不执行自动化和多发 1:执行自动化测试 2:执行多发(关联多发的源库(oracle或者mysql)的jdbcUrl中查询参数mode=MULTIPLEX) 3:执行自动化+多发(关联多发的源库(oracle或者mysql)的jdbcUrl中查询参数mode=MULTIPLEX)
multi.sendCompareService=1                               // 是否发送到比对服务(总开关),默认0不发送到比对服务,取值范围[0,1]
multi.pulsarServiceUrl=pulsar://${IP}:${PORT}            // Pulsar服务端地址,格式为:pulsar://<ip>:<port> 样例数据:pulsar://10.20.47.203:6650
multi.topicName=persistent://public/default/${TOPIC}     // Pulsar的持久化主题,主题格式:persistent://<tenant>/<namespace>/<topic>,样例数据为:persistent://public/default/recordMonitorJingji
multi.subscriptionName=${SUBSCRIPTION}                   // 在Pulsar中,订阅(Subscription)是用于消费主题消息的标识符。订阅名称是用来标识不同消费者或消费组在订阅相同主题时的唯一标识。合法字符串即可,比如jingjiTest

9.2.4.2. 模拟数据

CREATE TABLE foo (
    city_id NUMBER PRIMARY KEY,
    nation VARCHAR2(50),
    city_name VARCHAR2(100),
    city_sort NUMBER
);

INSERT INTO Foo (city_id, nation, city_name, city_sort) VALUES (1, 'China', 'Beijing', 1);
INSERT INTO Foo (city_id, nation, city_name, city_sort) VALUES (2, 'USA', 'New York', 2);
INSERT INTO Foo (city_id, nation, city_name, city_sort) VALUES (3, 'Japan', 'Tokyo', 3);
INSERT INTO Foo (city_id, nation, city_name, city_sort) VALUES (4, 'China', 'ShangHai', 4);
INSERT INTO Foo (city_id, nation, city_name, city_sort) VALUES (5, 'Canada', 'Toronto', 5);

9.2.4.3. pom依赖

 <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.hundsun.jrescloud</groupId>
            <artifactId>jrescloud-dependencies</artifactId>
            <version>3.0.21.2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>com.hundsun.jrescloud.middleware</groupId>
        <artifactId>jrescloud-starter-mybatis</artifactId>
    </dependency>

    <dependency>
        <groupId>com.hundsun.jrescloud</groupId>
        <artifactId>jrescloud-starter</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>log4j-slf4j-impl</artifactId>
                <groupId>org.apache.logging.log4j</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>com.hundsun.jrescloud</groupId>
        <artifactId>jrescloud-starter-rpc-def</artifactId>
    </dependency>

    <dependency>
        <groupId>com.oracle.ojdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.3.0.0</version>
    </dependency>

    <dependency>
        <groupId>cn.easyproject</groupId>
        <artifactId>orai18n</artifactId>
        <version>12.1.0.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>io.github.hslightdb</groupId>
        <artifactId>ltjdbc</artifactId>
        <version>42.2.24-22.4.0.3</version>
    </dependency>

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
    </dependency>

    <!--sql runtime-->
    <dependency>
        <groupId>com.hundsun.lightdb</groupId>
        <artifactId>sql-convert-runtime</artifactId>
        <version>24.2.3-SNAPSHOT</version>
    </dependency>

    <!--unisql-compare-client-->
    <dependency>
        <groupId>com.hundsun.lightdb</groupId>
        <artifactId>unisql-compare-client</artifactId>
        <version>24.2.3-SNAPSHOT</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/unisql-compare-client-fat-24.2.3.jar</systemPath>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
    </dependency>

    <dependency>
        <groupId>com.github.jnr</groupId>
        <artifactId>jnr-ffi</artifactId>
        <version>2.2.14</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba.fastjson2</groupId>
        <artifactId>fastjson2</artifactId>
        <version>2.0.36</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
        <version>4.4</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!--gaussdb_oracle驱动-->
    <dependency>
        <groupId>com.huawei.opengauss.jdbc</groupId>
        <artifactId>gaussdbDriver</artifactId>
        <version>3.0.0-htrunk21</version>
    </dependency>

    <!--tdsql-pg-->
    <dependency>
        <groupId>com.tencentcloud.tdsql</groupId>
        <artifactId>tdsql-pg-connector-java8</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>

9.2.4.4. 在配置文件src/main/resources/application.properties中配置多数据源

app.name=demo-datasource
app.group=dbtest

server.port=9876
mybatis.mapperLocations=classpath:/Mapper/*.xml

hs.db.enabled=true

#postgres
hs.datasource.default.driver-class-name=org.postgresql.Driver
hs.datasource.default.url=jdbc:postgresql://ip:port/postgres
hs.datasource.default.username=username
hs.datasource.default.password=password
hs.datasource.default.validationQuery=select 1

#mysql
hs.datasource.mysql.driverClassName=com.mysql.cj.jdbc.Driver
hs.datasource.mysql.url=jdbc:mysql://ip:port/unisql?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
hs.datasource.mysql.username=username
hs.datasource.mysql.password=password

#unisql  multiplex
hs.datasource.unisql.driverClassName=com.hundsun.lightdb.unisql.proxy.Driver
hs.datasource.unisql.url=jdbc:unisql:oracle:thin:@//ip:port/orcl?sourceDialect=oracle&targetDialect=oracle&mode=MULTIPLEX
hs.datasource.unisql.username=username
hs.datasource.unisql.password=password

# 目标库为 lightdb_oracle 时,打开并修改以下连接信息
multiplex.datasource.lightdb_oracle.url=jdbc:postgresql://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=lightdb_oracle&options=-c%20search_path=public
multiplex.datasource.lightdb_oracle.username=USERNAME
multiplex.datasource.lightdb_oracle.password=PASSWORD
# 目标库为 gaussdb_oracle 时,打开并修改以下连接信息
multiplex.datasource.gaussdb_oracle.url=jdbc:opengauss://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=gaussdb_oracle&options=-c%20search_path=public
multiplex.datasource.gaussdb_oracle.username=USERNAME
multiplex.datasource.gaussdb_oracle.password=PASSWORD

9.2.4.5. 使用多数据源注解@EnableCloudDataSource注解用于开启多数据源

/**
* 多数据源注解@EnableCloudDataSource,开启多数据源功能
*/
@EnableCloudDataSource
@CloudApplication // 启动类注解
public class UnisqlMultiDataSourceApplication {

    public static void main(String[] args) {
        CloudBootstrap.run(UnisqlMultiDataSourceApplication.class, args);
    }
}

9.2.4.6. 使用数据源指定注解@TargetDataSource指定当前服务类或服务方法所使用的数据源

@Service
public class TestServiceImpl implements TestService {

    @Override
    @TargetDataSource("unisql")// 指定数据源unisql,该数据源将会使用统一SQL
    public List<Foo> selectFooByUnisql() {
        List<Foo> foo = fooMapper.select();
        return foo;
    }

}

9.2.4.7. 基于mybatis,指定数据源unisql的mapper接口方法select对应的SQL映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.middleware.dao.FooMapper">


    <resultMap id="result" type="com.demo.middleware.domain.Foo">
        <result column="city_id" property="cityId" jdbcType="INTEGER" />
        <result column="nation" property="nation" jdbcType="VARCHAR" />
        <result column="city_name" property="cityName" jdbcType="VARCHAR" />
        <result column="city_sort" property="citySort" jdbcType="VARCHAR" />
    </resultMap>

    <select id="select" resultMap="result">
        SELECT city_id, nation,city_name, city_sort FROM foo
    </select>
</mapper>

9.2.4.8. 多发测试成功输出类似如下

2024-10-09 16:28:07.498  INFO 23724 --- [nio-9876-exec-2] c.h.lightdb.unisql.utils.PulsarUtil      :
sql驱动拦截,发送sql增量变化到pulsar服务端,开始,
消息体[{"appName":"demo-datasource","databaseName":"uniq_oracle","effectRows":0,"fieldColumnNames":"city_id&&nation&&city_name&&city_sort",
"fieldColumnTypes":"numeric&&varchar&&varchar&&numeric","functionId":"","ip":"","onlyCompare":true,
"prev":[[1,"China","Beijing",1],[2,"USA","New York",2],[3,"Japan","Tokyo",3],[4,"China","ShangHai",4],[5,"Canada","Toronto",5]],
"recordTimestamp":1728548887496,"sourceDialect":"ORACLE","sql":"SELECT city_id, nation,city_name, city_sort FROM foo",
"sqlParameters":"","sqlSequence":1,"sqlType":"SELECT","tableName":"foo","targetDialect":"GAUSSDB_ORACLE",
"traceId":"86e163d7-2bf8-4ec6-92a7-d8ae287d585e","transferSql":"SELECT city_id,nation,city_name,city_sort FROM foo"}]

9.2.5. SpringBoot + JdbcTemplate(IDEA开发模式集成为例)

9.2.5.1. 数据源配置如下:

server.port=8080

mybatis.configuration.map-underscore-to-camel-case=true

spring.datasource.driver-class-name=com.hundsun.lightdb.unisql.proxy.Driver
spring.datasource.url=jdbc:unisql:oracle:thin:@//ip:port/orcl?sourceDialect=oracle&targetDialect=oracle&mode=MULTIPLEX
spring.datasource.username=username
spring.datasource.password=password

logging.level.com.hundsun.lightdb.unisql=info

# 目标库为 lightdb_oracle 时,打开并修改以下连接信息
multiplex.datasource.lightdb_oracle.url=jdbc:postgresql://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=lightdb_oracle&options=-c%20search_path=public
multiplex.datasource.lightdb_oracle.username=USERNAME
multiplex.datasource.lightdb_oracle.password=PASSWORD
# 目标库为 gaussdb_oracle 时,打开并修改以下连接信息
multiplex.datasource.gaussdb_oracle.url=jdbc:opengauss://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=gaussdb_oracle&options=-c%20search_path=public
multiplex.datasource.gaussdb_oracle.username=USERNAME
multiplex.datasource.gaussdb_oracle.password=PASSWORD

9.2.5.2. pom依赖:

 <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.3.0</version>
    </dependency>

    <!--sql runtime-->
    <dependency>
        <groupId>com.hundsun.lightdb</groupId>
        <artifactId>sql-convert-runtime</artifactId>
        <version>24.2.3-SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.hundsun.lightdb</groupId>
        <artifactId>unisql-compare-client</artifactId>
        <version>24.2.3-SNAPSHOT</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/unisql-compare-client-fat-24.2.3.jar</systemPath>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.13.0</version> <!-- 这里可以使用最新版本 -->
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.11</version>
    </dependency>

    <dependency>
        <groupId>com.github.jnr</groupId>
        <artifactId>jnr-ffi</artifactId>
        <version>2.2.14</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba.fastjson2</groupId>
        <artifactId>fastjson2</artifactId>
        <version>2.0.36</version> <!-- 这里写上你想使用的版本号 -->
    </dependency>

    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
    </dependency>

    <!--gaussdb_oracle驱动-->
    <dependency>
        <groupId>com.huawei.opengauss.jdbc</groupId>
        <artifactId>gaussdbDriver</artifactId>
        <version>3.0.0-htrunk21</version>
    </dependency>

    <!--tdsql-pg-->
    <dependency>
        <groupId>com.tencentcloud.tdsql</groupId>
        <artifactId>tdsql-pg-connector-java8</artifactId>
        <version>1.1.1</version>
    </dependency>

    <!-- 日志相关 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.30</version>
    </dependency>

    <!-- logback 依赖 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

9.2.5.3. 代码如下:

@Autowired
JdbcTemplate jdbcTemplate;

@Test
void testSpringboot() {
    // 原生oracle sql语句
    String oracleSQL = "select nation, listagg(city_name,',') within group (order by city_sort desc) citys from foo group by nation";
    // 返回gaussdb_oracle执行结果
    List<Map<String, Object>> list = jdbcTemplate.queryForList(oracleSQL);
}

9.2.5.4. 多发测试成功结果输出类似如下

2024-10-09 17:29:40.697 [main] INFO  c.h.lightdb.unisql.utils.PulsarUtil - sql驱动拦截,发送sql增量变化到pulsar服务端,结束,
消息体[{"databaseName":"uniq_oracle","effectRows":0,"fieldColumnNames":"nation&&citys","fieldColumnTypes":"varchar&&text",
"functionId":"","ip":"","onlyCompare":true,"prev":[["Canada","Toronto"],["China","ShangHai,Beijing"],["Japan","Tokyo"],["USA","New York"]],
"recordTimestamp":1728552579224,"sourceDialect":"ORACLE","sql":"select nation, listagg(city_name,',') within group
(order by city_sort desc) citys from foo group by nation","sqlParameters":"","sqlSequence":1,"sqlType":"select",
"tableName":"foo","targetDialect":"GAUSSDB_ORACLE","traceId":"31f0aa49-bcda-495d-88d8-8fb2e4f46707","transferSql":"SELECT nation,
listagg(city_name, ',') WITHIN GROUP (ORDER BY city_sort DESC) AS citys FROM foo GROUP BY nation"}],messageId=[131641:20:-1]
[{nation=Canada, citys=Token}, {nation=China, citys=ShangHai,Beijing}, {nation=Japan, citys=Tokyo}, {nation=USA, citys=New York}]

9.2.6. studio集成多发

9.2.6.1. 下载文件

  1. 从官网下载最新的lightdb-studio包: 下载使用-客户端软件-LightDB-Studio-windows

解压 LightDB1.0-studio-Vxxxxxx-xx-xxx-win-x86_64.zip 到windows自定义目录中

  1. 从官网下载对应版本的统一sql比对服务包: 下载使用-LightDB中间件-多发比对-比对服务下载

解压 LightDB1.0-comparison-Vxxxxxx-xx-xxx.zip 到windows某个目录

  1. 从官网下载最新的统一sql包,如当前最新版本: 下载使用-LightDB中间件-统一SQL-下载(动态库)

解压 LightDB1.0-unisql-Vxxxxxx-xx-xxx.zip 到windows某个目录

9.2.6.2. 配置多发目标数据库

  1. 在 lightdb_studio 解压目录中新增多发目标库配置文件 LightDB1.0-studio-Vxxxxxx-xx-xxx-win-x86_64/lightdb_studio/config/jrescloud.properties

  2. 将目标数据库的多发数据源配置复制到 jrescloud.properties,并修改对应的连接信息,将IP、PORT、DATABASE、USERNAME、PASSWORD修改为目标库的IP地址、服务端口、连接数据库、连接用户名、连接密码

    # 目标库为 lightdb_oracle 时,打开并修改以下连接信息
    multiplex.datasource.lightdb_oracle.url=jdbc:postgresql://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=lightdb_oracle&options=-c%20search_path=public
    multiplex.datasource.lightdb_oracle.username=USERNAME
    multiplex.datasource.lightdb_oracle.password=PASSWORD
    # 目标库为 gaussdb_oracle 时,打开并修改以下连接信息
    multiplex.datasource.gaussdb_oracle.url=jdbc:opengauss://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=gaussdb_oracle&options=-c%20search_path=public
    multiplex.datasource.gaussdb_oracle.username=USERNAME
    multiplex.datasource.gaussdb_oracle.password=PASSWORD
    # 目标库为 ocean_base_oracle 时,打开并修改以下连接信息
    multiplex.datasource.ocean_base_oracle.url=jdbc:oceanbase://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=ocean_base_oracle
    multiplex.datasource.ocean_base_oracle.username=USERNAME
    multiplex.datasource.ocean_base_oracle.password=PASSWORD
    # 目标库为达梦数据库时,打开并修改以下连接信息
    multiplex.datasource.dm.url=jdbc:dm://IP:PORT/DATABASE?sourceDialect=oracle&targetDialect=dm
    multiplex.datasource.dm.username=USERNAME
    multiplex.datasource.dm.password=PASSWORD
    

9.2.6.3. 配置多发消息代理

  1. 修改LightDB1.0-studio-Vxxxxxx-xx-xxx-win-x86_64/lightdb_studio/config 目录下jrescloud.properties文件(多发配置项multi开头)

  2. 修改以下配置属性

multi.run.what=2                                        //0:不执行自动化和多发 1:执行自动化测试 2:执行多发(关联多发的源库(oracle或者mysql)的jdbcUrl中查询参数mode=MULTIPLEX) 3:执行自动化+多发(关联多发的源库(oracle或者mysql)的jdbcUrl中查询参数mode=MULTIPLEX)
multi.sendCompareService=1                               //是否发送到比对服务(总开关),默认0不发送到比对服务,取值范围[0,1]
multi.pulsarServiceUrl=pulsar://${IP}:${PORT}            //Pulsar服务端地址,格式为:pulsar://<ip>:<port> 样例数据:pulsar://10.20.47.203:6650
multi.topicName=persistent://public/default/${TOPIC}     //Pulsar的持久化主题,主题格式:persistent://<tenant>/<namespace>/<topic>,样例数据为:persistent://public/default/recordMonitorJingji
multi.subscriptionName=${SUBSCRIPTION}                   //在Pulsar中,订阅(Subscription)是用于消费主题消息的标识符。订阅名称是用来标识不同消费者或消费组在订阅相同主题时的唯一标识。合法字符串即可,比如jingjiTest

9.2.6.4. 指定统一SQL动态库及多发配置文件

  1. 下载windows版统一SQL 下载使用-LightDB中间件-统一SQL-windows版(仅用于开发) 并解压到自定义目录

  2. 修改 LightDB1.0-studio-Vxxxxxx-xx-xxx-win-x86_64/lightdb_studio/lightdb_studio.ini 文件,在 -Dfile.encoding=UTF-8 行下增加以下内容:

    -Dspring.config.location=【Studio解压目录/lightdb_studio/config/jrescloud.properties】
    -Dunisql.lib.full-path=【unisql-for-windows.zip解压后,其中unisql.windows.dll的全路径】
    
  3. 重启 lightdb_studio

9.2.6.5. 配置多发驱动管理器

  1. 新增目录并拷贝多发依赖

    1. 新增目录 LightDB1.0-studio-Vxxxxxx-xx-xxx-win-x86_64/lightdb_studio/lib

    2. 将 LightDB1.0-comparison-Vxxxxxx-xx-xxx/unisql-compare-client-fat-xx.xx.xx.jar 文件复制到该目录中。

    3. 将 LightDB1.0-unisql-Vxxxxxx-xx-xxx/sql-convert-runtime-fat-xx.xx.xx.jar 文件复制到该目录中。

  2. 点击studio上方导航栏中的 数据库 -> 驱动管理器 -> 新建;

  3. 在 创建新驱动 的第一个tab页面 设置:

    • 驱动名称:为便于区分可根据的操作源数据库来填写,例如【oracle多发】

    • 驱动类型:选择默认的 Generic 。

    • 类名: com.hundsun.lightdb.unisql.proxy.Driver

    • URL模板:jdbc:unisql:oracle:thin:@//{host}[:{port}]/[{database}]?mode=MULTIPLEX&sourceDialect=oracle&targetDialect=oracle

    • 默认端口:1521

    • 默认数据库:orcl

    • 默认用户:按需配置

../_images/studio_multi_add_driver.png
  1. 在 创建新驱动,选择第二个tab页面

    1. 点击 添加文件夹,将上述新增的目录添加进来

      ../_images/studio_config_drivers_add_dir.png
    2. 点击 添加工件,在 依赖声明 中将多发的目标库驱动添加进来,一次添加一个驱动

      ../_images/studio_config_drivers_add_lib.png
    <!--以下为oracle驱动-->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.14.0.0</version>
    </dependency>
    
    <!--以下为lightdb驱动-->
    <dependency>
        <groupId>com.hundsun.lightdb</groupId>
        <artifactId>ltjdbc</artifactId>
        <version>42.2.25-24.2.4</version>
    </dependency>
    
    <!--以下为gaussdb_oracle驱动-->
    <dependency>
        <groupId>com.huawei.opengauss.jdbc</groupId>
        <artifactId>gaussdbDriver</artifactId>
        <version>3.0.0-htrunk21</version>
    </dependency>
    
     <!--以下为ocean_base_oracle驱动-->
    <dependency>
        <groupId>com.oceanbase</groupId>
        <artifactId>oceanbase-client</artifactId>
        <version>2.4.3</version>
    </dependency>
    
     <!--以下为达梦数据库驱动-->
    <dependency>
        <groupId>com.dameng</groupId>
        <artifactId>DmJdbcDriver18</artifactId>
        <version>8.1.3.140</version>
    </dependency>
    
    1. 点击 下载/更新 下载驱动文件,下载完成后点击 确定 ,至此统一SQL的驱动就添加好了。

9.2.6.6. 创建多发连接

  1. 通过刚才新增的多发驱动建立连接,需配置源端的连接信息,之后可以通过测试连接来验证正确性

../_images/connect_1.png ../_images/connect_2.png

9.2.6.7. 测试多发功能

通过lightdb-studio直接执行sql语句,并通过结果比对页面实时检查多发操作结果的准确性。

环境初始化

  1. 创建数据库表:CREATE TABLE foo (city_id NUMBER,nation VARCHAR2(100),city_name VARCHAR2(100),city_sort NUMBER);

../_images/studio_create_table_2024-10-15_20-02-40.jpg
  1. 检查源库和多发目标库是否都创建表成功;

测试DML多发

  1. INSERT INTO foo (city_id, nation, city_name, city_sort) values(12,’china’,’beijing’,12);

  2. INSERT INTO foo (city_id, nation, city_name, city_sort) values(14,’USA’,’Jorgen’,14);

  3. 查询页面:http://IP:17334/em/workbench-tab.html,效果如下:

../_images/studio_multi_insert_result_2024-10-11.jpg
  1. 多字段表展示样例

../_images/compare_records_success_2024-07-19_16-34-34.jpg

测试DQL多发

  1. SELECT city_id,city_name FROM foo WHERE city_id=12;

../_images/studio_multi_select_result_2024-10-11.jpg
关键字配置

当配置的关键字和比对数据中的列名一样时,可以将关键字和值作为条件筛选比对结果,多个关键字查询用&连接。

../_images/add_keyword.png ../_images/compare_records_search_by_keyword.png
钉钉消息

当配置钉钉机器人后,数据比对失败,会给钉钉机器人发送消息,如下图:

../_images/dingding_message.png

环境清理

  1. DROP TABLE foo;

  2. 检查源库和多发目标库是否都已删除该表

9.2.6.8. 查看比对报告

  1. 登录到搭建的比对服务中 http://IP:17334/em/workbench-tab.html,初始化登录用户名和密码为 system/hs123456

  2. 从 lightdb_studio 日志中获取traceId,日志位于:系统用户目录AppDataRoamingLightDbStudioDataworkspace6.metadatadbeaver-debug.log

  3. 通过 traceId 查看比对报告

../_images/traceId%E6%9F%A5%E7%9C%8B%E6%AF%94%E5%AF%B9%E6%8A%A5%E5%91%8A.png
小提示

关于模式的设置,Oracle的数据库,默认情况下,用户名与模式名称相同。多发功能中多发到PostgreSQL系列相关数据库, 需要在PostgreSQL系列相关数据库下创建相同名称的模式。因为Oracle的模式名称一般是大写, 所以PostgreSQL系列相关数据库创建相同大写模式名称时,模式名称要用英文双引号包裹。

9.2.6.9. 全量同步比对失败的表

在比对报告中,可点击 全表数据同步 将对比失败的表进行表数据的全量同步,当前版本只支持从 ORACLE 同步表数据到 OCEAN_BASE_ORACLE ,只支持同步一个表。详细操作步骤如下:

../_images/%E5%85%A8%E9%87%8F%E5%90%8C%E6%AD%A5%E6%AF%94%E5%AF%B9%E5%A4%B1%E8%B4%A5%E7%9A%84%E8%A1%A8.png ../_images/%E6%88%90%E5%8A%9F%E5%85%A8%E9%87%8F%E5%90%8C%E6%AD%A5%E6%AF%94%E5%AF%B9%E5%A4%B1%E8%B4%A5%E7%9A%84%E8%A1%A8.png
  1. LightDB 官网下载迁移工具 LightDB-ETL

  2. 將下载的 LightDB-ETL 里的jar包(如 lightdb-etl-24.3.jar )的绝对路径配置在环境变量 LIGHTDB_ETL_JAR

  3. 迁移日志文件目录为 {比对服务安装目录的log}/lightdb-etl/{当前时间_traceId_计数} ,可查看详细的迁移日志。

  4. 前端页面会展示基本全量同步结果。

问题排查

../_images/%E5%85%A8%E9%87%8F%E5%90%8C%E6%AD%A5%E6%AF%94%E5%AF%B9%E5%A4%B1%E8%B4%A5%E7%9A%84%E8%A1%A8%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF.png
  1. 可通过查看 LightDB-ETL 的日志文件 lightdb-etl-error.log 查看更加详细的报错内容。

  2. 日志路径为 {比对服务安装目录的log}/lightdb-etl/{当前时间_traceId_计数}

  3. lightdb-etl.log :数据同步的总日志,可查看具体迁移的表、迁移数据等。

  4. lightdb-etl-error.log :数据同步报错日志汇总。