db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r1129769 - in /db/derby/code/branches/10.8: ./ java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java
Date Tue, 31 May 2011 16:02:52 GMT
Author: dag
Date: Tue May 31 16:02:51 2011
New Revision: 1129769

URL: http://svn.apache.org/viewvc?rev=1129769&view=rev
Log:
DERBY-5233 Interrupt of create table or index (i.e. a container) will throw XSDF1 under NIO
- connection survives

Backported cleanly from trunk as:

svn merge -c 1129764 https://svn.apache.org/repos/asf/db/derby/code/trunk

Patch DERBY-5233-2: The patch makes RAFContainer, when seeing an
interrupt exception during container creation, close it down and try
again, up to MAX_INTERRUPT_RETRIES times. Since RAFContainer should
work also under CDC/Foundation 1.1, the exceptions are checked using
reflection (NIO classes are excluded there).

I also adds a new test case to InterruptResilienceTest:
testCreateDropInterrupted.


Modified:
    db/derby/code/branches/10.8/   (props changed)
    db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
    db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java

Propchange: db/derby/code/branches/10.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 31 16:02:51 2011
@@ -1,2 +1,2 @@
 /db/derby/code/branches/10.7:1061570,1061578,1082235
-/db/derby/code/trunk:1063809,1088633,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1096741,1096890,1097247,1097249,1097460,1097469,1097471,1102826,1103681,1103718,1127825,1129136
+/db/derby/code/trunk:1063809,1088633,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1096741,1096890,1097247,1097249,1097460,1097469,1097471,1102826,1103681,1103718,1127825,1129136,1129764

Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java?rev=1129769&r1=1129768&r2=1129769&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
(original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
Tue May 31 16:02:51 2011
@@ -1344,67 +1344,93 @@ class RAFContainer extends FileContainer
                  throw StandardException.newException( SQLState.FILE_CREATE, se, file);
              }
 
