use of org.neo4j.io.fs.EphemeralFileSystemAbstraction in project neo4j by neo4j.
the class RecoveryRequiredCheckerTest method shouldWantToRecoverBrokenStore.
@Test
void shouldWantToRecoverBrokenStore() throws Exception {
try (EphemeralFileSystemAbstraction ephemeralFs = createAndCrashWithDefaultConfig();
PageCache pageCache = pageCacheExtension.getPageCache(ephemeralFs)) {
RecoveryRequiredChecker recoverer = getRecoveryCheckerWithDefaultConfig(ephemeralFs, pageCache, storageEngineFactory);
assertThat(recoverer.isRecoveryRequiredAt(databaseLayout, INSTANCE)).isEqualTo(true);
}
}
use of org.neo4j.io.fs.EphemeralFileSystemAbstraction in project neo4j by neo4j.
the class RecoveryRequiredCheckerTest method shouldBeAbleToRecoverBrokenStore.
@Test
void shouldBeAbleToRecoverBrokenStore() throws Exception {
try (EphemeralFileSystemAbstraction ephemeralFs = createAndCrashWithDefaultConfig();
PageCache pageCache = pageCacheExtension.getPageCache(ephemeralFs)) {
RecoveryRequiredChecker recoverer = getRecoveryCheckerWithDefaultConfig(ephemeralFs, pageCache, storageEngineFactory);
assertThat(recoverer.isRecoveryRequiredAt(databaseLayout, INSTANCE)).isEqualTo(true);
startStopDatabase(ephemeralFs, storeDir);
assertThat(recoverer.isRecoveryRequiredAt(databaseLayout, INSTANCE)).isEqualTo(false);
}
}
use of org.neo4j.io.fs.EphemeralFileSystemAbstraction in project neo4j by neo4j.
the class BatchInsertersTest method providedFileSystemNotClosedAfterShutdown.
@Test
void providedFileSystemNotClosedAfterShutdown() throws IOException {
try (EphemeralFileSystemAbstraction fs = new EphemeralFileSystemAbstraction()) {
verifyProvidedFileSystemOpenAfterShutdown(inserter(databaseLayout, fs), fs);
verifyProvidedFileSystemOpenAfterShutdown(inserter(databaseLayout, fs, getConfig()), fs);
verifyProvidedFileSystemOpenAfterShutdown(inserter(databaseLayout, fs, getConfig(), getExtensions()), fs);
}
}
use of org.neo4j.io.fs.EphemeralFileSystemAbstraction in project neo4j by neo4j.
the class GBPTreeTest method indexMustBeDirtyWhenCrashedWithChangesSinceLastCheckpoint.
@Test
void indexMustBeDirtyWhenCrashedWithChangesSinceLastCheckpoint() throws Exception {
// GIVEN
try (EphemeralFileSystemAbstraction ephemeralFs = new EphemeralFileSystemAbstraction()) {
ephemeralFs.mkdirs(indexFile.getParent());
PageCache pageCache = pageCacheExtension.getPageCache(ephemeralFs);
EphemeralFileSystemAbstraction snapshot;
try (GBPTree<MutableLong, MutableLong> index = index(pageCache).build()) {
insert(index, 0, 1);
// WHEN
// crash
snapshot = ephemeralFs.snapshot();
}
pageCache.close();
// THEN
MonitorDirty monitorDirty = new MonitorDirty();
pageCache = pageCacheExtension.getPageCache(snapshot);
index(pageCache).with(monitorDirty).build().close();
assertFalse(monitorDirty.cleanOnStart(), "Expected to be dirty on start after crash");
pageCache.close();
}
}
use of org.neo4j.io.fs.EphemeralFileSystemAbstraction in project neo4j by neo4j.
the class GBPTreeRecoveryITBase method doShouldRecoverFromAnything.
private void doShouldRecoverFromAnything(boolean replayRecoveryExactlyFromCheckpoint) throws Exception {
assertInitialized();
// GIVEN
// a tree which has had random updates and checkpoints in it, load generated with specific seed
Path file = directory.file("index");
List<Action> load = generateLoad();
List<Action> shuffledLoad = randomCausalAwareShuffle(load);
int lastCheckPointIndex = indexOfLastCheckpoint(load);
{
// _,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,c,_,_,_,_,_,_,_,_,_,_,_
// ^ ^
// | |------------ crash flush index
// |-------------------------- last checkpoint index
//
PageCache pageCache = createPageCache();
GBPTree<KEY, VALUE> index = createIndex(pageCache, file);
// Execute all actions up to and including last checkpoint ...
execute(shuffledLoad.subList(0, lastCheckPointIndex + 1), index);
// ... a random amount of the remaining "unsafe" actions ...
int numberOfRemainingActions = shuffledLoad.size() - lastCheckPointIndex - 1;
int crashFlushIndex = lastCheckPointIndex + random.nextInt(numberOfRemainingActions) + 1;
execute(shuffledLoad.subList(lastCheckPointIndex + 1, crashFlushIndex), index);
// ... flush ...
pageCache.flushAndForce();
// ... execute the remaining actions
execute(shuffledLoad.subList(crashFlushIndex, shuffledLoad.size()), index);
// ... and finally crash
EphemeralFileSystemAbstraction snapshot = fs.snapshot();
try {
index.close();
pageCache.close();
} finally {
fs.close();
fs = snapshot;
}
}
// WHEN doing recovery
List<Action> recoveryActions;
if (replayRecoveryExactlyFromCheckpoint) {
recoveryActions = recoveryActions(load, lastCheckPointIndex + 1);
} else {
recoveryActions = recoveryActions(load, random.nextInt(lastCheckPointIndex + 1));
}
// first crashing during recovery
int numberOfCrashesDuringRecovery = random.intBetween(0, 3);
for (int i = 0; i < numberOfCrashesDuringRecovery; i++) {
try (PageCache pageCache = createPageCache();
GBPTree<KEY, VALUE> index = createIndex(pageCache, file)) {
int numberOfActionsToRecoverBeforeCrashing = random.intBetween(1, recoveryActions.size());
recover(recoveryActions.subList(0, numberOfActionsToRecoverBeforeCrashing), index);
// ... crash
}
}
// to finally apply all actions after last checkpoint and verify tree
try (PageCache pageCache = createPageCache();
GBPTree<KEY, VALUE> index = createIndex(pageCache, file)) {
recover(recoveryActions, index);
// THEN
// we should end up with a consistent index containing all the stuff load says
index.consistencyCheck(NULL);
long[] /*key,value,key,value...*/
aggregate = expectedSortedAggregatedDataFromGeneratedLoad(load);
try (Seeker<KEY, VALUE> cursor = index.seek(key(Long.MIN_VALUE), key(Long.MAX_VALUE), NULL)) {
for (int i = 0; i < aggregate.length; ) {
assertTrue(cursor.next());
assertEqualsKey(key(aggregate[i++]), cursor.key());
assertEqualsValue(value(aggregate[i++]), cursor.value());
}
assertFalse(cursor.next());
}
}
}
Aggregations