Search in sources :

Example 1 with CatchupResult

use of org.neo4j.causalclustering.catchup.CatchupResult in project neo4j by neo4j.

the class CoreStateDownloader method downloadSnapshot.

public synchronized void downloadSnapshot(MemberId source, CoreState coreState) throws StoreCopyFailedException {
    try {
        /* Extract some key properties before shutting it down. */
        boolean isEmptyStore = localDatabase.isEmpty();
        if (!isEmptyStore) {
            /* make sure it's recovered before we start messing with catchup */
            localDatabase.start();
            localDatabase.stop();
        }
        StoreId remoteStoreId = remoteStore.getStoreId(source);
        if (!isEmptyStore && !remoteStoreId.equals(localDatabase.storeId())) {
            throw new StoreCopyFailedException("StoreId mismatch and not empty");
        }
        startStopOnStoreCopy.stop();
        localDatabase.stopForStoreCopy();
        log.info("Downloading snapshot from core server at %s", source);
        /* The core snapshot must be copied before the store, because the store has a dependency on
             * the state of the state machines. The store will thus be at or ahead of the state machines,
             * in consensus log index, and application of commands will bring them in sync. Any such commands
             * that carry transactions will thus be ignored by the transaction/token state machines, since they
             * are ahead, and the correct decisions for their applicability have already been taken as encapsulated
             * in the copied store. */
        CoreSnapshot coreSnapshot = catchUpClient.makeBlockingRequest(source, new CoreSnapshotRequest(), new CatchUpResponseAdaptor<CoreSnapshot>() {

            @Override
            public void onCoreSnapshot(CompletableFuture<CoreSnapshot> signal, CoreSnapshot response) {
                signal.complete(response);
            }
        });
        if (isEmptyStore) {
            storeCopyProcess.replaceWithStoreFrom(source, remoteStoreId);
        } else {
            StoreId localStoreId = localDatabase.storeId();
            CatchupResult catchupResult = remoteStore.tryCatchingUp(source, localStoreId, localDatabase.storeDir());
            if (catchupResult == E_TRANSACTION_PRUNED) {
                log.info("Failed to pull transactions from " + source + ". They may have been pruned away.");
                localDatabase.delete();
                storeCopyProcess.replaceWithStoreFrom(source, localStoreId);
            } else if (catchupResult != SUCCESS_END_OF_STREAM) {
                throw new StoreCopyFailedException("Failed to download store: " + catchupResult);
            }
        }
        /* We install the snapshot after the store has been downloaded,
             * so that we are not left with a state ahead of the store. */
        coreState.installSnapshot(coreSnapshot);
        log.info("Core snapshot installed: " + coreSnapshot);
        /* Starting the database will invoke the commit process factory in
             * the EnterpriseCoreEditionModule, which has important side-effects. */
        log.info("Starting local database");
        localDatabase.start();
        coreStateMachines.installCommitProcess(localDatabase.getCommitProcess());
        startStopOnStoreCopy.start();
    } catch (StoreCopyFailedException e) {
        throw e;
    } catch (Throwable e) {
        throw new StoreCopyFailedException(e);
    }
}
Also used : StoreCopyFailedException(org.neo4j.causalclustering.catchup.storecopy.StoreCopyFailedException) StoreId(org.neo4j.causalclustering.identity.StoreId) CatchupResult(org.neo4j.causalclustering.catchup.CatchupResult)

Example 2 with CatchupResult

use of org.neo4j.causalclustering.catchup.CatchupResult in project neo4j by neo4j.

the class TxStreamFinishedResponseDecoder method decode.

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
    int ordinal = msg.readInt();
    long latestTxid = msg.readLong();
    CatchupResult status = CatchupResult.values()[ordinal];
    out.add(new TxStreamFinishedResponse(status, latestTxid));
}
Also used : CatchupResult(org.neo4j.causalclustering.catchup.CatchupResult)

Example 3 with CatchupResult

use of org.neo4j.causalclustering.catchup.CatchupResult in project neo4j by neo4j.

the class RemoteStore method pullTransactions.

private CatchupResult pullTransactions(MemberId from, StoreId expectedStoreId, File storeDir, long fromTxId, boolean asPartOfStoreCopy) throws IOException, StoreCopyFailedException {
    try (TransactionLogCatchUpWriter writer = transactionLogFactory.create(storeDir, fs, pageCache, logProvider, fromTxId, asPartOfStoreCopy)) {
        log.info("Pulling transactions from: %d", fromTxId);
        long previousTxId = fromTxId - 1;
        CatchupResult lastStatus;
        do {
            TxPullRequestResult result = txPullClient.pullTransactions(from, expectedStoreId, previousTxId, writer);
            lastStatus = result.catchupResult();
            previousTxId = result.lastTxId();
        } while (lastStatus == SUCCESS_END_OF_BATCH);
        return lastStatus;
    } catch (CatchUpClientException e) {
        throw new StoreCopyFailedException(e);
    }
}
Also used : TransactionLogCatchUpWriter(org.neo4j.causalclustering.catchup.tx.TransactionLogCatchUpWriter) CatchupResult(org.neo4j.causalclustering.catchup.CatchupResult) CatchUpClientException(org.neo4j.causalclustering.catchup.CatchUpClientException) TxPullRequestResult(org.neo4j.causalclustering.catchup.TxPullRequestResult)

