diff options
author | Brian S. O'Neill <bronee@gmail.com> | 2010-08-26 00:31:18 +0000 |
---|---|---|
committer | Brian S. O'Neill <bronee@gmail.com> | 2010-08-26 00:31:18 +0000 |
commit | 7283752c177a5d38776905f0fa115c2405ae2175 (patch) | |
tree | 15a3ee64ca867686ca9b54fe5e7c6f50d6f7b0e4 | |
parent | 754b0ca594680502727eb71da755d6a41c9d210f (diff) |
More robust corruption repairs.
-rw-r--r-- | src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java | 38 | ||||
-rw-r--r-- | src/main/java/com/amazon/carbonado/repo/replicated/ReplicationTrigger.java | 25 |
2 files changed, 55 insertions, 8 deletions
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java index 1b6fe8d..2bb2f49 100644 --- a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java +++ b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java @@ -207,7 +207,18 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> { /** Assumes caller is in a transaction */
boolean deleteIndexEntry(S userStorable) throws PersistException {
- return makeIndexEntry(userStorable).tryDelete();
+ try {
+ return makeIndexEntry(userStorable).tryDelete();
+ } catch (PersistException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof IllegalArgumentException) {
+ // Can be caused by a corrupt master record, which is
+ // attempting do assign an illegal value to the index. There's
+ // no way to find the old index entry to delete.
+ return false;
+ }
+ throw e;
+ }
}
/** Assumes caller is in a transaction */
@@ -219,13 +230,26 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> { boolean updateIndexEntry(S userStorable, S oldUserStorable) throws PersistException {
Storable newIndexEntry = makeIndexEntry(userStorable);
- if (oldUserStorable != null) {
- Storable oldIndexEntry = makeIndexEntry(oldUserStorable);
+ if (oldUserStorable != null) deleteOldEntry: {
+ Storable oldIndexEntry;
+ try {
+ oldIndexEntry = makeIndexEntry(oldUserStorable);
+ } catch (PersistException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof IllegalArgumentException) {
+ // Can be caused by a corrupt master record, which is
+ // attempting do assign an illegal value to the index. There's
+ // no way to find the old index entry to delete.
+ break deleteOldEntry;
+ }
+ throw e;
+ }
+
if (oldIndexEntry.equalPrimaryKeys(newIndexEntry)) {
- // Index entry didn't change, so nothing to do. If the
- // index entry has a version, it will lag behind the
- // master's version until the index entry changes, at which
- // point the version will again match the master.
+ // Index entry didn't change, so nothing to do. If the index
+ // entry has a version, it will lag behind the master's version
+ // until the index entry changes, at which point the version
+ // will again match the master.
return true;
}
diff --git a/src/main/java/com/amazon/carbonado/repo/replicated/ReplicationTrigger.java b/src/main/java/com/amazon/carbonado/repo/replicated/ReplicationTrigger.java index 0e9281e..d29d568 100644 --- a/src/main/java/com/amazon/carbonado/repo/replicated/ReplicationTrigger.java +++ b/src/main/java/com/amazon/carbonado/repo/replicated/ReplicationTrigger.java @@ -18,6 +18,8 @@ package com.amazon.carbonado.repo.replicated;
+import java.util.Map;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -343,7 +345,28 @@ class ReplicationTrigger<S extends Storable> extends Trigger<S> { // properties. Be sure not to copy nulls from old replica to new
// replica, in case new non-nullable properties have been added. This
// is why copyUnequalProperties is called instead of copyAllProperties.
- replicaEntry.copyUnequalProperties(newReplicaEntry);
+ try {
+ replicaEntry.copyUnequalProperties(newReplicaEntry);
+ } catch (IllegalArgumentException e) {
+ // Some property cannot be copied, so copy one at a time and skip
+ // the broken one.
+ Map<String,Object> propertyMap = replicaEntry.propertyMap();
+ for (Map.Entry<String, Object> entry : propertyMap.entrySet()) {
+ String name = entry.getKey();
+ Object oldValue = entry.getValue();
+ try {
+ Object newValue = newReplicaEntry.getPropertyValue(name);
+ if (oldValue == null ? newValue != null : !oldValue.equals(newValue)) {
+ newReplicaEntry.setPropertyValue(name, oldValue);
+ }
+ } catch (IllegalArgumentException e2) {
+ // Skip it.
+ } catch (UnsupportedOperationException e2) {
+ // Skip it.
+ }
+ }
+ }
+
// Calling copyAllProperties will skip unsupported independent
// properties in master, thus preserving old independent property values.
masterEntry.copyAllProperties(newReplicaEntry);
|