Beispiel #1
0
        internal virtual void CheckDataConsistencyWithMaster(URI availableMasterId, Master master, StoreId storeId, TransactionIdStore transactionIdStore)
        {
            TransactionId   myLastCommittedTxData = transactionIdStore.LastCommittedTransaction;
            long            myLastCommittedTx     = myLastCommittedTxData.TransactionIdConflict();
            HandshakeResult handshake;

            try
            {
                using (Response <HandshakeResult> response = master.Handshake(myLastCommittedTx, storeId))
                {
                    handshake = response.ResponseConflict();
                    RequestContextFactory.Epoch = handshake.Epoch();
                }
            }
            catch (BranchedDataException e)
            {
                // Rethrow wrapped in a branched data exception on our side, to clarify where the problem originates.
                throw new BranchedDataException("The database stored on this machine has diverged from that " + "of the master. This will be automatically resolved.", e);
            }
            catch (Exception e)
            {
                // Checked exceptions will be wrapped as the cause if this was a serialized
                // server-side exception
                if (e.InnerException is MissingLogDataException)
                {
                    /*
                     * This means the master was unable to find a log entry for the txid we just asked. This
                     * probably means the thing we asked for is too old or too new. Anyway, since it doesn't
                     * have the tx it is better if we just throw our store away and ask for a new copy. Next
                     * time around it shouldn't have to even pass from here.
                     */
                    throw new StoreOutOfDateException("The master is missing the log required to complete the " + "consistency check", e.InnerException);
                }
                throw e;
            }

            long myChecksum = myLastCommittedTxData.Checksum();

            if (myChecksum != handshake.TxChecksum())
            {
                string msg = "The cluster contains two logically different versions of the database.. This will be " +
                             "automatically resolved. Details: I (server_id:" + Config.get(ClusterSettings.server_id) +
                             ") think checksum for txId (" + myLastCommittedTx + ") is " + myChecksum +
                             ", but master (server_id:" + getServerId(availableMasterId) + ") says that it's " +
                             handshake.TxChecksum() + ", where handshake is " + handshake;
                throw new BranchedDataException(msg);
            }
            MsgLog.info("Checksum for last committed tx ok with lastTxId=" + myLastCommittedTx + " with checksum=" + myChecksum);
        }
Beispiel #2
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void migrate(org.neo4j.io.layout.DatabaseLayout directoryLayout, org.neo4j.io.layout.DatabaseLayout migrationLayout, org.neo4j.kernel.impl.util.monitoring.ProgressReporter progressReporter, String versionToMigrateFrom, String versionToMigrateTo) throws java.io.IOException
        public override void Migrate(DatabaseLayout directoryLayout, DatabaseLayout migrationLayout, ProgressReporter progressReporter, string versionToMigrateFrom, string versionToMigrateTo)
        {
            // Extract information about the last transaction from legacy neostore
            File          neoStore          = directoryLayout.MetadataStore();
            long          lastTxId          = MetaDataStore.getRecord(_pageCache, neoStore, MetaDataStore.Position.LAST_TRANSACTION_ID);
            TransactionId lastTxInfo        = ExtractTransactionIdInformation(neoStore, lastTxId);
            LogPosition   lastTxLogPosition = ExtractTransactionLogPosition(neoStore, directoryLayout, lastTxId);

            // Write the tx checksum to file in migrationStructure, because we need it later when moving files into storeDir
            WriteLastTxInformation(migrationLayout, lastTxInfo);
            WriteLastTxLogPosition(migrationLayout, lastTxLogPosition);

            if (versionToMigrateFrom.Equals("vE.H.0"))
            {
                // NOTE for 3.0 here is a special case for vE.H.0 "from" record format.
                // Legend has it that 3.0.5 enterprise changed store format without changing store version.
                // This was done to cheat the migrator to avoid doing store migration since the
                // format itself was backwards compatible. Immediately a problem was detected:
                // if a user uses 3.0.5 for a while and then goes back to a previous 3.0.x patch release
                // the db wouldn't recognize it was an incompatible downgrade and start up normally,
                // but read records with scrambled values and pointers, sort of.
                //
                // This condition has two functions:
                //  1. preventing actual store migration between vE.H.0 --> vE.H.0b
                //  2. making vE.H.0b used in any migration where either vE.H.0 or vE.H.0b is the existing format,
                //     this because vE.H.0b is a superset of vE.H.0 and sometimes (for 3.0.5) vE.H.0
                //     actually means vE.H.0b (in later version).
                //
                // In later versions of neo4j there are better mechanics in place so that a non-migration like this
                // can be performed w/o special casing. To not require backporting that functionality
                // this condition is here and should be removed in 3.1.
                versionToMigrateFrom = "vE.H.0b";
            }
            RecordFormats oldFormat = selectForVersion(versionToMigrateFrom);
            RecordFormats newFormat = selectForVersion(versionToMigrateTo);

            if (FormatFamily.isHigherFamilyFormat(newFormat, oldFormat) || (FormatFamily.isSameFamily(oldFormat, newFormat) && IsDifferentCapabilities(oldFormat, newFormat)))
            {
                // TODO if this store has relationship indexes then warn user about that they will be incorrect
                // after migration, because now we're rewriting the relationship ids.

                // Some form of migration is required (a fallback/catch-all option)
                MigrateWithBatchImporter(directoryLayout, migrationLayout, lastTxId, lastTxInfo.Checksum(), lastTxLogPosition.LogVersion, lastTxLogPosition.ByteOffset, progressReporter, oldFormat, newFormat);
            }
            // update necessary neostore records
            LogPosition logPosition = ReadLastTxLogPosition(migrationLayout);

            UpdateOrAddNeoStoreFieldsAsPartOfMigration(migrationLayout, directoryLayout, versionToMigrateTo, logPosition);
        }
