diff options
author | Eike Stepper | 2007-10-18 07:56:26 +0000 |
---|---|---|
committer | Eike Stepper | 2007-10-18 07:56:26 +0000 |
commit | 0d6898b6c2715c9f032446e8a1749055eb77d09b (patch) | |
tree | d98f894fb7a0f6837ecd0d82d8e6336901159feb | |
parent | 5a9194bd229c110fce0efd3e02ae91a707a3c4c9 (diff) | |
download | cdo-0d6898b6c2715c9f032446e8a1749055eb77d09b.tar.gz cdo-0d6898b6c2715c9f032446e8a1749055eb77d09b.tar.xz cdo-0d6898b6c2715c9f032446e8a1749055eb77d09b.zip |
[206713] Implement DBStore.repairAfterCrash
https://bugs.eclipse.org/bugs/show_bug.cgi?id=206713
8 files changed, 102 insertions, 19 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMappingStrategy.java index f3d91faf92..4ec0c545c7 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IMappingStrategy.java @@ -16,6 +16,7 @@ import org.eclipse.emf.cdo.protocol.model.CDOClassRef; import org.eclipse.net4j.util.io.CloseableIterator; +import java.sql.Connection; import java.util.Map; /** @@ -48,4 +49,9 @@ public interface IMappingStrategy public CDOID readResourceID(IDBStoreAccessor storeAccessor, String path); public String readResourcePath(IDBStoreAccessor storeAccessor, CDOID id); + + /** + * Must return the next CDOID value to be used for new objects. + */ + public long repairAfterCrash(Connection connection); } 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 366d355566..9745ba307f 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 @@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.server.internal.db; import org.eclipse.emf.cdo.internal.server.Repository; import org.eclipse.emf.cdo.internal.server.Store; +import org.eclipse.emf.cdo.internal.server.StoreUtil; import org.eclipse.emf.cdo.protocol.model.CDOType; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.IView; @@ -31,6 +32,7 @@ import org.eclipse.net4j.internal.db.DBSchema; import org.eclipse.net4j.util.ImplementationError; import java.sql.Connection; +import java.text.MessageFormat; import java.util.Set; /** @@ -193,12 +195,11 @@ public class DBStore extends Store implements IDBStore else { // Restart - - int nextCDOID = DBUtil.selectMaximum(connection, CDODBSchema.REPOSITORY_NEXT_CDOID); - int nextMetaID = DBUtil.selectMaximum(connection, CDODBSchema.REPOSITORY_NEXT_METAID); + int nextCDOID = DBUtil.selectMaximumInt(connection, CDODBSchema.REPOSITORY_NEXT_CDOID); + int nextMetaID = DBUtil.selectMaximumInt(connection, CDODBSchema.REPOSITORY_NEXT_METAID); if (nextCDOID == 0 || nextMetaID == 0) { - repairAfterCrash(repository, connection); + OM.LOG.warn("Detected restart after crash"); } setNextOIDValue(nextCDOID); @@ -231,9 +232,9 @@ public class DBStore extends Store implements IDBStore } } - nextPackageID = DBUtil.selectMaximum(connection, CDODBSchema.PACKAGES_ID) + 1; - nextClassID = DBUtil.selectMaximum(connection, CDODBSchema.CLASSES_ID) + 1; - nextFeatureID = DBUtil.selectMaximum(connection, CDODBSchema.FEATURES_ID) + 1; + nextPackageID = DBUtil.selectMaximumInt(connection, CDODBSchema.PACKAGES_ID) + 1; + nextClassID = DBUtil.selectMaximumInt(connection, CDODBSchema.CLASSES_ID) + 1; + nextFeatureID = DBUtil.selectMaximumInt(connection, CDODBSchema.FEATURES_ID) + 1; } protected void deactivateStore(Repository repository, Connection connection) @@ -262,12 +263,31 @@ public class DBStore extends Store implements IDBStore } } - protected void repairAfterCrash(Repository repository, Connection connection) + public void repairAfterCrash() { - OM.LOG.warn("Detected restart after crash"); + Repository repository = (Repository)getRepository(); + DBStoreAccessor storeReader = getReader(null); + StoreUtil.setReader(storeReader); + + try + { + Connection connection = storeReader.getConnection(); + long nextCDOID = mappingStrategy.repairAfterCrash(connection); + long nextMetaID = DBUtil.selectMaximumLong(connection, CDODBSchema.PACKAGES_RANGE_UB) + 2L; + if (nextMetaID == 2L) + { + nextMetaID = 1L; + } - // TODO repairAfterCrash not yet implemented - OM.LOG.error("repairAfterCrash not yet implemented"); + OM.LOG.info(MessageFormat.format("Repaired after crash: nextCDOID={0}, nextMetaID={1}", nextCDOID, nextMetaID)); + setNextOIDValue(nextCDOID); + repository.setNextMetaIDValue(nextMetaID); + } + finally + { + storeReader.release(); + StoreUtil.setReader(null); + } } protected IDBSchema createSchema() diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java index 922809559f..83c21e526c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/MappingStrategy.java @@ -31,6 +31,7 @@ import org.eclipse.net4j.db.IDBTable; import org.eclipse.net4j.internal.util.om.trace.ContextTracer; import org.eclipse.net4j.util.io.CloseableIterator; +import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -400,6 +401,26 @@ public abstract class MappingStrategy implements IMappingStrategy } } + public long repairAfterCrash(Connection connection) + { + long max = 0L; + for (CDOClass idClass : getClassesWithObjectInfo()) + { + IClassMapping classMapping = getClassMapping(idClass); + IDBTable table = classMapping.getTable(); + IDBField idField = table.getField(CDODBSchema.ATTRIBUTES_ID); + long classMax = DBUtil.selectMaximumLong(connection, idField); + if (TRACER.isEnabled()) + { + TRACER.format("Max CDOID of table {0}: {1}", table, classMax); + } + + max = Math.max(max, classMax); + } + + return max + 2L; + } + @Override public String toString() { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStore.java index 424d565407..0ab5cb49da 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStore.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStore.java @@ -40,6 +40,10 @@ public class NOOPStore extends Store return true; } + public void repairAfterCrash() + { + } + public NOOPStoreAccessor getReader(ISession session) { return new NOOPStoreAccessor(this, session); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java index 7169123563..9d2a6a5cb6 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java @@ -283,6 +283,11 @@ public class Repository extends Container<IRepositoryElement> implements IReposi typeManager.setPersistent(!store.hasEfficientTypeLookup()); typeManager.activate(); packageManager.activate(); + if (store.hasCrashed()) + { + store.repairAfterCrash(); + } + sessionManager.activate(); resourceManager.activate(); revisionManager.activate(); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Store.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Store.java index 6a05e2b0a8..10038820a8 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Store.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Store.java @@ -67,4 +67,9 @@ public abstract class Store extends Lifecycle implements IStore { this.nextOIDValue = nextOIDValue; } + + public boolean hasCrashed() + { + return nextOIDValue == 0L; + } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java index 5f4afadcfa..62c024c7bc 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java @@ -39,6 +39,10 @@ public interface IStore extends IRepositoryElement */ public boolean hasEfficientTypeLookup(); + public boolean hasCrashed(); + + public void repairAfterCrash(); + /** * Returns a reader that can be used to read from this store in the context of the given session. * diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java index 34ec50cac0..6f1f4e8c52 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBUtil.java @@ -136,7 +136,29 @@ public final class DBUtil return null; } - public static int selectMaximum(Connection connection, IDBField field) throws DBException + public static int selectMaximumInt(Connection connection, IDBField field) throws DBException + { + Number number = getMaximumNumber(connection, field); + if (number instanceof Integer) + { + return (Integer)number; + } + + return 0; + } + + public static long selectMaximumLong(Connection connection, IDBField field) throws DBException + { + Number number = getMaximumNumber(connection, field); + if (number instanceof Long) + { + return (Long)number; + } + + return 0; + } + + private static Number getMaximumNumber(Connection connection, IDBField field) throws DBException { StringBuilder builder = new StringBuilder(); builder.append("SELECT MAX("); @@ -145,11 +167,7 @@ public final class DBUtil builder.append(field.getTable()); String sql = builder.toString(); - if (TRACER.isEnabled()) - { - TRACER.trace(sql); - } - + if (TRACER.isEnabled()) TRACER.trace(sql); Statement statement = null; ResultSet resultSet = null; @@ -162,10 +180,10 @@ public final class DBUtil resultSet = statement.executeQuery(sql); if (!resultSet.next()) { - return 0; + return null; } - return resultSet.getInt(1); + return (Number)resultSet.getObject(1); } catch (SQLException ex) { |