Uploaded image for project: 'Fedora Repository Project'
  1. Fedora Repository Project
  2. FCREPO-1213

ConnectionPool may spuriously set database connections to read-only

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Ready for Test
    • Affects Version/s: Fedora 3.x trunk, Fedora 3.6.2, Fedora 3.7.1
    • Fix Version/s: Fedora 3.8.0
    • Component/s: legacy - Fedora
    • Labels:
      None

      Description

      When releasing a connection from the SQL connection pool, and SQL exception may cause the connection to never be read/write again.

      The offending code is in org.fcrepo.server.storage.ConnectionPool where this method is:
      {code}
          private void setConnectionReadOnly(Connection connection, boolean readOnly) {
              if (supportsReadOnly) {
                  try {
                      connection.setReadOnly(readOnly);
                  } catch (Throwable th) {
                      logger.info("Read-only connections not supported (" + th.getMessage() + ")");
                      supportsReadOnly = false;
                  }
              }
          }
      {code}

      Note that on any exception it is never tried again to change the mode of the connection. And since the default is that connections are read only in the pool, the connection will never again be read/write.
      The log message is erronous too, it seems to claim that the problem is in setting a connection read only, but it might as well be in setting it read write.

      This may happen in a real world scenario, where the exception you try to set to readWrite or readOnly is closed. You will get an exception with "connection is closed". You will have this scenario if you call free twice:
      {code}
          public void free(Connection connection) {
              try {
                  // ensure connections returned to pool as read-only
                  setConnectionReadOnly(connection, true);
                  if (!connection.isClosed()) connection.close();
              } catch (SQLException sqle) {
                  logger.warn("Unable to close connection", sqle);
              } finally {
                  if (logger.isDebugEnabled()) {
                      logger.debug("Returned connection to pool (" + toString() + ")");
                  }
              }
          }
      {code}
      because free tries to set the connection to readOnly.

      We think this happens if an SQL query is expired, while still delivering data. The connection will then be freed twice: First when expired, second when the result is finally ready.

      We have had this situation happen to us twice in 24 hours, and it makes Fedora unwritable but responsive to reads.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                barmintor Benjamin Armintor
                Reporter:
                kfc@statsbiblioteket.dk Kåre Fiedler Christiansen
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: