Search in sources :

Example 11 with IndexState

use of com.apple.foundationdb.record.IndexState in project fdb-record-layer by FoundationDB.

the class IndexingBase method handleStateAndDoBuildIndexAsync.

@Nonnull
private CompletableFuture<Void> handleStateAndDoBuildIndexAsync(boolean markReadable, KeyValueLogMessage message) {
    /*
         * Multi target:
         * The primary and follower indexes must the same state.
         * If the primary is disabled, a follower is write_only/readable, and the policy for write_only/readable is
         *   rebuild - the follower's state will be cleared.
         * If the primary is cleared, all the followers are cleared (must match stamps/ranges).
         * If the primary is write_only, and the followers' stamps/ranges do not match, it would be caught during indexing.
         */
    final List<Index> targetIndexes = common.getTargetIndexes();
    final Index primaryIndex = targetIndexes.get(0);
    return getRunner().runAsync(context -> openRecordStore(context).thenCompose(store -> {
        IndexState indexState = store.getIndexState(primaryIndex);
        if (isScrubber) {
            validateOrThrowEx(indexState == IndexState.READABLE, "Scrubber was called for a non-readable index. Index:" + primaryIndex.getName() + " State: " + indexState);
            return setScrubberTypeOrThrow(store).thenApply(ignore -> true);
        }
        OnlineIndexer.IndexingPolicy.DesiredAction desiredAction = policy.getStateDesiredAction(indexState);
        if (desiredAction == OnlineIndexer.IndexingPolicy.DesiredAction.ERROR) {
            throw new ValidationException("Index state is not as expected", LogMessageKeys.INDEX_NAME, primaryIndex.getName(), LogMessageKeys.INDEX_VERSION, primaryIndex.getLastModifiedVersion(), LogMessageKeys.INDEX_STATE, indexState);
        }
        boolean shouldClear = desiredAction == OnlineIndexer.IndexingPolicy.DesiredAction.REBUILD;
        boolean shouldBuild = shouldClear || indexState != IndexState.READABLE;
        message.addKeyAndValue(LogMessageKeys.INITIAL_INDEX_STATE, indexState);
        message.addKeyAndValue(LogMessageKeys.INDEXING_POLICY_DESIRED_ACTION, desiredAction);
        message.addKeyAndValue(LogMessageKeys.SHOULD_BUILD_INDEX, shouldBuild);
        message.addKeyAndValue(LogMessageKeys.SHOULD_CLEAR_EXISTING_DATA, shouldClear);
        if (!shouldBuild) {
            // do not index
            return AsyncUtil.READY_FALSE;
        }
        List<Index> indexesToClear = new ArrayList<>(targetIndexes.size());
        if (shouldClear) {
            indexesToClear.add(primaryIndex);
            // The code can work without this line, but it'll save probing the missing ranges
            forceStampOverwrite = true;
        }
        boolean continuedBuild = !shouldClear && indexState == IndexState.WRITE_ONLY;
        for (Index targetIndex : targetIndexes.subList(1, targetIndexes.size())) {
            // Must follow the primary index' status
            IndexState state = store.getIndexState(targetIndex);
            if (state != indexState) {
                if (policy.getStateDesiredAction(state) != OnlineIndexer.IndexingPolicy.DesiredAction.REBUILD || continuedBuild) {
                    throw new ValidationException("A target index state doesn't match the primary index state", LogMessageKeys.INDEX_NAME, primaryIndex.getName(), LogMessageKeys.INDEX_STATE, indexState, LogMessageKeys.TARGET_INDEX_NAME, targetIndex.getName(), LogMessageKeys.TARGET_INDEX_STATE, state);
                }
                // just clear this one, the primary is disabled
                indexesToClear.add(targetIndex);
            } else if (shouldClear) {
                indexesToClear.add(targetIndex);
            }
        }
        return AsyncUtil.whenAll(indexesToClear.stream().map(store::clearAndMarkIndexWriteOnly).collect(Collectors.toList())).thenCompose(vignore -> markIndexesWriteOnly(continuedBuild, store)).thenCompose(vignore -> setIndexingTypeOrThrow(store, continuedBuild)).thenApply(ignore -> true);
    }), common.indexLogMessageKeyValues("IndexingBase::handleIndexingState")).thenCompose(doIndex -> doIndex ? buildIndexInternalAsync().thenApply(ignore -> markReadable) : AsyncUtil.READY_FALSE).thenCompose(this::markIndexReadable).thenApply(ignore -> null);
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) LogMessageKeys(com.apple.foundationdb.record.logging.LogMessageKeys) BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) AsyncIterator(com.apple.foundationdb.async.AsyncIterator) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) RangeSet(com.apple.foundationdb.async.RangeSet) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) Subspace(com.apple.foundationdb.subspace.Subspace) ArrayList(java.util.ArrayList) MutationType(com.apple.foundationdb.MutationType) Key(com.apple.foundationdb.record.metadata.Key) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Range(com.apple.foundationdb.Range) RecordCursorResult(com.apple.foundationdb.record.RecordCursorResult) KeyValueLogMessage(com.apple.foundationdb.record.logging.KeyValueLogMessage) Pair(org.apache.commons.lang3.tuple.Pair) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) BiConsumer(java.util.function.BiConsumer) IndexBuildProto(com.apple.foundationdb.record.IndexBuildProto) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) ByteArrayUtil2(com.apple.foundationdb.tuple.ByteArrayUtil2) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) Logger(org.slf4j.Logger) SynchronizedSessionRunner(com.apple.foundationdb.record.provider.foundationdb.synchronizedsession.SynchronizedSessionRunner) IndexState(com.apple.foundationdb.record.IndexState) Collectors(java.util.stream.Collectors) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) RecordMetaDataProvider(com.apple.foundationdb.record.RecordMetaDataProvider) Index(com.apple.foundationdb.record.metadata.Index) FDBException(com.apple.foundationdb.FDBException) Message(com.google.protobuf.Message) RecordCursor(com.apple.foundationdb.record.RecordCursor) API(com.apple.foundationdb.annotation.API) Collections(java.util.Collections) SyntheticRecordPlanner(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordPlanner) SyntheticRecordFromStoredRecordPlan(com.apple.foundationdb.record.query.plan.synthetic.SyntheticRecordFromStoredRecordPlan) ArrayList(java.util.ArrayList) Index(com.apple.foundationdb.record.metadata.Index) IndexState(com.apple.foundationdb.record.IndexState) Nonnull(javax.annotation.Nonnull)

Aggregations

IndexState (com.apple.foundationdb.record.IndexState)11 Nonnull (javax.annotation.Nonnull)10 Index (com.apple.foundationdb.record.metadata.Index)9 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)8 LogMessageKeys (com.apple.foundationdb.record.logging.LogMessageKeys)8 ArrayList (java.util.ArrayList)8 List (java.util.List)8 CompletableFuture (java.util.concurrent.CompletableFuture)8 Nullable (javax.annotation.Nullable)8 Logger (org.slf4j.Logger)8 LoggerFactory (org.slf4j.LoggerFactory)8 MoreAsyncUtil (com.apple.foundationdb.async.MoreAsyncUtil)7 KeyValueLogMessage (com.apple.foundationdb.record.logging.KeyValueLogMessage)7 ImmutableMap (com.google.common.collect.ImmutableMap)7 HashMap (java.util.HashMap)7 Map (java.util.Map)7 Function (java.util.function.Function)7 Range (com.apple.foundationdb.Range)6 Transaction (com.apple.foundationdb.Transaction)6 API (com.apple.foundationdb.annotation.API)6