use of org.neo4j.kernel.impl.transaction.log.TransactionIdStore 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.transaction.log.TransactionIdStore 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));
}
use of org.neo4j.kernel.impl.transaction.log.TransactionIdStore in project neo4j by neo4j.
the class TransactionStateMachineSPITest method doesNotWaitWhenTxIdUpToDate.
@Test
public void doesNotWaitWhenTxIdUpToDate() throws Exception {
long lastClosedTransactionId = 100;
TransactionIdStore txIdStore = fixedTxIdStore(lastClosedTransactionId);
TransactionStateMachineSPI txSpi = createTxSpi(txIdStore, Duration.ZERO, Clock.systemUTC());
Future<Void> result = otherThread.execute(state -> {
txSpi.awaitUpToDate(lastClosedTransactionId - 42);
return null;
});
assertNull(result.get(20, SECONDS));
}
use of org.neo4j.kernel.impl.transaction.log.TransactionIdStore in project neo4j by neo4j.
the class NeoStoreDataSource method start.
@Override
public void start() throws IOException {
dependencies = new Dependencies();
life = new LifeSupport();
schemaIndexProvider = dependencyResolver.resolveDependency(SchemaIndexProvider.class, HighestSelectionStrategy.getInstance());
labelScanStoreProvider = dependencyResolver.resolveDependency(LabelScanStoreProvider.class, new NamedLabelScanStoreSelectionStrategy(config));
dependencyResolver.resolveDependency(LabelScanStoreProvider.class, new DeleteStoresFromOtherLabelScanStoreProviders(labelScanStoreProvider));
IndexConfigStore indexConfigStore = new IndexConfigStore(storeDir, fs);
dependencies.satisfyDependency(lockService);
dependencies.satisfyDependency(indexConfigStore);
life.add(indexConfigStore);
// Monitor listeners
LoggingLogFileMonitor loggingLogMonitor = new LoggingLogFileMonitor(msgLog);
monitors.addMonitorListener(loggingLogMonitor);
life.add(new Delegate(Lifecycles.multiple(indexProviders.values())));
// Upgrade the store before we begin
RecordFormats formats = selectStoreFormats(config, storeDir, fs, pageCache, logService);
upgradeStore(formats);
// Build all modules and their services
StorageEngine storageEngine = null;
try {
UpdateableSchemaState updateableSchemaState = new KernelSchemaStateStore(logProvider);
SynchronizedArrayIdOrderingQueue legacyIndexTransactionOrdering = new SynchronizedArrayIdOrderingQueue(20);
storageEngine = buildStorageEngine(propertyKeyTokenHolder, labelTokens, relationshipTypeTokens, legacyIndexProviderLookup, indexConfigStore, updateableSchemaState::clear, legacyIndexTransactionOrdering);
LogEntryReader<ReadableClosablePositionAwareChannel> logEntryReader = new VersionAwareLogEntryReader<>(storageEngine.commandReaderFactory());
TransactionIdStore transactionIdStore = dependencies.resolveDependency(TransactionIdStore.class);
LogVersionRepository logVersionRepository = dependencies.resolveDependency(LogVersionRepository.class);
NeoStoreTransactionLogModule transactionLogModule = buildTransactionLogs(storeDir, config, logProvider, scheduler, fs, storageEngine, logEntryReader, legacyIndexTransactionOrdering, transactionIdStore, logVersionRepository);
transactionLogModule.satisfyDependencies(dependencies);
buildRecovery(fs, transactionIdStore, logVersionRepository, monitors.newMonitor(Recovery.Monitor.class), monitors.newMonitor(PositionToRecoverFrom.Monitor.class), transactionLogModule.logFiles(), startupStatistics, storageEngine, logEntryReader, transactionLogModule.logicalTransactionStore());
// At the time of writing this comes from the storage engine (IndexStoreView)
PropertyAccessor propertyAccessor = dependencies.resolveDependency(PropertyAccessor.class);
final NeoStoreKernelModule kernelModule = buildKernel(transactionLogModule.transactionAppender(), dependencies.resolveDependency(IndexingService.class), storageEngine.storeReadLayer(), updateableSchemaState, dependencies.resolveDependency(LabelScanStore.class), storageEngine, indexConfigStore, transactionIdStore, availabilityGuard, clock, propertyAccessor);
kernelModule.satisfyDependencies(dependencies);
// Do these assignments last so that we can ensure no cyclical dependencies exist
this.storageEngine = storageEngine;
this.transactionLogModule = transactionLogModule;
this.kernelModule = kernelModule;
dependencies.satisfyDependency(this);
dependencies.satisfyDependency(updateableSchemaState);
dependencies.satisfyDependency(storageEngine.storeReadLayer());
dependencies.satisfyDependency(logEntryReader);
dependencies.satisfyDependency(storageEngine);
} catch (Throwable e) {
// Something unexpected happened during startup
msgLog.warn("Exception occurred while setting up store modules. Attempting to close things down.", e);
try {
// Close the neostore, so that locks are released properly
if (storageEngine != null) {
storageEngine.forceClose();
}
} catch (Exception closeException) {
msgLog.error("Couldn't close neostore after startup failure", closeException);
}
throw Exceptions.launderedException(e);
}
// NOTE: please make sure this is performed after having added everything to the life, in fact we would like
// to perform the checkpointing as first step when the life is shutdown.
life.add(lifecycleToTriggerCheckPointOnShutdown());
try {
life.start();
} catch (Throwable e) {
// Something unexpected happened during startup
msgLog.warn("Exception occurred while starting the datasource. Attempting to close things down.", e);
try {
life.shutdown();
// Close the neostore, so that locks are released properly
storageEngine.forceClose();
} catch (Exception closeException) {
msgLog.error("Couldn't close neostore after startup failure", closeException);
}
throw Exceptions.launderedException(e);
}
/*
* At this point recovery has completed and the datasource is ready for use. Whatever panic might have
* happened before has been healed. So we can safely set the kernel health to ok.
* This right now has any real effect only in the case of internal restarts (for example, after a store copy
* in the case of HA). Standalone instances will have to be restarted by the user, as is proper for all
* kernel panics.
*/
databaseHealth.healed();
}
use of org.neo4j.kernel.impl.transaction.log.TransactionIdStore in project neo4j by neo4j.
the class ResponsePackerTest method shouldHaveFixedTargetTransactionIdEvenIfLastTransactionIdIsMoving.
@Test
public void shouldHaveFixedTargetTransactionIdEvenIfLastTransactionIdIsMoving() throws Exception {
// GIVEN
LogicalTransactionStore transactionStore = mock(LogicalTransactionStore.class);
long lastAppliedTransactionId = 5L;
TransactionCursor endlessCursor = new EndlessCursor(lastAppliedTransactionId + 1);
when(transactionStore.getTransactions(anyLong())).thenReturn(endlessCursor);
final long targetTransactionId = 8L;
final TransactionIdStore transactionIdStore = new DeadSimpleTransactionIdStore(targetTransactionId, 0, BASE_TX_COMMIT_TIMESTAMP, 0, 0);
ResponsePacker packer = new ResponsePacker(transactionStore, transactionIdStore, Suppliers.singleton(StoreIdTestFactory.newStoreIdForCurrentVersion()));
// WHEN
Response<Object> response = packer.packTransactionStreamResponse(requestContextStartingAt(5L), null);
final AtomicLong nextExpectedVisit = new AtomicLong(lastAppliedTransactionId);
response.accept(new Response.Handler() {
@Override
public void obligation(long txId) throws IOException {
fail("Should not be called");
}
@Override
public Visitor<CommittedTransactionRepresentation, Exception> transactions() {
return new Visitor<CommittedTransactionRepresentation, Exception>() {
@Override
public boolean visit(CommittedTransactionRepresentation element) {
// THEN
long txId = element.getCommitEntry().getTxId();
assertThat(txId, lessThanOrEqualTo(targetTransactionId));
assertEquals(nextExpectedVisit.incrementAndGet(), txId);
// Move the target transaction id forward one step, effectively always keeping it out of reach
transactionIdStore.setLastCommittedAndClosedTransactionId(transactionIdStore.getLastCommittedTransactionId() + 1, 0, BASE_TX_COMMIT_TIMESTAMP, 3, 4);
return true;
}
};
}
});
}
Aggregations