How to Troubleshoot JDBC Batch Insert Failure Without Exceptions

Note:
This topic has been translated from a Chinese forum by GPT and might contain errors.

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

| username: dxss-lee

tidb v6.1
Loading into the database through Flink
Inserting data via JDBC batch insert method
The situation is that under normal circumstances, the insert statement returns an array with a size equal to the batch size, and all elements are -2.
However, sometimes it returns an array where each element is -2, but the size is smaller than the batch size. No exceptions are caught by the program, and no anomalies are found in the TiDB logs. Seeking troubleshooting ideas.

| username: Icemap | Original post link

Could you please share the code snippet and table creation statement or the reproduction method?

| username: dxss-lee | Original post link

The table is a very ordinary partitioned table, partitioned by day, with a primary key and an index on the table.

| username: Icemap | Original post link

Is there a pattern to the occurrence of the error? Is there an SQL log when returning a -2 array?

| username: dxss-lee | Original post link

No, you can see the rollback in the monitoring.

| username: dxss-lee | Original post link

There are some messages about inserting into the delete-range table.

| username: Icemap | Original post link

Please provide the reproduction steps. Without detailed information, I can only guess…

| username: dxss-lee | Original post link

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(“The number of records inserted is inconsistent, Rows.size():%d, number of successful executions, length of the int array returned by batch execution: %s”, rows.size(), j));
}
long s = System.currentTimeMillis() - start;
LOG.info(“Batch inserted {} records, took {}ms, actually inserted {} records”, rows.size(), s, j);
rows.clear();
} catch (Exception e) {
LOG.info(“Batch insertion failed, switching to single record insertion…{}, 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 failed, affected " + i + " rows");
            }
            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 completed, total {} records, successfully inserted {} records, failed {} records, took {}ms", rows.size(), success.get(), failed.get(), s);
    rows.clear();
}
| username: ealam_小羽 | Original post link

I remember that the JVM will modify the returned exception for certain types of exceptions under a large number of repetitions (the exception object has no message and stack), retaining only the stack error information from the front, and the latter will be gone.
Reference: https://www.51cto.com/article/658494.html
So consider restarting, and then see what the error is.
You can also check TiDB Dashboard to see if there are any abnormal SQLs, or check the logs to see if the related insert SQLs are coming in.

| username: Raymond | Original post link

  1. You can check the tidb.log to try to find some information.
  2. If there is no information returned on the JDBC side, manually execute these statements in TiDB to see if there are any errors.
| username: system | Original post link

This topic was automatically closed 60 days after the last reply. No new replies are allowed.