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); }
//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); }
//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)); }
//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()); }