Uploaded image for project: 'Derby'
  1. Derby
  2. DERBY-4960

Race condition in FileContainer#allocCache when reopening RAFContainer after interrupt

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 10.8.1.2
    • Fix Version/s: 10.8.1.2
    • Component/s: Store
    • Labels:
      None

      Description

      The symptom is an ArrayIndexOutOfBoundsException:

      java.lang.ArrayIndexOutOfBoundsException: -1
      at org.apache.derby.impl.store.raw.data.AllocationCache.validate(AllocationCache.java:581)
      at org.apache.derby.impl.store.raw.data.AllocationCache.getLastPageNumber(AllocationCache.java:122)
      at org.apache.derby.impl.store.raw.data.FileContainer.pageValid(FileContainer.java:2067)
      at org.apache.derby.impl.store.raw.data.FileContainer.getUserPage(FileContainer.java:2522)
      at org.apache.derby.impl.store.raw.data.FileContainer.getInsertablePage(FileContainer.java:2867)
      at org.apache.derby.impl.store.raw.data.FileContainer.getPageForInsert(FileContainer.java:3017)
      at org.apache.derby.impl.store.raw.data.BaseContainerHandle.getPageForInsert(BaseContainerHandle.java:372)
      at org.apache.derby.impl.store.access.heap.HeapController.doInsert(HeapController.java:244)
      at org.apache.derby.impl.store.access.heap.HeapController.insertAndFetchLocation(HeapController.java:599)
      at org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(RowChangerImpl.java:452)
      at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(InsertResultSet.java:1028)
      at org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:505)
      at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:436)
      at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:317)
      at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1241)
      at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java:1686)
      at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(EmbedPreparedStatement.java:308)
      at InterruptTest$WorkerThread.run(InterruptTest.java:261

      This can only happen if another thread has called allocCache.reset while the thread above is in the loop in validate, so as to set numExtents to 0.
      The synchronization of allocCache is documented in the Javadoc of the FileContainer class: all accesses to allocCache should synchronize.
      This is omitted when we reopen: FileContainer#openContainer calls readHeader -> readHeaderFromArray -> allocCache.reset

        Attachments

        1. derby-4960-2.stat
          0.2 kB
          Dag H. Wanvik
        2. derby-4960-2.diff
          4 kB
          Dag H. Wanvik
        3. derby-4960-1.stat
          0.4 kB
          Dag H. Wanvik
        4. derby-4960-1.diff
          6 kB
          Dag H. Wanvik
        5. InterruptTest.java
          17 kB
          Dag H. Wanvik

          Issue Links

            Activity

              People

              • Assignee:
                dagw Dag H. Wanvik
                Reporter:
                dagw Dag H. Wanvik
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: