jdbc batch insert失败但是没有异常怎么排查

tidb v6.1
通过flink加载到数据库
通过jdbc batch insert 方式 插入数据
情况是 正常情况下insert语句返回一个规模等于batchsize 的数组元素都是-2
但是有时候返回一个数组 数组的每个元素都是-2 但是 规模小于batchsize 程序没有异常被捕获 tidb的日志也没有发现异常求排查思路

可否共享 代码片段及建表语句 或 复现方法 ?

库表很普通一个分区表 按天分区 表上一个主键一个索引

错误的出现有没有规律?返回 -2 数组时有没有打SQL日志?

没有啊 在监控上能看到rollback

有一些 insert into delete-range table 的消息

给下复现流程吧,没有详细信息我也只能猜……

public void executeBatch(Connection connection) throws SQLException {
long start = System.currentTimeMillis();
if (rows.size() != 0) {
try {
rows.forEach(row -> {
try {
JDBCUtils.setRecordToStatement(this.statement, this.fieldTypes, (Row) row);
this.statement.addBatch();
} catch (SQLException e) {
throw new RuntimeException(e);
}
});
int[] ints = this.statement.executeBatch();
connection.commit();
int j = ints.length;
if (rows.size() != j) {
throw new RuntimeException(String.format(“入库数量不一致, Rows.size():%d, 执行成功条数,批量执行返回int数组长度:%s”, rows.size(), j));
}
long s = System.currentTimeMillis() - start;
LOG.info(“批量入库{}条数据,用时{}ms, 实际入库{}条数据”, rows.size(), s, j);
rows.clear();
} catch (Exception e) {
LOG.info(“批量入库失败,转为单条入库…{}, rows:{}”, e, rows);
connection.rollback();
connection.commit();
this.statement.clearBatch();
executeUpdate(connection);
}
}
}

public synchronized void executeUpdate(Connection connection) {
    long start = System.currentTimeMillis();
    AtomicInteger success = new AtomicInteger();
    AtomicInteger failed = new AtomicInteger();
    rows.forEach(row -> {
        try {
            JDBCUtils.setRecordToStatement(statement, fieldTypes, row);
            int i = statement.executeUpdate();
            if (i <= 0) {
                throw new RuntimeException("执行executeUpdate失败,影响" + i + "行");
            }
            connection.commit();
            success.getAndAdd(i);
        } catch (Exception e) {
            try {
                //                    connection.rollback();
                connection.commit();
            } catch (SQLException e1) {
                throw new RuntimeException(e1);
            }
            failed.getAndIncrement();
            LOG.error("Insert failed , data: {{}}", row);
            LOG.error("", e);
        }
    });
    long s = System.currentTimeMillis() - start;
    LOG.info("execute update 完成,共{}条,成功入库{}条,失败{}条,用时{}ms", rows.size(), success.get(), failed.get(), s);
    rows.clear();
}

我记得 JVM 会某些异常类型在大量重复下会修改返回异常(该异常对象无 messsage 和 stack),仅保留前面的堆栈报错信息,后面的就没了。
参考:https://www.51cto.com/article/658494.html
因此考虑重启一下,然后看下是什么报错吧。
也可以看看 TiDB DashBoard 观察下有没有一些异常 SQL,或者看日志相关的插入 SQL 是否进来

1、可以去查看下tidb.log 里面尝试去找一些信息
2、如果jdbc 这一侧没有返回信息,去tidb 里面手动这些这些语句,看是否报错

该主题在最后一个回复创建后60天后自动关闭。不再允许新的回复。