本章节介绍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为基准库,与其他微服务传送到消息队列中的不同信创库的查询结果集进行一一比对,并记录比对差异,以比对报告的形式展示给用户查看。

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. 微服务集成多发代理

9.2.3.1. 引用代理包

目前可通过两种方式来引用多发代理包(代理模式或外挂模式):

  • 通过Maven依赖引入 sql-convert-runtime

  • sql-convert-runtime 的fat包外挂到微服务可以加载的文件目录

以下介绍两种方法的操作方式。

9.2.3.1.1. 引入 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.2.5</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.1.2. 外挂sql-convert-runtime的fat包

  • 从制品库下载最新的统一sql包,例如: 统一sql包LightDB1.0-unisql-V202402-06-000.zip

  • sql-convert-runtime的fat包 sql-convert-runtime-fat-24.2.5.jar 在统一sql包 LightDB1.0-unisql-V202402-06-000.zip 中的路径为:LightDB1.0-unisql-V202402-06-000.zip/sql-convert-runtime-fat-24.2.5.jar

9.2.3.1.2.1. 将sql-convert-runtime的fat包 sql-convert-runtime-fat-24.2.5.jar 外挂到微服务可以加载的依赖目录中

  • 以微服务 broker-foo 为例,sql-convert-runtime的fat包 sql-convert-runtime-fat-24.2.5.jar 在该微服务工作目录( /home/hundsun/server/broker-foo )lib目录下, 可使用Spring Boot的 -Dloader.path 参数指定加载fat包, java -Dloader.path=/home/hundsun/server/broker-foo/lib/ -jar broker-foo.jar

9.2.3.2. 统一sql动态库配置

9.2.3.3. 配置多发目标数据源

  • 修改微服务配置文件 jrescloud.properties

  • 将目标数据库的多发数据源配置复制到 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
    
  • 启动微服务时,通过【-Dspring.config.location=多发数据源配置文件的绝对路径】手动指定多发的目标数据源配置

9.2.3.4. 消息队列安装

9.2.3.4.1. 下载消息队列(Pulsar)

9.2.3.4.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.5. 比对服务安装

9.2.3.5.1. 下载比对服务(comparison)

  • 从制品库下载最新的统一sql比对服务包,例如: 统一sql比对服务包 LightDB1.0-comparison-V202402-06-000.zip

  • 比对服务的jar包(可独立启动) comparison-24.2.6.jar,在比对服务包中路径为:LightDB1.0-comparison-V202402-06-000/comparison-24.2.5.jar。

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

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

  • 安装LightDB数据库 下载LightDB 安装LightDB

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

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

  • 修改微服务配置文件 LightDB1.0-comparison-V202402-06-000/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-V202402-06-000/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

9.2.3.5.4. 启动比对服务(comparison)

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

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

# 进入解压目录 LightDB1.0-comparison-V202402-06-000
[lightdb@hs-10-20-30-217 comparison]$ pwd
/home/lightdb/LightDB1.0-comparison-V202402-06-000
[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包,例如: LightDB1.0-studio-V202402-06-000-win-x86_64.zip

解压 LightDB1.0-studio-V202402-06-000-win-x86_64.zip 到windows自定义目录中

  1. 从制品库下载对应版本的统一sql比对服务包,例如: LightDB1.0-comparison-V202402-06-000.zip

解压 LightDB1.0-comparison-V202402-06-000.zip 到windows某个目录

  1. 从制品库下载最新的统一sql包,如当前最新版本: 统一sql包LightDB1.0-unisql-V202402-02-000-debug.zip

解压 LightDB1.0-unisql-V202402-06-000.zip 到windows某个目录

9.2.6.2. 配置多发目标数据库

  1. 在 lightdb_studio 解压目录中新增多发目标库配置文件 LightDB1.0-studio-V202402-06-000-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-V202402-06-000-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. 下载 unisql-for-windows.zip 并解压到自定义目录

  2. 修改 LightDB1.0-studio-V202402-06-000-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-V202402-06-000-win-x86_64/lightdb_studio/lib

    2. 将 LightDB1.0-comparison-V202402-06-000/unisql-compare-client-fat-24.2.5.jar 文件复制到该目录中。

    3. 将 LightDB1.0-unisql-V202402-06-000/sql-convert-runtime-fat-24.2.5.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

环境清理

  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系列相关数据库创建相同大写模式名称时,模式名称要用英文双引号包裹。