Search in sources :

Example 16 with Transaction

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

the class IndexingBase method rebuildIndexAsync.

// rebuildIndexAsync - builds the whole index inline (without committing)
@Nonnull
public CompletableFuture<Void> rebuildIndexAsync(@Nonnull FDBRecordStore store) {
    return forEachTargetIndex(index -> store.clearAndMarkIndexWriteOnly(index).thenCompose(bignore -> {
        // Insert the full range into the range set. (The internal rebuild method only indexes the records and
        // does not update the range set.) This is important because if marking the index as readable fails (for
        // example, because of uniqueness violations), we still want to record in the range set that the entire
        // range was built so that future index builds don't re-scan the record data and so that non-idempotent
        // indexes know to update the index on all record saves.
        Transaction tr = store.ensureContextActive();
        RangeSet rangeSet = new RangeSet(store.indexRangeSubspace(index));
        return rangeSet.insertRange(tr, null, null);
    })).thenCompose(vignore -> rebuildIndexInternalAsync(store));
}
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) Transaction(com.apple.foundationdb.Transaction) RangeSet(com.apple.foundationdb.async.RangeSet) Nonnull(javax.annotation.Nonnull)

Example 17 with Transaction

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

the class IndexingBase method setScrubberTypeOrThrow.

@Nonnull
private CompletableFuture<Void> setScrubberTypeOrThrow(FDBRecordStore store) {
    // HERE: The index must be readable, checked by the caller
    // if scrubber had already run and still have missing ranges, do nothing
    // else: clear ranges and overwrite type-stamp
    Transaction tr = store.getContext().ensureActive();
    IndexBuildProto.IndexBuildIndexingStamp indexingTypeStamp = getIndexingTypeStamp(store);
    validateOrThrowEx(indexingTypeStamp.getMethod().equals(IndexBuildProto.IndexBuildIndexingStamp.Method.SCRUB_REPAIR), "Not a scrubber type-stamp");
    // Note: the scrubbers do not support multi target (yet)
    final Index index = common.getIndex();
    final Subspace indexesRangeSubspace = indexScrubIndexRangeSubspace(store, index);
    final Subspace recordsRangeSubspace = indexScrubRecordsRangeSubspace(store, index);
    RangeSet indexRangeSet = new RangeSet(indexesRangeSubspace);
    RangeSet recordsRangeSet = new RangeSet(recordsRangeSubspace);
    AsyncIterator<Range> indexRanges = indexRangeSet.missingRanges(tr).iterator();
    AsyncIterator<Range> recordsRanges = recordsRangeSet.missingRanges(tr).iterator();
    return indexRanges.onHasNext().thenCompose(hasNextIndex -> {
        if (Boolean.FALSE.equals(hasNextIndex)) {
            // erase the 'ranges' data to allow a fresh index re-scrubbing.
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(KeyValueLogMessage.build("Reset scrubber's index range").addKeysAndValues(common.indexLogMessageKeyValues()).toString());
            }
            tr.clear(indexesRangeSubspace.range());
        }
        return recordsRanges.onHasNext().thenAccept(hasNextRecord -> {
            if (Boolean.FALSE.equals(hasNextRecord)) {
                // erase the 'ranges' data to allow a fresh records re-scrubbing.
                if (LOGGER.isInfoEnabled()) {
                    LOGGER.info(KeyValueLogMessage.build("Reset scrubber's records range").addKeysAndValues(common.indexLogMessageKeyValues()).toString());
                }
                tr.clear(recordsRangeSubspace.range());
            }
        });
    });
}
Also used : Transaction(com.apple.foundationdb.Transaction) IndexBuildProto(com.apple.foundationdb.record.IndexBuildProto) Subspace(com.apple.foundationdb.subspace.Subspace) RangeSet(com.apple.foundationdb.async.RangeSet) Index(com.apple.foundationdb.record.metadata.Index) Range(com.apple.foundationdb.Range) Nonnull(javax.annotation.Nonnull)

Example 18 with Transaction

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

the class FDBSystemOperations method getPrimaryDatacenterAsync.

/**
 * Get the primary datacenter of the underlying cluster. This will return the datacenter ID (if set)
 * of the datacenter currently serving as the primary, which (by definition) is where the transaction
 * subsystem will be recruited. This is mostly relevant for
 * <a href="https://apple.github.io/foundationdb/configuration.html#configuring-regions">multi-region configurations</a>,
 * where this value might change if the cluster decides that it needs to fail over to a secondary region. The returned
 * datacenter ID will be {@code null} if the FDB cluster's datacenter has not been set.
 *
 * <p>
 * Note that this operation must read this information from the database's storage and uses its own transaction.
 * </p>
 *
 * @param runner a runner to use to perform the operation
 * @return a future that will complete with the primary datacenter of the cluster for the database underlying {@code runner}
 */
@Nonnull
public static CompletableFuture<String> getPrimaryDatacenterAsync(@Nonnull FDBDatabaseRunner runner) {
    return runner.runAsync(context -> {
        final Transaction tr = context.ensureActive();
        tr.options().setReadSystemKeys();
        return tr.get(SystemKeyspace.PRIMARY_DATACENTER_KEY).thenApply(FDBSystemOperations::nullableUtf8);
    }, Arrays.asList(LogMessageKeys.TRANSACTION_NAME, "FDBSystemOperations::getPrimaryDatacenterAsync"));
}
Also used : Transaction(com.apple.foundationdb.Transaction) Nonnull(javax.annotation.Nonnull)

