use of org.neo4j.kernel.impl.store.TransactionId in project neo4j by neo4j.
the class StoreMigrator method migrate.
@Override
public void migrate(File storeDir, File migrationDir, MigrationProgressMonitor.Section progressMonitor, String versionToMigrateFrom, String versionToMigrateTo) throws IOException {
if (versionToMigrateFrom.equals(StandardV2_0.STORE_VERSION) || versionToMigrateFrom.equals(StandardV2_1.STORE_VERSION) || versionToMigrateFrom.equals(StandardV2_2.STORE_VERSION)) {
// These versions are not supported for block devices.
CustomIOConfigValidator.assertCustomIOConfigNotUsed(config, CUSTOM_IO_EXCEPTION_MESSAGE);
}
// Extract information about the last transaction from legacy neostore
File neoStore = new File(storeDir, MetaDataStore.DEFAULT_NAME);
long lastTxId = MetaDataStore.getRecord(pageCache, neoStore, Position.LAST_TRANSACTION_ID);
TransactionId lastTxInfo = extractTransactionIdInformation(neoStore, storeDir, lastTxId);
LogPosition lastTxLogPosition = extractTransactionLogPosition(neoStore, storeDir, lastTxId);
// Write the tx checksum to file in migrationDir, because we need it later when moving files into storeDir
writeLastTxInformation(migrationDir, lastTxInfo);
writeLastTxLogPosition(migrationDir, 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(storeDir, migrationDir, lastTxId, lastTxInfo.checksum(), lastTxLogPosition.getLogVersion(), lastTxLogPosition.getByteOffset(), progressMonitor, oldFormat, newFormat);
}
if (versionToMigrateFrom.equals(StandardV2_1.STORE_VERSION)) {
removeDuplicateEntityProperties(storeDir, migrationDir, pageCache, schemaIndexProvider, oldFormat);
}
// DO NOT migrate logs. LegacyLogs is able to migrate logs, but only changes its format, not any
// contents of it, and since the record format has changed there would be a mismatch between the
// commands in the log and the contents in the store. If log migration is to be performed there
// must be a proper translation happening while doing so.
}
use of org.neo4j.kernel.impl.store.TransactionId in project neo4j by neo4j.
the class KernelTransactions method newInstance.
public KernelTransaction newInstance(KernelTransaction.Type type, SecurityContext securityContext, long timeout) {
assertCurrentThreadIsNotBlockingNewTransactions();
SecurityContext frozenSecurityContext = securityContext.freeze();
try {
while (!newTransactionsLock.readLock().tryLock(1, TimeUnit.SECONDS)) {
assertRunning();
}
try {
assertRunning();
TransactionId lastCommittedTransaction = transactionIdStore.getLastCommittedTransaction();
KernelTransactionImplementation tx = localTxPool.acquire();
StatementLocks statementLocks = statementLocksFactory.newInstance();
tx.initialize(lastCommittedTransaction.transactionId(), lastCommittedTransaction.commitTimestamp(), statementLocks, type, frozenSecurityContext, timeout);
return tx;
} finally {
newTransactionsLock.readLock().unlock();
}
} catch (InterruptedException ie) {
Thread.interrupted();
throw new TransactionFailureException("Fail to start new transaction.", ie);
}
}
use of org.neo4j.kernel.impl.store.TransactionId in project neo4j by neo4j.
the class SwitchToSlave method checkDataConsistencyWithMaster.
void checkDataConsistencyWithMaster(URI availableMasterId, Master master, StoreId storeId, TransactionIdStore transactionIdStore) {
TransactionId myLastCommittedTxData = transactionIdStore.getLastCommittedTransaction();
long myLastCommittedTx = myLastCommittedTxData.transactionId();
HandshakeResult handshake;
try (Response<HandshakeResult> response = master.handshake(myLastCommittedTx, storeId)) {
handshake = response.response();
requestContextFactory.setEpoch(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 (RuntimeException e) {
// server-side exception
if (e.getCause() instanceof 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.getCause());
}
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, true);
}
use of org.neo4j.kernel.impl.store.TransactionId in project neo4j by neo4j.
the class SwitchToSlaveBranchThenCopyTest method shouldHandleBranchedStoreWhenMyStoreIdDiffersFromMasterStoreId.
@Test
@SuppressWarnings("unchecked")
public void shouldHandleBranchedStoreWhenMyStoreIdDiffersFromMasterStoreId() throws Throwable {
// Given
SwitchToSlaveBranchThenCopy switchToSlave = newSwitchToSlaveSpy();
URI me = new URI("cluster://localhost?serverId=2");
MasterClient masterClient = mock(MasterClient.class);
Response<HandshakeResult> response = mock(Response.class);
when(response.response()).thenReturn(new HandshakeResult(1, 2));
when(masterClient.handshake(anyLong(), any(StoreId.class))).thenReturn(response);
StoreId storeId = newStoreIdForCurrentVersion(1, 2, 3, 4);
TransactionIdStore transactionIdStore = mock(TransactionIdStore.class);
when(transactionIdStore.getLastCommittedTransaction()).thenReturn(new TransactionId(42, 42, 42));
when(transactionIdStore.getLastCommittedTransactionId()).thenReturn(TransactionIdStore.BASE_TX_ID);
// When
try {
switchToSlave.checkDataConsistency(masterClient, transactionIdStore, storeId, new URI("cluster://localhost?serverId=1"), me, CancellationRequest.NEVER_CANCELLED);
fail("Should have thrown " + MismatchingStoreIdException.class.getSimpleName() + " exception");
} catch (MismatchingStoreIdException e) {
// good we got the expected exception
}
// Then
verify(switchToSlave).stopServicesAndHandleBranchedStore(any(BranchedDataPolicy.class));
}
use of org.neo4j.kernel.impl.store.TransactionId in project neo4j by neo4j.
the class SwitchToSlaveBranchThenCopyTest method newSwitchToSlaveSpy.
@SuppressWarnings("unchecked")
private SwitchToSlaveBranchThenCopy newSwitchToSlaveSpy(PageCache pageCacheMock, StoreCopyClient storeCopyClient) throws IOException {
ClusterMembers clusterMembers = mock(ClusterMembers.class);
ClusterMember master = mock(ClusterMember.class);
when(master.getStoreId()).thenReturn(storeId);
when(master.getHARole()).thenReturn(HighAvailabilityModeSwitcher.MASTER);
when(master.hasRole(eq(HighAvailabilityModeSwitcher.MASTER))).thenReturn(true);
when(master.getInstanceId()).thenReturn(new InstanceId(1));
when(clusterMembers.getMembers()).thenReturn(singletonList(master));
Dependencies resolver = new Dependencies();
resolver.satisfyDependencies(requestContextFactory, clusterMembers, mock(TransactionObligationFulfiller.class), mock(OnlineBackupKernelExtension.class), mock(IndexConfigStore.class), mock(TransactionCommittingResponseUnpacker.class), mock(DataSourceManager.class), mock(StoreLockerLifecycleAdapter.class), mock(FileSystemWatcherService.class));
NeoStoreDataSource dataSource = mock(NeoStoreDataSource.class);
when(dataSource.getStoreId()).thenReturn(storeId);
TransactionStats transactionCounters = mock(TransactionStats.class);
when(transactionCounters.getNumberOfActiveTransactions()).thenReturn(0L);
Response<HandshakeResult> response = mock(Response.class);
when(response.response()).thenReturn(new HandshakeResult(42, 2));
when(masterClient.handshake(anyLong(), any(StoreId.class))).thenReturn(response);
when(masterClient.getProtocolVersion()).thenReturn(MasterClient320.PROTOCOL_VERSION);
TransactionIdStore transactionIdStoreMock = mock(TransactionIdStore.class);
// note that the checksum (the second member of the array) is the same as the one in the handshake mock above
when(transactionIdStoreMock.getLastCommittedTransaction()).thenReturn(new TransactionId(42, 42, 42));
MasterClientResolver masterClientResolver = mock(MasterClientResolver.class);
when(masterClientResolver.instantiate(anyString(), anyInt(), anyString(), any(Monitors.class), any(StoreId.class), any(LifeSupport.class))).thenReturn(masterClient);
return spy(new SwitchToSlaveBranchThenCopy(new File(""), NullLogService.getInstance(), configMock(), resolver, mock(HaIdGeneratorFactory.class), mock(DelegateInvocationHandler.class), mock(ClusterMemberAvailability.class), requestContextFactory, pullerFactory, masterClientResolver, mock(SwitchToSlave.Monitor.class), storeCopyClient, Suppliers.singleton(dataSource), Suppliers.singleton(transactionIdStoreMock), slave -> {
SlaveServer server = mock(SlaveServer.class);
InetSocketAddress inetSocketAddress = InetSocketAddress.createUnresolved("localhost", 42);
when(server.getSocketAddress()).thenReturn(inetSocketAddress);
return server;
}, updatePuller, pageCacheMock, mock(Monitors.class), transactionCounters));
}
Aggregations