Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2012-11-06 07:51:42 +0000
committerEike Stepper2012-11-06 07:51:42 +0000
commitaa797f40e69af58abc6740706486290514e19de0 (patch)
treecebea7daf61be578624b3ae6709c1d5b6dc8257c
parent16b7f6ba4c45b827bfffc9c86f70ea71dce61d8e (diff)
downloadcdo-aa797f40e69af58abc6740706486290514e19de0.tar.gz
cdo-aa797f40e69af58abc6740706486290514e19de0.tar.xz
cdo-aa797f40e69af58abc6740706486290514e19de0.zip
[364809] DBStore with Postgres fail to recover from crash
https://bugs.eclipse.org/bugs/show_bug.cgi?id=364809
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java59
-rw-r--r--plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java77
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java10
-rw-r--r--plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java17
4 files changed, 101 insertions, 62 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
index 0484959a21..ccada761dc 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
@@ -98,10 +98,6 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
private static final String PROP_GRACEFULLY_SHUT_DOWN = "org.eclipse.emf.cdo.server.db.gracefullyShutDown"; //$NON-NLS-1$
- private static final String TABLE_NOT_FOUND = "42S02";
-
- private static final String COLUMN_NOT_FOUND = "42S22";
-
private long creationTime;
private boolean firstTime;
@@ -276,7 +272,7 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
throw new DBException(ex1);
}
- if (!COLUMN_NOT_FOUND.equalsIgnoreCase(ex.getSQLState()))
+ if (!dbAdapter.isColumnNotFoundException(ex))
{
throw new DBException(ex);
}
@@ -822,7 +818,7 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
}
catch (SQLException ex)
{
- if (TABLE_NOT_FOUND.equals(ex.getSQLState()))
+ if (dbAdapter.isTableNotFoundException(ex))
{
return FIRST_START;
}
@@ -839,12 +835,10 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
protected void migrateSchema(int fromVersion) throws Exception
{
Connection connection = null;
- Statement statement = null;
try
{
connection = getConnection();
- statement = connection.createStatement();
for (int version = fromVersion; version < SCHEMA_VERSION; version++)
{
@@ -852,7 +846,7 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
{
int nextVersion = version + 1;
OM.LOG.info("Migrating schema from version " + version + " to version " + nextVersion + "...");
- SCHEMA_MIGRATORS[version].migrateSchema(this, statement);
+ SCHEMA_MIGRATORS[version].migrateSchema(this, connection);
}
}
@@ -860,7 +854,6 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
}
finally
{
- DBUtil.close(statement);
DBUtil.close(connection);
}
}
@@ -870,7 +863,7 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
*/
private static abstract class SchemaMigrator
{
- public abstract void migrateSchema(DBStore store, Statement statement) throws Exception;
+ public abstract void migrateSchema(DBStore store, Connection connection) throws Exception;
}
private static final SchemaMigrator NO_MIGRATION_NEEDED = null;
@@ -878,22 +871,33 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
private static final SchemaMigrator NON_AUDIT_MIGRATION = new SchemaMigrator()
{
@Override
- public void migrateSchema(DBStore store, final Statement statement) throws Exception
+ public void migrateSchema(DBStore store, Connection connection) throws Exception
{
InternalRepository repository = store.getRepository();
if (!repository.isSupportingAudits())
{
- store.visitAllTables(statement.getConnection(), new IDBStore.TableVisitor()
+ store.visitAllTables(connection, new IDBStore.TableVisitor()
{
public void visitTable(Connection connection, String name) throws SQLException
{
- String from = " FROM " + name + " WHERE " + CDODBSchema.ATTRIBUTES_VERSION + "<"
- + CDOBranchVersion.FIRST_VERSION;
+ Statement statement = null;
- statement.executeUpdate("DELETE FROM " + CDODBSchema.CDO_OBJECTS + " WHERE " + CDODBSchema.ATTRIBUTES_ID
- + " IN (SELECT " + CDODBSchema.ATTRIBUTES_ID + from + ")");
+ try
+ {
+ statement = connection.createStatement();
+
+ String from = " FROM " + name + " WHERE " + CDODBSchema.ATTRIBUTES_VERSION + "<"
+ + CDOBranchVersion.FIRST_VERSION;
- statement.executeUpdate("DELETE" + from);
+ statement.executeUpdate("DELETE FROM " + CDODBSchema.CDO_OBJECTS + " WHERE " + CDODBSchema.ATTRIBUTES_ID
+ + " IN (SELECT " + CDODBSchema.ATTRIBUTES_ID + from + ")");
+
+ statement.executeUpdate("DELETE" + from);
+ }
+ finally
+ {
+ DBUtil.close(statement);
+ }
}
});
}
@@ -903,11 +907,22 @@ public class DBStore extends Store implements IDBStore, CDOAllRevisionsProvider
private static final SchemaMigrator LOB_SIZE_MIGRATION = new SchemaMigrator()
{
@Override
- public void migrateSchema(DBStore store, final Statement statement) throws Exception
+ public void migrateSchema(DBStore store, final Connection connection) throws Exception
{
- IDBAdapter dbAdapter = store.getDBAdapter();
- String sql = dbAdapter.sqlRenameField(CDODBSchema.LOBS_SIZE, "size");
- statement.execute(sql);
+ Statement statement = null;
+
+ try
+ {
+ statement = connection.createStatement();
+
+ IDBAdapter dbAdapter = store.getDBAdapter();
+ String sql = dbAdapter.sqlRenameField(CDODBSchema.LOBS_SIZE, "size");
+ statement.execute(sql);
+ }
+ finally
+ {
+ DBUtil.close(statement);
+ }
}
};
diff --git a/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java b/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java
index 3ff7c75a9e..43614e8225 100644
--- a/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java
+++ b/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java
@@ -13,14 +13,12 @@
*/
package org.eclipse.net4j.db.postgresql;
-import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.IDBAdapter;
import org.eclipse.net4j.db.ddl.IDBField;
import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.db.internal.postgresql.bundle.OM;
import org.eclipse.net4j.spi.db.DBAdapter;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.postgresql.ds.PGSimpleDataSource;
@@ -42,7 +40,7 @@ public class PostgreSQLAdapter extends DBAdapter
public static final String VERSION = "9.0"; //$NON-NLS-1$
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SQL, DBAdapter.class);
+ // private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SQL, DBAdapter.class);
private static final String[] RESERVED_WORDS = { "ALL", "ANALYSE", "ANALYZE", "AND", "ANY", "AS", "ASC", "ATOMIC", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
"AUTHORIZATION", "BETWEEN", "BIGINT", "BINARY", "BIT", "BOOLEAN", "BOTH", "C", "CASE", "CAST", "CHAR", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$
@@ -117,57 +115,58 @@ public class PostgreSQLAdapter extends DBAdapter
return RESERVED_WORDS;
}
- /*
- * TODO Remove this method override after fixing Bug 282791 - [DB] Check for existing tables instead of relying on
- * SQLExceptions PostgreSQL uses transaction on DDL operations. If an error occurs, the SQL Connection goes to an
- * error state, and can only be cleared by rolling back. Therefore, savepoints for table creation were added
+ /**
+ * See <a href="http://www.postgresql.org/docs/9.0/static/errcodes-appendix.html">Appendix A. PostgreSQL Error Codes</a>.
*/
@Override
- public boolean createTable(IDBTable table, Statement statement) throws DBException
+ public boolean isDuplicateKeyException(SQLException ex)
{
- boolean created = true;
- Savepoint savepoint = null;
+ // RESTRICT VIOLATION || UNIQUE VIOLATION
+ return super.isDuplicateKeyException(ex) || "23505".equals(ex.getSQLState());
+ }
- try
- {
- savepoint = statement.getConnection().setSavepoint();
- }
- catch (SQLException ex)
- {
- OM.LOG.error(ex);
- }
+ /**
+ * See <a href="http://www.postgresql.org/docs/9.0/static/errcodes-appendix.html">Appendix A. PostgreSQL Error Codes</a>.
+ */
+ @Override
+ public boolean isTableNotFoundException(SQLException ex)
+ {
+ // UNDEFINED TABLE
+ return "42P01".equals(ex.getSQLState());
+ }
+
+ /**
+ * See <a href="http://www.postgresql.org/docs/9.0/static/errcodes-appendix.html">Appendix A. PostgreSQL Error Codes</a>.
+ */
+ @Override
+ public boolean isColumnNotFoundException(SQLException ex)
+ {
+ // UNDEFINED COLUMN
+ return "42703".equals(ex.getSQLState());
+ }
+
+ @Override
+ protected void doCreateTable(IDBTable table, Statement statement) throws SQLException
+ {
+ Savepoint savepoint = statement.getConnection().setSavepoint();
try
{
- doCreateTable(table, statement);
+ super.doCreateTable(table, statement);
}
catch (SQLException ex)
{
- created = false;
- if (TRACER.isEnabled())
- {
- TRACER.trace("-- " + ex.getMessage() + ". Trying to rollback operation"); //$NON-NLS-1$
- }
-
- if (savepoint != null)
+ try
{
- try
- {
- statement.getConnection().rollback(savepoint);
- }
- catch (SQLException ex1)
- {
- OM.LOG.error(ex1);
- }
+ statement.getConnection().rollback(savepoint);
}
- else
+ catch (SQLException ex1)
{
- OM.LOG.error("Could not rollback last operation. Savepoint was not created."); //$NON-NLS-1$
+ OM.LOG.error(ex1);
}
- }
- validateTable(table, statement);
- return created;
+ throw ex;
+ }
}
@Override
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java
index 5d73ba2e2a..3aaa5a6fcc 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/IDBAdapter.java
@@ -103,5 +103,15 @@ public interface IDBAdapter
/**
* @since 4.2
*/
+ public boolean isTableNotFoundException(SQLException ex);
+
+ /**
+ * @since 4.2
+ */
+ public boolean isColumnNotFoundException(SQLException ex);
+
+ /**
+ * @since 4.2
+ */
public String sqlRenameField(IDBField field, String oldName);
}
diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java
index e1405f1bca..9892e0fbd6 100644
--- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java
+++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/spi/db/DBAdapter.java
@@ -557,13 +557,28 @@ public abstract class DBAdapter implements IDBAdapter
*/
public boolean isDuplicateKeyException(SQLException ex)
{
- /* SQL code for duplicate keys is 23001 */
return "23001".equals(ex.getSQLState());
}
/**
* @since 4.2
*/
+ public boolean isTableNotFoundException(SQLException ex)
+ {
+ return "42S02".equals(ex.getSQLState());
+ }
+
+ /**
+ * @since 4.2
+ */
+ public boolean isColumnNotFoundException(SQLException ex)
+ {
+ return "42S22".equals(ex.getSQLState());
+ }
+
+ /**
+ * @since 4.2
+ */
public String sqlRenameField(IDBField field, String oldName)
{
return "ALTER TABLE " + field.getTable() + " RENAME COLUMN " + oldName + " TO " + field;

Back to the top