Active blob deletion fails on composite setups
@@ -42,6 +42,7 @@ import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.management.openmbean.CompositeData;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
@@ -52,6 +53,7 @@ import java.util.stream.StreamSupport;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Iterators.any;
import static org.apache.jackrabbit.oak.api.Type.STRING;
import static org.apache.jackrabbit.oak.api.jmx.IndexStatsMBean.STATUS_RUNNING;
import static org.apache.jackrabbit.oak.commons.jmx.ManagementOperation.Status.failed;
@@ -319,15 +321,27 @@ public class ActiveDeletedBlobCollectorMBeanImpl implements ActiveDeletedBlobCol
try {
List<CheckpointMBean> services = tracker.getServices();
- if (services.size() == 1) {
- return services.get(0).getOldestCheckpointCreationTimestamp();
- } else if (services.isEmpty()) {
+ if (services.isEmpty()) {
LOG.warn("Unable to get checkpoint mbean. No service of required type found.");
return -1;
} else {
- LOG.warn("Unable to get checkpoint mbean. Multiple services of required type found.");
+ // OAK-7610: Composite node store setups have 2 instances of CheckpointMBean:
+ // 1. registered via CompositeNodeStore
+ // 2. registered via global node store
+ // While it is still to be decided whether it's reasonable to have multiple instances
+ // of checkpoint bean - we are going to iterate over the beans and return oldest
+ // timestamp iff each of the bean reports the same oldest timestamp value. The reason
+ // it'd work, at least as of now, is that CompositeNodeStore implementation of checkpoint
+ // bean simply delegates to global store's implementation
+ Iterator<CheckpointMBean> beans = services.iterator();
+ long ret = beans.next().getOldestCheckpointCreationTimestamp();
+ if (any(beans, bean -> ret != bean.getOldestCheckpointCreationTimestamp())) {
+ LOG.warn("Unable to get checkpoint mbean. Multiple services of required type found and not" +
+ " all of them returned same value of oldest timestamp ({})", ret);
return -1;
}
+ return ret;
+ }
} finally {
tracker.stop();
}