Example 4 with CatchupResult

use of org.neo4j.causalclustering.catchup.CatchupResult in project neo4j by neo4j.

the class RemoteStore method copy.

public void copy(MemberId from, StoreId expectedStoreId, File destDir) throws StoreCopyFailedException, StreamingTransactionsFailedException {
    try {
        log.info("Copying store from %s", from);
        long lastFlushedTxId;
        try (StreamToDisk storeFileStreams = new StreamToDisk(destDir, fs, pageCache, monitors)) {
            lastFlushedTxId = storeCopyClient.copyStoreFiles(from, expectedStoreId, storeFileStreams);
        }
        log.info("Store files need to be recovered starting from: %d", lastFlushedTxId);
        CatchupResult catchupResult = pullTransactions(from, expectedStoreId, destDir, lastFlushedTxId, true);
        if (catchupResult != SUCCESS_END_OF_STREAM) {
            throw new StreamingTransactionsFailedException("Failed to pull transactions: " + catchupResult);
        }
    } catch (IOException e) {
        throw new StoreCopyFailedException(e);
    }
}
Also used : CatchupResult(org.neo4j.causalclustering.catchup.CatchupResult) IOException(java.io.IOException)

Example 5 with CatchupResult

use of org.neo4j.causalclustering.catchup.CatchupResult in project neo4j by neo4j.

the class TxPullRequestHandler method channelRead0.

@Override
protected void channelRead0(ChannelHandlerContext ctx, final TxPullRequest msg) throws Exception {
    long firstTxId = Math.max(msg.previousTxId(), BASE_TX_ID) + 1;
    long lastTxId = firstTxId;
    CatchupResult status = SUCCESS_END_OF_STREAM;
    StoreId localStoreId = storeIdSupplier.get();
    long lastCommittedTransactionId = transactionIdStore.getLastCommittedTransactionId();
    if (localStoreId == null || !localStoreId.equals(msg.expectedStoreId())) {
        status = E_STORE_ID_MISMATCH;
        log.info("Failed to serve TxPullRequest for tx %d and storeId %s because that storeId is different " + "from this machine with %s", lastTxId, msg.expectedStoreId(), localStoreId);
    } else if (!databaseAvailable.getAsBoolean()) {
        // database is not available for pulling transactions...
        status = E_STORE_UNAVAILABLE;
        log.info("Failed to serve TxPullRequest for tx %d because the local database is unavailable.", lastTxId);
    } else if (lastCommittedTransactionId >= firstTxId) {
        try (IOCursor<CommittedTransactionRepresentation> cursor = logicalTransactionStore.getTransactions(firstTxId)) {
            status = SUCCESS_END_OF_BATCH;
            for (int i = 0; i < batchSize; i++) {
                if (cursor.next()) {
                    ctx.write(ResponseMessageType.TX);
                    CommittedTransactionRepresentation tx = cursor.get();
                    lastTxId = tx.getCommitEntry().getTxId();
                    ctx.write(new TxPullResponse(localStoreId, tx));
                } else {
                    status = SUCCESS_END_OF_STREAM;
                    break;
                }
            }
            ctx.flush();
        } catch (NoSuchTransactionException e) {
            status = E_TRANSACTION_PRUNED;
            log.info("Failed to serve TxPullRequest for tx %d because the transaction does not exist.", lastTxId);
        }
    }
    ctx.write(ResponseMessageType.TX_STREAM_FINISHED);
    TxStreamFinishedResponse response = new TxStreamFinishedResponse(status, lastCommittedTransactionId);
    ctx.write(response);
    ctx.flush();
    monitor.increment();
    protocol.expect(State.MESSAGE_TYPE);
}
Also used : CommittedTransactionRepresentation(org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation) StoreId(org.neo4j.causalclustering.identity.StoreId) CatchupResult(org.neo4j.causalclustering.catchup.CatchupResult) NoSuchTransactionException(org.neo4j.kernel.impl.transaction.log.NoSuchTransactionException)

Aggregations

CatchupResult (org.neo4j.causalclustering.catchup.CatchupResult)5 StoreId (org.neo4j.causalclustering.identity.StoreId)2 IOException (java.io.IOException)1 CatchUpClientException (org.neo4j.causalclustering.catchup.CatchUpClientException)1 TxPullRequestResult (org.neo4j.causalclustering.catchup.TxPullRequestResult)1 StoreCopyFailedException (org.neo4j.causalclustering.catchup.storecopy.StoreCopyFailedException)1 TransactionLogCatchUpWriter (org.neo4j.causalclustering.catchup.tx.TransactionLogCatchUpWriter)1 CommittedTransactionRepresentation (org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation)1 NoSuchTransactionException (org.neo4j.kernel.impl.transaction.log.NoSuchTransactionException)1