[CONJ-759] Connections sometimes don't respect setCatalog Created: 2020-02-03  Updated: 2020-03-06  Resolved: 2020-03-06

Status: Closed
Project: MariaDB Connector/J
Component/s: aurora, Failover
Affects Version/s: 2.4.4, 2.5.4
Fix Version/s: 2.6.0

Type: Bug Priority: Major
Reporter: Jared Stehler Assignee: Diego Dupin
Resolution: Fixed Votes: 0
Labels: None
Environment:

AWS Aurora RDS with 1 replica



 Description   

We have a multi-tenant DataSource implementation, which wraps HikariCP pools and calls setCatalog on connect, like so:

@Override
public Connection getConnection() throws SQLException {
  DataSource ds = getHikariDs(...);
  Connection conn = ds.getConnection();
  conn.setCatalog(...);
  return conn;
}

What I'm seeing is sporadic SQL errors indicating a connection is using the default database (from the url) and not the one specified in setCatalog. In debugging, I see that the connection with the error is different than the one created, leading me to think it's an issue with secondary protocol. This seems to happen with Spring MVC controller methods marked as @Transactional(readOnly=true).

I found in reading the source a questionable condition which potentially might be leading to this issue, in MastersSlavesListener:: lockAndSwitchSecondary(): https://github.com/mariadb-corporation/mariadb-connector-j/blob/master/src/main/java/org/mariadb/jdbc/internal/failover/impl/MastersSlavesListener.java#L648

    // if asked to be on read only connection, switching to this new connection
    if (currentReadOnlyAsked
        || (urlParser.getOptions().failOnReadOnly && !currentReadOnlyAsked && isMasterHostFail())) {
>>>      if (currentProtocol == null) {    <<<
        try {
          syncConnection(currentProtocol, newSecondaryProtocol);
        } catch (Exception e) {
          // Some error append during connection parameter synchronisation
        }
      }
      currentProtocol = newSecondaryProtocol;

I am thinking that line should rather be " if (currentProtocol != null) ", so that the syncConnection() call can properly copy the database into the newSecondaryProtocol?



 Comments   
Comment by Jared Stehler [ 2020-02-03 ]

Further, I see similar logic in lockAndSwitchMaster(), but with the != condition:

  public void lockAndSwitchMaster(Protocol newMasterProtocol)
      throws ReconnectDuringTransactionException {
    if (masterProtocol != null && !masterProtocol.isClosed()) {
      masterProtocol.close();
    }
 
    if (!currentReadOnlyAsked || isSecondaryHostFail()) {
      // actually on a secondary read-only because master was unknown.
      // So select master as currentConnection
>>>      if (currentProtocol != null) {     <<<
        try {
          syncConnection(currentProtocol, newMasterProtocol);
        } catch (Exception e) {
          // Some error append during connection parameter synchronisation
        }

Comment by Diego Dupin [ 2020-03-06 ]

done by this PR from reporter (jared stehler)

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