You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2011/07/06 13:41:42 UTC
svn commit: r1143356 - in /db/derby/code/branches/10.8: ./
java/engine/org/apache/derby/impl/sql/execute/
java/testing/org/apache/derbyTesting/functionTests/tests/lang/
Author: kahatlen
Date: Wed Jul 6 11:41:41 2011
New Revision: 1143356
URL: http://svn.apache.org/viewvc?rev=1143356&view=rev
Log:
DERBY-4275: Query executions fail when compressing a table using SYSCS_UTIL.SYSCS_COMPRESS_TABLE
Merged fix from trunk (revision 1142583).
Modified:
db/derby/code/branches/10.8/ (props changed)
db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CompressTableTest.java
db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TruncateTableTest.java
Propchange: db/derby/code/branches/10.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jul 6 11:41:41 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,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1125305,1126358,1126468,1127825,1127883,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132860,1132928,1133304,1133317,1133741,1133752,1136363,1136371,1136397,1136844,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1141924,1142635
+/db/derby/code/trunk:1063809,1088633,1091000,1091221,1091285,1092067,1092795,1094315,1094572,1094728,1096741,1096890,1097247,1097249,1097460,1097469,1097471,1101059,1101839,1102620,1102826,1103681,1103718,1103742,1125305,1126358,1126468,1127825,1127883,1129136,1129764,1129797,1130077,1130084,1130632,1130895,1131030,1131272,1132546,1132664,1132860,1132928,1133304,1133317,1133741,1133752,1136363,1136371,1136397,1136844,1138201,1138341,1138444,1138787,1138795,1139449,1139451,1141924,1142583,1142635
Modified: db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java?rev=1143356&r1=1143355&r2=1143356&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java (original)
+++ db/derby/code/branches/10.8/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java Wed Jul 6 11:41:41 2011
@@ -388,7 +388,7 @@ class AlterTableConstantAction extends D
sd = getAndCheckSchemaDescriptor(dd, schemaId, "ALTER TABLE");
}
- /* Prepare all dependents to invalidate. (This is there chance
+ /* Prepare all dependents to invalidate. (This is their chance
* to say that they can't be invalidated. For example, an open
* cursor referencing a table/view that the user is attempting to
* alter.) If no one objects, then invalidate any dependent objects.
@@ -2090,14 +2090,6 @@ class AlterTableConstantAction extends D
TransactionController.MODE_TABLE,
TransactionController.ISOLATION_SERIALIZABLE);
- // invalidate any prepared statements that depended on this table
- // (including this one), this fixes problem with threads that start up
- // and block on our lock, but do not see they have to recompile their
- // plan. We now invalidate earlier however they still might recompile
- // using the old conglomerate id before we commit our DD changes.
- //
- dm.invalidateFor(td, DependencyManager.COMPRESS_TABLE, lcc);
-
rl = compressHeapCC.newRowLocationTemplate();
// Get the properties on the old heap
@@ -2221,6 +2213,10 @@ class AlterTableConstantAction extends D
// Update sys.sysconglomerates with new conglomerate #
dd.updateConglomerateDescriptor(cd, newHeapConglom, tc);
+ // Now that the updated information is available in the system tables,
+ // we should invalidate all statements that use the old conglomerates
+ dm.invalidateFor(td, DependencyManager.COMPRESS_TABLE, lcc);
+
// Drop the old conglomerate
tc.dropConglomerate(oldHeapConglom);
cleanUp();
@@ -2305,15 +2301,6 @@ class AlterTableConstantAction extends D
TransactionController.MODE_TABLE,
TransactionController.ISOLATION_SERIALIZABLE);
- // invalidate any prepared statements that
- // depended on this table (including this one)
- // bug 3653 has threads that start up and block on our lock, but do
- // not see they have to recompile their plan. We now invalidate earlier
- // however they still might recompile using the old conglomerate id before we
- // commit our DD changes.
- //
- dm.invalidateFor(td, DependencyManager.TRUNCATE_TABLE, lcc);
-
rl = compressHeapCC.newRowLocationTemplate();
// Get the properties on the old heap
compressHeapCC.getInternalTablePropertySet(properties);
@@ -2399,6 +2386,11 @@ class AlterTableConstantAction extends D
// Update sys.sysconglomerates with new conglomerate #
dd.updateConglomerateDescriptor(cd, newHeapConglom, tc);
+
+ // Now that the updated information is available in the system tables,
+ // we should invalidate all statements that use the old conglomerates
+ dm.invalidateFor(td, DependencyManager.TRUNCATE_TABLE, lcc);
+
// Drop the old conglomerate
tc.dropConglomerate(oldHeapConglom);
cleanUp();
Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CompressTableTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CompressTableTest.java?rev=1143356&r1=1143355&r2=1143356&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CompressTableTest.java (original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CompressTableTest.java Wed Jul 6 11:41:41 2011
@@ -21,10 +21,17 @@ limitations under the License.
package org.apache.derbyTesting.functionTests.tests.lang;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import junit.framework.Test;
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+import org.apache.derbyTesting.junit.JDBC;
import org.apache.derbyTesting.junit.TestConfiguration;
/**
@@ -38,7 +45,8 @@ public class CompressTableTest extends B
public static Test suite() {
// compress table is an embedded feature, no need to run network tests
- return TestConfiguration.embeddedSuite(CompressTableTest.class);
+ return new CleanDatabaseTestSetup(
+ TestConfiguration.embeddedSuite(CompressTableTest.class));
}
/**
@@ -54,4 +62,67 @@ public class CompressTableTest extends B
"'abc\"def', 1, 1, 1)");
s.execute("drop table app.\"abc\"\"def\"");
}
+
+ /**
+ * Test that statement invalidation works when SYSCS_COMPRESS_TABLE calls
+ * and other statements accessing the same table execute concurrently.
+ * DERBY-4275.
+ */
+ public void testConcurrentInvalidation() throws Exception {
+ Statement s = createStatement();
+ s.execute("create table d4275(x int)");
+ s.execute("insert into d4275 values 1");
+
+ // Object used by the main thread to tell the helper thread to stop.
+ // The helper thread stops once the list is non-empty.
+ final List stop = Collections.synchronizedList(new ArrayList());
+
+ // Holder for anything thrown by the run() method in the helper thread.
+ final Throwable[] error = new Throwable[1];
+
+ // Set up a helper thread that executes a query against the table
+ // until the main thread tells it to stop.
+ Connection c2 = openDefaultConnection();
+ final PreparedStatement ps = c2.prepareStatement("select * from d4275");
+
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ while (stop.isEmpty()) {
+ JDBC.assertSingleValueResultSet(ps.executeQuery(), "1");
+ }
+ } catch (Throwable t) {
+ error[0] = t;
+ }
+ }
+ };
+
+ t.start();
+
+ // Compress the table while a query is being executed against the
+ // same table to force invalidation of the running statement. Since
+ // the problem we try to reproduce is timing-dependent, do it 100
+ // times to increase the chance of hitting the bug.
+ try {
+ for (int i = 0; i < 100; i++) {
+ s.execute(
+ "call syscs_util.syscs_compress_table('APP', 'D4275', 1)");
+ }
+ } finally {
+ // We're done, so tell the helper thread to stop.
+ stop.add(Boolean.TRUE);
+ }
+
+ t.join();
+
+ // Before DERBY-4275, the helper thread used to fail with an error
+ // saying the container was not found.
+ if (error[0] != null) {
+ fail("Helper thread failed", error[0]);
+ }
+
+ // Cleanup.
+ ps.close();
+ c2.close();
+ }
}
Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TruncateTableTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TruncateTableTest.java?rev=1143356&r1=1143355&r2=1143356&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TruncateTableTest.java (original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TruncateTableTest.java Wed Jul 6 11:41:41 2011
@@ -26,6 +26,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import junit.framework.Test;
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
@@ -300,4 +303,64 @@ public class TruncateTableTest extends B
truncatorStatement.close();
}
+ /**
+ * Test that statement invalidation works when TRUNCATE TABLE statements
+ * and other statements accessing the same table execute concurrently.
+ * DERBY-4275.
+ */
+ public void testConcurrentInvalidation() throws Exception {
+ Statement s = createStatement();
+ s.execute("create table d4275(x int)");
+
+ // Object used by the main thread to tell the helper thread to stop.
+ // The helper thread stops once the list is non-empty.
+ final List stop = Collections.synchronizedList(new ArrayList());
+
+ // Holder for anything thrown by the run() method in the helper thread.
+ final Throwable[] error = new Throwable[1];
+
+ // Set up a helper thread that executes a query against the table
+ // until the main thread tells it to stop.
+ Connection c2 = openDefaultConnection();
+ final PreparedStatement ps = c2.prepareStatement("select * from d4275");
+
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ while (stop.isEmpty()) {
+ JDBC.assertEmpty(ps.executeQuery());
+ }
+ } catch (Throwable t) {
+ error[0] = t;
+ }
+ }
+ };
+
+ t.start();
+
+ // Truncate the table while a query is being executed against the
+ // same table to force invalidation of the running statement. Since
+ // the problem we try to reproduce is timing-dependent, do it 100
+ // times to increase the chance of hitting the bug.
+ try {
+ for (int i = 0; i < 100; i++) {
+ s.execute("truncate table d4275");
+ }
+ } finally {
+ // We're done, so tell the helper thread to stop.
+ stop.add(Boolean.TRUE);
+ }
+
+ t.join();
+
+ // Before DERBY-4275, the helper thread used to fail with an error
+ // saying the container was not found.
+ if (error[0] != null) {
+ fail("Helper thread failed", error[0]);
+ }
+
+ // Cleanup.
+ ps.close();
+ c2.close();
+ }
}