use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.
the class TransactionLogInitializer method appendEmptyTransactionAndCheckPoint.
private void appendEmptyTransactionAndCheckPoint(LogFiles logFiles, String reason) throws IOException {
TransactionId committedTx = store.getLastCommittedTransaction();
long timestamp = committedTx.commitTimestamp();
long transactionId = committedTx.transactionId();
LogFile logFile = logFiles.getLogFile();
TransactionLogWriter transactionLogWriter = logFile.getTransactionLogWriter();
PhysicalTransactionRepresentation emptyTx = emptyTransaction(timestamp);
int checksum = transactionLogWriter.append(emptyTx, BASE_TX_ID, BASE_TX_CHECKSUM);
logFile.forceAfterAppend(LogAppendEvent.NULL);
LogPosition position = transactionLogWriter.getCurrentPosition();
appendCheckpoint(logFiles, reason, position);
try (CursorContext cursorContext = new CursorContext(tracer.createPageCursorTracer(LOGS_UPGRADER_TRACER_TAG))) {
store.setLastCommittedAndClosedTransactionId(transactionId, checksum, timestamp, position.getByteOffset(), position.getLogVersion(), cursorContext);
}
}
use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.
the class CheckPointerImpl method doCheckPoint.
private long doCheckPoint(TriggerInfo triggerInfo) throws IOException {
var databaseTracer = tracers.getDatabaseTracer();
var pageCacheTracer = tracers.getPageCacheTracer();
var versionContext = versionContextSupplier.createVersionContext();
try (var cursorContext = new CursorContext(pageCacheTracer.createPageCursorTracer(CHECKPOINT_TAG), versionContext);
LogCheckPointEvent event = databaseTracer.beginCheckPoint()) {
long[] lastClosedTransaction = metadataProvider.getLastClosedTransaction();
long lastClosedTransactionId = lastClosedTransaction[0];
versionContext.initWrite(lastClosedTransactionId);
LogPosition logPosition = new LogPosition(lastClosedTransaction[1], lastClosedTransaction[2]);
String checkpointReason = triggerInfo.describe(lastClosedTransactionId);
/*
* Check kernel health before going into waiting for transactions to be closed, to avoid
* getting into a scenario where we would await a condition that would potentially never
* happen.
*/
databaseHealth.assertHealthy(IOException.class);
/*
* First we flush the store. If we fail now or during the flush, on recovery we'll find the
* earlier check point and replay from there all the log entries. Everything will be ok.
*/
msgLog.info(checkpointReason + " checkpoint started...");
Stopwatch startTime = Stopwatch.start();
forceOperation.flushAndForce(cursorContext);
/*
* Check kernel health before going to write the next check point. In case of a panic this check point
* will be aborted, which is the safest alternative so that the next recovery will have a chance to
* repair the damages.
*/
databaseHealth.assertHealthy(IOException.class);
checkpointAppender.checkPoint(event, logPosition, clock.instant(), checkpointReason);
threshold.checkPointHappened(lastClosedTransactionId);
long durationMillis = startTime.elapsed(MILLISECONDS);
msgLog.info(checkpointReason + " checkpoint completed in " + duration(durationMillis));
event.checkpointCompleted(durationMillis);
/*
* Prune up to the version pointed from the latest check point,
* since it might be an earlier version than the current log version.
*/
logPruning.pruneLogs(logPosition.getLogVersion());
lastCheckPointedTx = lastClosedTransactionId;
return lastClosedTransactionId;
} catch (Throwable t) {
// Why only log failure here? It's because check point can potentially be made from various
// points of execution e.g. background thread triggering check point if needed and during
// shutdown where it's better to have more control over failure handling.
msgLog.error("Checkpoint failed", t);
throw t;
}
}
use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.
the class RecordStorageMigratorIT method shouldBeAbleToMigrateWithoutErrors.
@ParameterizedTest
@MethodSource("versions")
void shouldBeAbleToMigrateWithoutErrors(String version, LogPosition expectedLogPosition, Function<TransactionId, Boolean> txIdComparator) throws Exception {
// GIVEN a legacy database
Path prepare = testDirectory.directory("prepare");
var fs = testDirectory.getFileSystem();
MigrationTestUtils.prepareSampleLegacyDatabase(version, fs, databaseLayout.databaseDirectory(), prepare);
AssertableLogProvider logProvider = new AssertableLogProvider(true);
LogService logService = new SimpleLogService(logProvider, logProvider);
RecordStoreVersionCheck check = getVersionCheck(pageCache, databaseLayout);
String versionToMigrateFrom = getVersionToMigrateFrom(check);
RecordStorageMigrator migrator = new RecordStorageMigrator(fs, pageCache, CONFIG, logService, jobScheduler, PageCacheTracer.NULL, batchImporterFactory, INSTANCE);
// WHEN migrating
migrator.migrate(databaseLayout, migrationLayout, progressMonitor.startSection("section"), versionToMigrateFrom, getVersionToMigrateTo(check), EMPTY);
migrator.moveMigratedFiles(migrationLayout, databaseLayout, versionToMigrateFrom, getVersionToMigrateTo(check));
// THEN starting the new store should be successful
assertThat(testDirectory.getFileSystem().fileExists(databaseLayout.relationshipGroupDegreesStore())).isTrue();
GBPTreeRelationshipGroupDegreesStore.DegreesRebuilder noRebuildAssertion = new GBPTreeRelationshipGroupDegreesStore.DegreesRebuilder() {
@Override
public void rebuild(RelationshipGroupDegreesStore.Updater updater, CursorContext cursorContext, MemoryTracker memoryTracker) {
throw new IllegalStateException("Rebuild should not be required");
}
@Override
public long lastCommittedTxId() {
try {
return new RecordStorageEngineFactory().readOnlyTransactionIdStore(fs, databaseLayout, pageCache, NULL).getLastCommittedTransactionId();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
};
try (GBPTreeRelationshipGroupDegreesStore groupDegreesStore = new GBPTreeRelationshipGroupDegreesStore(pageCache, databaseLayout.relationshipGroupDegreesStore(), testDirectory.getFileSystem(), immediate(), noRebuildAssertion, writable(), PageCacheTracer.NULL, GBPTreeGenericCountsStore.NO_MONITOR, databaseLayout.getDatabaseName(), counts_store_max_cached_entries.defaultValue())) {
// The rebuild would happen here in start and will throw exception (above) if invoked
groupDegreesStore.start(NULL, INSTANCE);
// The store keeps track of committed transactions.
// It is essential that it starts with the transaction
// that is the last committed one at the upgrade time.
assertEquals(TX_ID, groupDegreesStore.txId());
}
StoreFactory storeFactory = new StoreFactory(databaseLayout, CONFIG, new ScanOnOpenOverwritingIdGeneratorFactory(fs, databaseLayout.getDatabaseName()), pageCache, fs, logService.getInternalLogProvider(), PageCacheTracer.NULL, writable());
storeFactory.openAllNeoStores().close();
assertThat(logProvider).forLevel(ERROR).doesNotHaveAnyLogs();
}
use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.
the class BatchInsertTest method shouldBuildCorrectCountsStoreOnIncrementalImport.
@Test
void shouldBuildCorrectCountsStoreOnIncrementalImport() throws Exception {
// given
Label label = Label.label("Person");
int denseNodeThreshold = dense_node_threshold.defaultValue();
for (int r = 0; r < 3; r++) {
// when
BatchInserter inserter = newBatchInserter(denseNodeThreshold);
try {
for (int i = 0; i < 100; i++) {
inserter.createNode(null, label);
}
} finally {
inserter.shutdown();
}
// then
try (GBPTreeCountsStore countsStore = new GBPTreeCountsStore(pageCache, databaseLayout.countStore(), fs, RecoveryCleanupWorkCollector.immediate(), new CountsBuilder() {
@Override
public void initialize(CountsAccessor.Updater updater, CursorContext cursorContext, MemoryTracker memoryTracker) {
throw new UnsupportedOperationException("Should not be required");
}
@Override
public long lastCommittedTxId() {
return TransactionIdStore.BASE_TX_ID;
}
}, readOnly(), PageCacheTracer.NULL, GBPTreeCountsStore.NO_MONITOR, databaseLayout.getDatabaseName(), 1000)) {
countsStore.start(NULL, INSTANCE);
assertEquals((r + 1) * 100, countsStore.nodeCount(0, NULL));
}
}
}
use of org.neo4j.io.pagecache.context.CursorContext in project neo4j by neo4j.
the class GBPTreeSingleWriterTest method trackPageCacheAccessOnMerge.
@Test
void trackPageCacheAccessOnMerge() throws IOException {
var pageCacheTracer = new DefaultPageCacheTracer();
var cursorContext = new CursorContext(pageCacheTracer.createPageCursorTracer("trackPageCacheAccessOnMerge"));
assertZeroCursor(cursorContext);
try (var gbpTree = new GBPTreeBuilder<>(pageCache, directory.file("index"), layout).build();
var treeWriter = gbpTree.writer(0, cursorContext)) {
treeWriter.merge(new MutableLong(0), new MutableLong(1), ValueMergers.overwrite());
PageCursorTracer cursorTracer = cursorContext.getCursorTracer();
assertThat(cursorTracer.pins()).isEqualTo(5);
assertThat(cursorTracer.unpins()).isEqualTo(4);
assertThat(cursorTracer.hits()).isEqualTo(4);
assertThat(cursorTracer.faults()).isEqualTo(1);
}
}
Aggregations