Example 19 with Transaction

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

the class FDBDatabase method openContext.

/**
 * Open a new record context with a new transaction begun on the underlying FDB database. Various
 * options on the transaction will be informed based on the passed context.
 *
 * @param contextConfig a configuration object specifying various options on the returned context
 * @return a new record context
 * @see Database#createTransaction
 */
@Nonnull
@SuppressWarnings("PMD.CompareObjectsWithEquals")
public FDBRecordContext openContext(@Nonnull FDBRecordContextConfig contextConfig) {
    openFDB();
    final Executor executor = newContextExecutor(contextConfig.getMdcContext());
    final Transaction transaction = createTransaction(contextConfig, executor);
    // TODO: Compatibility with STABLE API.
    if (transactionIsTracedSupplier.get()) {
        contextConfig = contextConfig.toBuilder().setTrackOpen(true).setLogTransaction(true).setSaveOpenStackTrace(true).build();
    }
    FDBRecordContext context = new FDBRecordContext(this, transaction, contextConfig);
    final WeakReadSemantics weakReadSemantics = context.getWeakReadSemantics();
    if (isTrackLastSeenVersion() && (weakReadSemantics != null)) {
        Pair<Long, Long> pair = lastSeenFDBVersion.get();
        if (pair != initialVersionPair) {
            long version = pair.getLeft();
            long versionTimeMillis = pair.getRight();
            // otherwise getReadVersion does not use the cached value and results in a GRV call to FDB
            if (version >= weakReadSemantics.getMinVersion() && (System.currentTimeMillis() - versionTimeMillis) <= weakReadSemantics.getStalenessBoundMillis()) {
                context.setReadVersion(version);
                context.increment(FDBStoreTimer.Counts.SET_READ_VERSION_TO_LAST_SEEN);
            }
        }
    }
    if (warnAndCloseOpenContextsAfterSeconds > 0) {
        warnAndCloseOldTrackedOpenContexts(warnAndCloseOpenContextsAfterSeconds);
    }
    if (contextConfig.isTrackOpen()) {
        trackOpenContext(context);
    }
    return context;
}
Also used : Executor(java.util.concurrent.Executor) Transaction(com.apple.foundationdb.Transaction) Nonnull(javax.annotation.Nonnull)

Example 20 with Transaction

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

the class BunchedMapScanTest method testScan.

private void testScan(int limit, boolean reverse, @Nonnull BiFunction<Transaction, byte[], BunchedMapIterator<Tuple, Tuple>> iteratorFunction) {
    try (Transaction tr = db.createTransaction()) {
        byte[] continuation = null;
        List<Tuple> readKeys = new ArrayList<>();
        Tuple lastKey = null;
        do {
            int returned = 0;
            BunchedMapIterator<Tuple, Tuple> bunchedMapIterator = iteratorFunction.apply(tr, continuation);
            while (bunchedMapIterator.hasNext()) {
                Tuple toAdd = bunchedMapIterator.peek().getKey();
                readKeys.add(toAdd);
                assertEquals(toAdd, bunchedMapIterator.next().getKey());
                if (lastKey != null) {
                    assertEquals(reverse ? 1 : -1, lastKey.compareTo(toAdd));
                }
                lastKey = toAdd;
                returned += 1;
            }
            assertFalse(bunchedMapIterator.hasNext());
            assertThrows(NoSuchElementException.class, bunchedMapIterator::peek);
            assertThrows(NoSuchElementException.class, bunchedMapIterator::next);
            continuation = bunchedMapIterator.getContinuation();
            if (limit == ReadTransaction.ROW_LIMIT_UNLIMITED || returned < limit) {
                assertNull(continuation);
            } else {
                assertNotNull(continuation);
            }
        } while (continuation != null);
        if (reverse) {
            readKeys = Lists.reverse(readKeys);
        }
        assertEquals(keys, readKeys);
        tr.cancel();
    }
}
Also used : Transaction(com.apple.foundationdb.Transaction) ReadTransaction(com.apple.foundationdb.ReadTransaction) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple)

Aggregations

Transaction (com.apple.foundationdb.Transaction)84 ReadTransaction (com.apple.foundationdb.ReadTransaction)34 Tuple (com.apple.foundationdb.tuple.Tuple)34 Test (org.junit.jupiter.api.Test)33 Nonnull (javax.annotation.Nonnull)28 ArrayList (java.util.ArrayList)26 List (java.util.List)26 CompletableFuture (java.util.concurrent.CompletableFuture)26 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)22 Subspace (com.apple.foundationdb.subspace.Subspace)21 Collectors (java.util.stream.Collectors)19 Nullable (javax.annotation.Nullable)19 KeyValue (com.apple.foundationdb.KeyValue)18 Map (java.util.Map)18 KeyValueLogMessage (com.apple.foundationdb.record.logging.KeyValueLogMessage)17 Range (com.apple.foundationdb.Range)16 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)16 AtomicReference (java.util.concurrent.atomic.AtomicReference)16 Collections (java.util.Collections)15 RecordCursor (com.apple.foundationdb.record.RecordCursor)14