[CONJ-873] IndexOutOfBoundsException when executing prepared queries using automatic key generation in parallel Created: 2021-04-20  Updated: 2021-07-29  Resolved: 2021-05-17

Status: Closed
Project: MariaDB Connector/J
Component/s: Other
Affects Version/s: 2.7.2
Fix Version/s: 2.7.4

Type: Bug Priority: Major
Reporter: Tobias Riemenschneider Assignee: Diego Dupin
Resolution: Fixed Votes: 0
Labels: None

Attachments: File ddl.sql     Zip Archive test.zip    

 Description   

We found an issue when executing prepared queries using automatic key generation in parallel. It occurs when accessing a MySQL database (tested with 8.0.16, 5.7.26 and 5.6.50) via MariaDB Connector/J (2.7.2). When executing the following piece of code multiple times in parallel:

try (
    Connection connection = DriverManager.getConnection("jdbc:mysql://ensembldb.ensembl.org:3306?pool=true&minPoolSize=1&maxPoolSize=5&maxIdleTime=60", "anonymous", "");
    PreparedStatement statement = connection.prepareStatement("SELECT * FROM acanthochromis_polyacanthus_core_100_1.analysis WHERE analysis_id = ?", Statement.RETURN_GENERATED_KEYS)
) {
    statement.setInt(1, 5);
    try (ResultSet result = statement.executeQuery()) {
        try (ResultSet keys = statement.getGeneratedKeys()) {
            ResultSetMetaData metadata = keys.getMetaData();
            int cols = metadata.getColumnCount();
            for (int i = 1; i <= cols; i++)
                metadata.getColumnLabel(i);
        }
    }
}

we see the following exceptions:

java.lang.ArrayIndexOutOfBoundsException: 38
	at org.mariadb.jdbc.internal.com.read.Buffer.skipLengthEncodedBytes(Buffer.java:228)
	at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getString(ColumnDefinition.java:225)
	at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getName(ColumnDefinition.java:243)
	at org.mariadb.jdbc.MariaDbResultSetMetaData.getColumnLabel(MariaDbResultSetMetaData.java:154)
	at MariaDBConnectionPool.executeQuery(MariaDBConnectionPool.java:30)
	[...]

java.lang.StringIndexOutOfBoundsException: String index out of range: 121
	at java.lang.String.checkBounds(String.java:385)
	at java.lang.String.<init>(String.java:462)
	at org.mariadb.jdbc.internal.com.read.Buffer.readStringLengthEncoded(Buffer.java:123)
	at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getString(ColumnDefinition.java:227)
	at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getName(ColumnDefinition.java:243)
	at org.mariadb.jdbc.MariaDbResultSetMetaData.getColumnLabel(MariaDbResultSetMetaData.java:154)
	at MariaDBConnectionPool.executeQuery(MariaDBConnectionPool.java:30)
	[...]

A reproducer can be found at https://github.com/riemenschneider/JDBCPoolUsingMariaDBDriverTest. It contains the relevant test:

  • MariaDBConnectionPool: using the connection pooling provided by MariaDB Connector/J for running 1000 prepared queries in parallel.

Ignore the remaining tests. These were just used for tracking the issue down to MariaDB Connector/J.

Steps to reproduce:

  1. Clone the reproducer.
  2. Run gradlew clean test --tests MariaDBConnectionPool in the root folder of the cloned reproducer.


 Comments   
Comment by Diego Dupin [ 2021-05-17 ]

I've try to reproduced the issue without success.
Could you give the DDL of acanthochromis_polyacanthus_core_100_1.analysis table ?

Comment by Tobias Riemenschneider [ 2021-05-17 ]

Hm, that's strange. If I run the reproducer I get the following output:

C:\Users\tori\code\github\riemenschneider\JDBCPoolUsingMariaDBDriverTest>gradlew clean test --tests MariaDBConnectionPool
Starting a Gradle Daemon (subsequent builds will be faster)
 
> Task :test
 
MariaDBConnectionPool > repetition 2 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 9 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 1 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 17 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 20 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 35 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 33 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 45 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 57 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 59 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 75 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 74 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 80 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 135 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 134 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 142 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 147 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 152 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 157 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 187 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 173 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 177 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 179 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 178 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 174 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 180 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 182 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 188 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 197 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 196 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 207 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 217 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 222 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 236 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 227 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 247 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 282 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 338 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 334 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 333 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 335 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 353 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 339 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 345 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 349 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 360 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 393 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 387 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 413 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 443 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 434 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 439 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 513 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 520 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 522 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 526 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 547 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 552 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 554 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 557 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 560 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 564 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 689 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 692 of 1000 FAILED
    java.lang.ArrayIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 695 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 705 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 786 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
MariaDBConnectionPool > repetition 790 of 1000 FAILED
    java.lang.StringIndexOutOfBoundsException at MariaDBConnectionPool.java:30
 
1000 tests completed, 68 failed
 
> Task :test FAILED
 
FAILURE: Build failed with an exception.
 
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///C:/Users/tori/code/github/riemenschneider/JDBCPoolUsingMariaDBDriverTest/build/reports/tests/test/index.html
 
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
 
* Get more help at https://help.gradle.org
 
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8/userguide/command_line_interface.html#sec:command_line_warnings
 
BUILD FAILED in 12s
4 actionable tasks: 4 executed

I have attached the test report (test.zip) as well as the DDL for the test table (ddl.sql). It is just a free-to-use MySQL database since I need some MySQL database for the reproducer. In our test suite we are using MySQL databases hosted on Linux VMs as well as containerized MySQL databases.

Comment by Diego Dupin [ 2021-05-17 ]

issue identified.
When command return no getGeneratedKeys driver return an empty static resultset.
Problem is that the shared buffer position can changed if used simultaneously, resulting with those errors

Generated at Thu Feb 08 03:18:56 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.