使用oceanbase jdbc驱动执行replace into语句时rewritebatchedstatements true 不生效

【 使用环境 】测试环境
【 OB or 其他组件 】oceanbase-client, oceanbase
【 使用版本 】oceanbase-client:2.4.7.1, ob:4.2.1
【问题描述】使用oceanbase官方的jdbc的驱动,在url中使用rewritebatchedstatements=true进行自动批处理改写,insert into 的场景下通过SQL审计和日志可以监控到批处理生效,但在replace into 的场景下,批处理未生效

使用的oceanbase client 版本:

<dependency>
            <groupId>com.oceanbase</groupId>
            <artifactId>oceanbase-client</artifactId>
            <version>2.4.7.1</version>
        </dependency>

在相同数据的情况下,使用mysql 原生版本的jdbc驱动,insert into 与 replace into 两种场景下,均能实现自动批处理改写。

mysql jdbc驱动版本:

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

问题列表:

  1. 社区里是否有其他人有遇到过类似的情况?
  2. 3.x 版本的OB推荐使用的jdbc版本是哪一个?
2 个赞

麻烦提供下 jdbc 连接串的信息,我们测试下;另外,ob 不能批量处理是通过什么来判断的,是查看 sql_audit 来判断的吗?

麻烦再提供下集群的基本信息:

  1. root@sys租户登录集群,执行SQL提供下结果
    a. select svr_ip,zone,with_rootserver,status,block_migrate_in_time,start_service_time,stop_time,build_version from oceanbase.__all_server order by zone;
    b. select tenant_id,tenant_name,primary_zone,compatibility_mode from oceanbase.__all_tenant; (问题租户的租户id)
    c. show parameters like ‘%syslog_level%’;
    d. show parameters like ‘%syslog_io_bandwidth_limit%’;
    e. select count(*),tenant_id,zone_list,unit_count from oceanbase.__all_resource_pool group by tenant_id,zone_list,unit_count;
  2. 登录OB任意一台主机,执行lsblk提供下结果
  3. 登录OB任意一台主机,执行lscpu | grep Architecture 提供下结果
1 个赞

ocp 的 sql 诊断和 sql_audit 部分有截图吗?jdbc 的连接串也麻烦提供一下

是通过sql 审计中执行计划的更新行数来判断的,不知道这个准确与否?

jdbc的连接串如下:

jdbc:oceanbase://xxxx:2883/testdb?socketTimeout=60000&autoReconnect=true&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&connectTimeout=3000&loadBalanceBlacklistTimeout=180000

另外,再请教一下与义老师,4.2.1版本的oceanbase 数据库有推荐版本的jdbc驱动吗?我们想再组织测试复现一下

看一下 sql_audit 的结果呢?

oceanbase-client:2.4.7.1 这个版本用得比较多

使用oceanbase-client:2.4.7.1 再测试了一下INSERT INTO 和 REPLCAE INTO的性能差比,数据量在一百万左右,INSERT 和。REPLACE 耗时差别非常大,通过OCP看,INSERT 的批量处理应该生效了,500一提交,REPLACE的还是单笔提交的。

使用 MySQL 的驱动执行 Replace into 是可以批处理的吗?

对的,使用mysql的jdbc可以自动进行批处理改写


用mysql的jdbc驱动再试了一下,确实是实现了500笔一提交的自动批处理改写

可以查下sql_audit 吗?
select * from V$SQL_AUDIT where query_sql like ‘xxx’;

query_sql 的格式是怎么样的呢?是 replace into tbbfkbb.tbl_xxxx colums (col1, col2, col3) values (val1, val2, val3), (val4, val5, val6)....; 这样的吗? 我们这边内核的同事想验证下

是的,

用mysql的驱动从sql_audit 中看,query_sql的形式是这样的 replace into tbl_xxx (col1, … colxx) values (xx,…xxxx), (xx,…xxxx), … 此处应该是query_sql 字段限制没有完全打全

用oceanbase-client values 后面只跟了一行记录

麻烦把 query_sql 提供一下吧,字段名和 values 可以脱敏处理下

你 业务侧 replace into 的代码是怎么写的,是类似于prepareCall(replace into语句)
setXXX
addBatch
executeBatch 这样的吗?

用oceanbase-client values 后面只跟了一行记录 ,你这里只有 一行记录 是指 replace into tbl_xxx (col1, … colxx) values (xx,…xxxx) 这里只有一组值吧。

对的,从ocp的SQL诊断页面也可以很明显看到,更行的行数是1
如果使用mysql 的jdbc 驱动,SQL诊断可以看到更行的行数是500

从sys租户的oceanbase.GV$OB_SQL_AUDIT中也可以很清晰的看到,使用oceanbase-client 审计表中query_sql记录 values 后面只有一组记录,将query_sql 拿出来手动执行,对应表插入/更行了一行记录。

如果是使用mysql jdbc 驱动,query_sql记录 values 后面有多组记录,因为对应表的字段比较多(一百多个字段),query_sql 字段类型是longtext, 处理掉被截断的values值,手动执行也有十多行的数据插入/更新。

对的,两种情况下只变动了jdbc的驱动类型,代码都是同一份。

大致的流程:

conn.setAutoCommit(false);
pstmt = conn.prepareStatement(insS);
pstmt.addBatch();
pstmt.executeBatch();
conn.commit();
pstmt.clearBatch();

你好,你这边方便提供 可以简单复现的 damain 吗,我们复现看下

上面有给出表结构和一部分示例的数据,可以供参考。应用层的代码因为管控的问题没办法单独摘出来。