-             try {
+             boolean success = false;
+             int maxTries = MAX_INTERRUPT_RETRIES;
+             while (!success) {
+                 success = true;
 
-                 // OK not to force WAL here, in fact, this operation preceeds the
-                 // creation of the log record to ensure sufficient space.
+                 try {
 
-                 dataFactory.writeInProgress();
-                 try
-                 {
-                     fileData = file.getRandomAccessFile( "rw");
-                 }
-                 finally
-                 {
-                     dataFactory.writeFinished();
-                 }
+                     // OK not to force WAL here, in fact, this operation
+                     // preceeds the creation of the log record to ensure
+                     // sufficient space.
 
-                 // This container format specifies that the first page is an
-                 // allocation page and the container information is stored 
-                 // within it.  The allocation page needs to be somewhat 
-                 // formatted because if the system crashed after the create 
-                 // container log operation is written, it needs to be well 
-                 // formed enough to get the container information back out of
-                 // it.
-                 //
-                 // Don't try to go thru the page cache here because the 
-                 // container object cannot be found in the container cache at
-                 // this point yet.  However, if we use the page cache to store
-                 // the first allocation page, then in order to write itself 
-                 // out, it needs to ask the container to do so, which is going
-                 // to create a deadlock.  The allocation page cannot write 
-                 // itself out without going thru the container because it 
-                 // doesn't know where its offset is.  Here we effectively 
-                 // hardwire page 0 at offset 0 of the container file to be 
-                 // the first allocation page.
-
-                 // create an embryonic page - if this is not a temporary 
-                 // container, synchronously write out the file header.
-                 writeRAFHeader(
-                     actionIdentity, fileData, true, 
-                     (actionIdentity.getSegmentId() != 
+                     dataFactory.writeInProgress();
+                     try
+                     {
+                         fileData = file.getRandomAccessFile( "rw");
+                     }
+                     finally
+                     {
+                         dataFactory.writeFinished();
+                     }
+
+                     // This container format specifies that the first page is
+                     // an allocation page and the container information is
+                     // stored within it.  The allocation page needs to be
+                     // somewhat formatted because if the system crashed after
+                     // the create container log operation is written, it needs
+                     // to be well formed enough to get the container
+                     // information back out of it.
+                     //
+                     // Don't try to go thru the page cache here because the
+                     // container object cannot be found in the container cache
+                     // at this point yet.  However, if we use the page cache
+                     // to store the first allocation page, then in order to
+                     // write itself out, it needs to ask the container to do
+                     // so, which is going to create a deadlock.  The
+                     // allocation page cannot write itself out without going
+                     // thru the container because it doesn't know where its
+                     // offset is.  Here we effectively hardwire page 0 at
+                     // offset 0 of the container file to be the first
+                     // allocation page.
+
+                     // create an embryonic page - if this is not a temporary
+                     // container, synchronously write out the file header.
+                     writeRAFHeader(
+                         actionIdentity, fileData, true,
+                         (actionIdentity.getSegmentId() !=
                           ContainerHandle.TEMPORARY_SEGMENT));
 
-             } catch (SecurityException se) {
+                 } catch (IOException ioe) {
+                     Class clazz = ioe.getClass();
 
-                 // only thrown by the RandomeAccessFile constructor,
-                 // so the file won't exist
-                 throw StandardException.newException( SQLState.FILE_CREATE, se, file);
+                     // test with reflection since NIO is not in Foundation 1.1
+                     if (clazz.getName().equals(
+                             "java.nio.channels.ClosedByInterruptException") ||
+                         clazz.getName().equals( // Java NIO Bug 6979009:
+                             "java.nio.channels.AsynchronousCloseException")) {
+
+                         if (--maxTries > 0) {
+                             success = false;
+                             InterruptStatus.setInterrupted();
+                             closeContainer();
+                             continue;
+                         }
+                     }
 
-             } catch (IOException ioe) {
+                     boolean fileDeleted;
+                     try {
+                         fileDeleted = privRemoveFile(file);
+                     } catch (SecurityException se) {
+                         throw StandardException.newException(
+                             SQLState.FILE_CREATE_NO_CLEANUP,
+                             ioe,
+                             file,
+                             se.toString());
+                     }
 
-                 boolean fileDeleted;
-                 try {
-                     fileDeleted = privRemoveFile(file);
-                 } catch (SecurityException se) {
-                     throw StandardException.newException( SQLState.FILE_CREATE_NO_CLEANUP,
ioe, file, se.toString());
-                 }
+                     if (!fileDeleted) {
+                         throw StandardException.newException(
+                             SQLState.FILE_CREATE_NO_CLEANUP,
+                             ioe,
+                             file,
+                             ioe.toString());
+                     }
 
-                 if (!fileDeleted) {
-                     throw StandardException.newException( SQLState.FILE_CREATE_NO_CLEANUP,
ioe, file, ioe.toString());
+                     throw StandardException.newException(
+                         SQLState.FILE_CREATE, ioe, file);
                  }
-
-                 throw StandardException.newException( SQLState.FILE_CREATE, ioe, file);
              }
 
              canUpdate = true;

Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java?rev=1129769&r1=1129768&r2=1129769&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java
(original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java
Tue May 31 16:02:51 2011
@@ -662,9 +662,39 @@ public class InterruptResilienceTest ext
 
             TestConfiguration.getCurrent().shutdownDatabase();
 
-            // Assert and clear thread's flag:
+            // Assert thread's flag:
             // DERBY-5152: Fails before fix due to lcc going away.
-            assertTrue(Thread.interrupted());
+            assertTrue(Thread.currentThread().isInterrupted());
+
+        } finally {
+            Thread.interrupted(); // clear flag
+        }
+    }
+
+    /**
+     * DERBY-5233: verify that CREATE TABLE (i.e. container creation) survives
+     * interrupts with NIO.
+     */
+    public void testCreateDropInterrupted() throws SQLException {
+
+        if (!usingEmbedded()) {
+            // Only meaningful for embedded.
+            return;
+        }
+
+        setAutoCommit(false);
+
+        Statement s = createStatement();
+
+        try {
+            Thread.currentThread().interrupt();
+
+            s.executeUpdate("create table foo (i int)");
+            s.executeUpdate("insert into foo values 1");
+            s.executeUpdate("drop table foo");
+
+            // Assert thread's flag:
+            assertTrue(Thread.currentThread().isInterrupted());
 
         } finally {
             Thread.interrupted(); // clear flag



Mime
View raw message