Beispiel #3
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: private void updateOrAddNeoStoreFieldsAsPartOfMigration(org.neo4j.io.layout.DatabaseLayout migrationStructure, org.neo4j.io.layout.DatabaseLayout sourceDirectoryStructure, String versionToMigrateTo, org.neo4j.kernel.impl.transaction.log.LogPosition lastClosedTxLogPosition) throws java.io.IOException
        private void UpdateOrAddNeoStoreFieldsAsPartOfMigration(DatabaseLayout migrationStructure, DatabaseLayout sourceDirectoryStructure, string versionToMigrateTo, LogPosition lastClosedTxLogPosition)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.io.File storeDirNeoStore = sourceDirectoryStructure.metadataStore();
            File storeDirNeoStore = sourceDirectoryStructure.MetadataStore();
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.io.File migrationDirNeoStore = migrationStructure.metadataStore();
            File migrationDirNeoStore = migrationStructure.MetadataStore();

            fileOperation(COPY, _fileSystem, sourceDirectoryStructure, migrationStructure, Iterables.iterable(DatabaseFile.METADATA_STORE), true, ExistingTargetStrategy.SKIP);

            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.UPGRADE_TRANSACTION_ID, MetaDataStore.getRecord(_pageCache, storeDirNeoStore, MetaDataStore.Position.LAST_TRANSACTION_ID));
            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.UPGRADE_TIME, DateTimeHelper.CurrentUnixTimeMillis());

            // Store the checksum of the transaction id the upgrade is at right now. Store it both as
            // LAST_TRANSACTION_CHECKSUM and UPGRADE_TRANSACTION_CHECKSUM. Initially the last transaction and the
            // upgrade transaction will be the same, but imagine this scenario:
            //  - legacy store is migrated on instance A at transaction T
            //  - upgraded store is copied, via backup or HA or whatever to instance B
            //  - instance A performs a transaction
            //  - instance B would like to communicate with A where B's last transaction checksum
            //    is verified on A. A, at this point not having logs from pre-migration era, will need to
            //    know the checksum of transaction T to accommodate for this request from B. A will be able
            //    to look up checksums for transactions succeeding T by looking at its transaction logs,
            //    but T needs to be stored in neostore to be accessible. Obviously this scenario is only
            //    problematic as long as we don't migrate and translate old logs.
            TransactionId lastTxInfo = ReadLastTxInformation(migrationStructure);

            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.LAST_TRANSACTION_CHECKSUM, lastTxInfo.Checksum());
            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.UPGRADE_TRANSACTION_CHECKSUM, lastTxInfo.Checksum());
            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.LAST_TRANSACTION_COMMIT_TIMESTAMP, lastTxInfo.CommitTimestamp());
            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.UPGRADE_TRANSACTION_COMMIT_TIMESTAMP, lastTxInfo.CommitTimestamp());

            // add LAST_CLOSED_TRANSACTION_LOG_VERSION and LAST_CLOSED_TRANSACTION_LOG_BYTE_OFFSET to the migrated
            // NeoStore
            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.LAST_CLOSED_TRANSACTION_LOG_VERSION, lastClosedTxLogPosition.LogVersion);
            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.LAST_CLOSED_TRANSACTION_LOG_BYTE_OFFSET, lastClosedTxLogPosition.ByteOffset);

            // Upgrade version in NeoStore
            MetaDataStore.setRecord(_pageCache, migrationDirNeoStore, MetaDataStore.Position.STORE_VERSION, MetaDataStore.versionStringToLong(versionToMigrateTo));
        }
Beispiel #4
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: void writeLastTxInformation(org.neo4j.io.layout.DatabaseLayout migrationStructure, org.neo4j.kernel.impl.store.TransactionId txInfo) throws java.io.IOException
        internal virtual void WriteLastTxInformation(DatabaseLayout migrationStructure, TransactionId txInfo)
        {
            WriteTxLogCounters(_fileSystem, LastTxInformationFile(migrationStructure), txInfo.TransactionIdConflict(), txInfo.Checksum(), txInfo.CommitTimestamp());
        }