Exemplo n.º 1
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: long copyStoreFiles(org.neo4j.causalclustering.catchup.CatchupAddressProvider catchupAddressProvider, org.neo4j.causalclustering.identity.StoreId expectedStoreId, StoreFileStreamProvider storeFileStreamProvider, System.Func<TerminationCondition> requestWiseTerminationCondition, java.io.File destDir) throws StoreCopyFailedException
        internal virtual long CopyStoreFiles(CatchupAddressProvider catchupAddressProvider, StoreId expectedStoreId, StoreFileStreamProvider storeFileStreamProvider, System.Func <TerminationCondition> requestWiseTerminationCondition, File destDir)
        {
            try
            {
                PrepareStoreCopyResponse prepareStoreCopyResponse = PrepareStoreCopy(catchupAddressProvider.Primary(), expectedStoreId, storeFileStreamProvider);
                CopyFilesIndividually(prepareStoreCopyResponse, expectedStoreId, catchupAddressProvider, storeFileStreamProvider, requestWiseTerminationCondition, destDir);
                CopyIndexSnapshotIndividually(prepareStoreCopyResponse, expectedStoreId, catchupAddressProvider, storeFileStreamProvider, requestWiseTerminationCondition);
                return(prepareStoreCopyResponse.LastTransactionId());
            }
            catch (Exception e) when(e is CatchupAddressResolutionException || e is CatchUpClientException)
            {
                throw new StoreCopyFailedException(e);
            }
        }
Exemplo n.º 2
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void copy(org.neo4j.causalclustering.catchup.CatchupAddressProvider addressProvider, org.neo4j.causalclustering.identity.StoreId expectedStoreId, org.neo4j.io.layout.DatabaseLayout destinationLayout, boolean rotateTransactionsManually) throws StoreCopyFailedException
        public virtual void Copy(CatchupAddressProvider addressProvider, StoreId expectedStoreId, DatabaseLayout destinationLayout, bool rotateTransactionsManually)
        {
            try
            {
                long lastFlushedTxId;
                StreamToDiskProvider streamToDiskProvider = new StreamToDiskProvider(destinationLayout.DatabaseDirectory(), _fs, _monitors);
                lastFlushedTxId = _storeCopyClient.copyStoreFiles(addressProvider, expectedStoreId, streamToDiskProvider, () => new MaximumTotalTime(_config.get(CausalClusteringSettings.store_copy_max_retry_time_per_request).Seconds, TimeUnit.SECONDS), destinationLayout.DatabaseDirectory());

                _log.info("Store files need to be recovered starting from: %d", lastFlushedTxId);

                CatchupResult catchupResult = PullTransactions(addressProvider.Primary(), expectedStoreId, destinationLayout, lastFlushedTxId, true, true, rotateTransactionsManually);
                if (catchupResult != SUCCESS_END_OF_STREAM)
                {
                    throw new StoreCopyFailedException("Failed to pull transactions: " + catchupResult);
                }
            }
            catch (Exception e) when(e is CatchupAddressResolutionException || e is IOException)
            {
                throw new StoreCopyFailedException(e);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Tries to catchup this instance by downloading a snapshot. A snapshot consists of both the
        /// comparatively small state of the cluster state machines as well as the database store. The
        /// store is however caught up using two different approach. If it is possible to catchup by
        /// pulling transactions, then this will be sufficient, but if the store is lagging too far
        /// behind then a complete store copy will be attempted.
        /// </summary>
        /// <param name="addressProvider"> Provider of addresses to catchup from. </param>
        /// <returns> True if the operation succeeded, and false otherwise. </returns>
        /// <exception cref="LifecycleException"> A major database component failed to start or stop. </exception>
        /// <exception cref="IOException"> An issue with I/O. </exception>
        /// <exception cref="DatabaseShutdownException"> The database is shutting down. </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: boolean downloadSnapshot(org.neo4j.causalclustering.catchup.CatchupAddressProvider addressProvider) throws org.neo4j.kernel.lifecycle.LifecycleException, java.io.IOException, org.neo4j.causalclustering.catchup.storecopy.DatabaseShutdownException
        internal virtual bool DownloadSnapshot(CatchupAddressProvider addressProvider)
        {
            /* Extract some key properties before shutting it down. */
            bool isEmptyStore = _localDatabase.Empty;

            /*
             *  There is no reason to try to recover if there are no transaction logs and in fact it is
             *  also problematic for the initial transaction pull during the snapshot download because the
             *  kernel will create a transaction log with a header where previous index points to the same
             *  index as that written down into the metadata store. This is problematic because we have no
             *  guarantee that there are later transactions and we need at least one transaction in
             *  the log to figure out the Raft log index (see {@link RecoverConsensusLogIndex}).
             */
            if (_commitStateHelper.hasTxLogs(_localDatabase.databaseLayout()))
            {
                _log.info("Recovering local database");
                Ensure(_localDatabase.start, "start local database");
                Ensure(_localDatabase.stop, "stop local database");
            }

            AdvertisedSocketAddress primary;
            StoreId remoteStoreId;

            try
            {
                primary       = addressProvider.Primary();
                remoteStoreId = _remoteStore.getStoreId(primary);
            }
            catch (Exception e) when(e is CatchupAddressResolutionException || e is StoreIdDownloadFailedException)
            {
                _log.warn("Store copy failed", e);
                return(false);
            }

            if (!isEmptyStore && !remoteStoreId.Equals(_localDatabase.storeId()))
            {
                _log.error("Store copy failed due to store ID mismatch");
                return(false);
            }

            Ensure(_suspendOnStoreCopy.disable, "disable auxiliary services before store copy");
            Ensure(_localDatabase.stopForStoreCopy, "stop local database for store copy");

            _log.info("Downloading snapshot from core server at %s", primary);

            /* 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;

            try
            {
                coreSnapshot = _catchUpClient.makeBlockingRequest(primary, new CoreSnapshotRequest(), new CatchUpResponseAdaptorAnonymousInnerClass(this));
            }
            catch (CatchUpClientException e)
            {
                _log.warn("Store copy failed", e);
                return(false);
            }

            if (!isEmptyStore)
            {
                StoreId       localStoreId = _localDatabase.storeId();
                CatchupResult catchupResult;
                try
                {
                    catchupResult = _remoteStore.tryCatchingUp(primary, localStoreId, _localDatabase.databaseLayout(), false, false);
                }
                catch (StoreCopyFailedException e)
                {
                    _log.warn("Failed to catch up", e);
                    return(false);
                }

                if (catchupResult == E_TRANSACTION_PRUNED)
                {
                    _log.warn(format("Failed to pull transactions from (%s). They may have been pruned away", primary));
                    _localDatabase.delete();
                    isEmptyStore = true;
                }
                else if (catchupResult != SUCCESS_END_OF_STREAM)
                {
                    _log.warn(format("Unexpected catchup operation result %s from %s", catchupResult, primary));
                    return(false);
                }
            }

            if (isEmptyStore)
            {
                try
                {
                    _storeCopyProcess.replaceWithStoreFrom(addressProvider, remoteStoreId);
                }
                catch (StoreCopyFailedException e)
                {
                    _log.warn("Failed to copy and replace store", e);
                    return(false);
                }
            }

            /* We install the snapshot after the store has been downloaded,
             * so that we are not left with a state ahead of the store. */
            _snapshotService.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");
            Ensure(_localDatabase.start, "start local database after store copy");

            _coreStateMachines.installCommitProcess(_localDatabase.CommitProcess);
            Ensure(_suspendOnStoreCopy.enable, "enable auxiliary services after store copy");

            return(true);
        }