use of org.neo4j.io.layout.DatabaseLayout in project neo4j by neo4j.
the class DumpCommand method execute.
@Override
public void execute() {
var databaseName = database.name();
Path archive = buildArchivePath(databaseName, to.toAbsolutePath());
var memoryTracker = EmptyMemoryTracker.INSTANCE;
Config config = CommandHelpers.buildConfig(ctx, allowCommandExpansion);
DatabaseLayout databaseLayout = Neo4jLayout.of(config).databaseLayout(databaseName);
try {
Validators.CONTAINS_EXISTING_DATABASE.validate(databaseLayout.databaseDirectory());
} catch (IllegalArgumentException e) {
throw new CommandFailedException("Database does not exist: " + databaseName, e);
}
try (FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction()) {
if (fileSystem.fileExists(databaseLayout.file(StoreUpgrader.MIGRATION_DIRECTORY))) {
throw new CommandFailedException("Store migration folder detected - A dump can not be taken during a store migration. Make sure " + "store migration is completed before trying again.");
}
} catch (IOException e) {
wrapIOException(e);
}
try (Closeable ignored = LockChecker.checkDatabaseLock(databaseLayout)) {
checkDbState(databaseLayout, config, memoryTracker);
dump(databaseLayout, archive);
} catch (FileLockException e) {
throw new CommandFailedException("The database is in use. Stop database '" + databaseName + "' and try again.", e);
} catch (IOException e) {
wrapIOException(e);
} catch (CannotWriteException e) {
throw new CommandFailedException("You do not have permission to dump the database.", e);
}
}
use of org.neo4j.io.layout.DatabaseLayout in project neo4j by neo4j.
the class LoadCommandTest method shouldCalculateTheDatabaseDirectoryFromConfig.
@Test
void shouldCalculateTheDatabaseDirectoryFromConfig() throws IOException, CommandFailedException, IncorrectFormat {
Path dataDir = testDirectory.directory("some-other-path");
Path databaseDir = dataDir.resolve("databases/foo");
Path transactionLogsDir = dataDir.resolve(DEFAULT_TX_LOGS_ROOT_DIR_NAME);
Files.createDirectories(databaseDir);
Files.write(configDir.resolve(Config.DEFAULT_CONFIG_FILE_NAME), singletonList(formatProperty(data_directory, dataDir)));
execute("foo", archive);
DatabaseLayout databaseLayout = createDatabaseLayout(dataDir, databaseDir.getParent(), "foo", transactionLogsDir);
verify(loader).load(any(), eq(databaseLayout));
}
use of org.neo4j.io.layout.DatabaseLayout in project neo4j by neo4j.
the class DegreesRebuildFromStoreTest method skipNotUsedRecordsOnDegreeStoreRebuild.
@Test
void skipNotUsedRecordsOnDegreeStoreRebuild() throws Exception {
// given a dataset containing mixed sparse and dense nodes with relationships in random directions,
// where some chains have been marked as having external degrees
int denseThreshold = dense_node_threshold.defaultValue();
DatabaseLayout layout = DatabaseLayout.ofFlat(directory.homePath());
int[] relationshipTypes;
MutableLongLongMap expectedDegrees = LongLongMaps.mutable.empty();
try (Lifespan life = new Lifespan()) {
RecordStorageEngine storageEngine = openStorageEngine(layout, denseThreshold);
relationshipTypes = createRelationshipTypes(storageEngine);
life.add(storageEngine);
generateData(storageEngine, denseThreshold, relationshipTypes);
storageEngine.relationshipGroupDegreesStore().accept((groupId, direction, degree) -> expectedDegrees.put(combinedKeyOnGroupAndDirection(groupId, direction), degree), NULL);
assertThat(expectedDegrees.isEmpty()).isFalse();
RelationshipGroupStore groupStore = storageEngine.testAccessNeoStores().getRelationshipGroupStore();
long highId = groupStore.getHighId();
assertThat(highId).isGreaterThan(1);
for (int i = 10; i < highId; i++) {
RelationshipGroupRecord record = groupStore.getRecord(i, new RelationshipGroupRecord(i), RecordLoad.ALWAYS, NULL);
record.setInUse(false);
groupStore.updateRecord(record, NULL);
}
storageEngine.flushAndForce(NULL);
}
// when
directory.getFileSystem().deleteFile(layout.relationshipGroupDegreesStore());
try (Lifespan life = new Lifespan()) {
RecordStorageEngine storageEngine = assertDoesNotThrow(() -> life.add(openStorageEngine(layout, denseThreshold)));
// then
storageEngine.relationshipGroupDegreesStore().accept((groupId, direction, degree) -> {
long key = combinedKeyOnGroupAndDirection(groupId, direction);
assertThat(expectedDegrees.containsKey(key)).isTrue();
long expectedDegree = expectedDegrees.get(key);
expectedDegrees.remove(key);
assertThat(degree).isEqualTo(expectedDegree);
}, NULL);
assertThat(expectedDegrees.size()).isGreaterThan(0);
}
}
use of org.neo4j.io.layout.DatabaseLayout in project neo4j by neo4j.
the class BatchInserterImplTest method shouldCorrectlyMarkHighIds.
@Test
void shouldCorrectlyMarkHighIds() throws Exception {
// given
DatabaseLayout layout = databaseLayout;
long[] nodeIds = new long[10];
try (var inserter = BatchInserters.inserter(layout, fileSystem, config)) {
Map<String, Object> properties = new HashMap<>();
properties.put("name", "Just some name");
properties.put("some_array", new String[] { "this", "is", "a", "string", "which", "really", "is", "an", "array" });
for (int i = 0; i < nodeIds.length; i++) {
nodeIds[i] = inserter.createNode(properties);
}
}
MutableLongSet nodeIdsSet = LongSets.mutable.of(nodeIds);
// when/then
DatabaseManagementService dbms = new TestDatabaseManagementServiceBuilder(layout.getNeo4jLayout().homeDirectory()).setFileSystem(fileSystem).build();
try {
GraphDatabaseService db = dbms.database(DEFAULT_DATABASE_NAME);
for (long nodeId : nodeIds) {
try (Transaction tx = db.beginTx()) {
tx.getNodeById(nodeId).addLabel(TestLabels.LABEL_ONE);
tx.commit();
}
}
for (int i = 0; i < 5; i++) {
try (Transaction tx = db.beginTx()) {
Node node = tx.createNode();
assertFalse(nodeIdsSet.contains(node.getId()));
tx.commit();
}
}
for (long nodeId : nodeIds) {
try (Transaction tx = db.beginTx()) {
tx.getNodeById(nodeId).delete();
tx.commit();
}
}
} finally {
dbms.shutdown();
}
}
use of org.neo4j.io.layout.DatabaseLayout in project neo4j by neo4j.
the class RecoveryWithTokenIndexesIT method recoverDatabaseWithPersistedTokenIndex.
@Test
void recoverDatabaseWithPersistedTokenIndex() throws Throwable {
// Starting an existing database on 4.3 or newer binaries should make the old label scan store
// into a token index - but there is no schema rule for it in store until after upgrade transaction has been run
// (there is just an injected indexRule in the cache).
// This tests that recovery on a database with the persisted version of the NLI keeps it through recovery.
config = Config.newBuilder().set(allow_single_automatic_upgrade, true).set(allow_upgrade, true).build();
// Database with 10 nodes with label 'label' and 10 relationships with type 'type'.
int numberOfEntities = 10;
GraphDatabaseService database = createDatabaseOfOlderVersion("4-2-data-10-nodes-rels.zip");
DatabaseLayout layout = ((GraphDatabaseAPI) database).databaseLayout();
verifyInjectedNLIExistAndOnline(database);
// Do a write transaction to trigger upgrade transaction.
try (Transaction tx = database.beginTx()) {
tx.createNode();
tx.commit();
}
// Injected index should now have been turned into a real one.
IndexDescriptor persistedNLI = IndexDescriptor.NLI_PROTOTYPE.materialise(1);
verifyIndexExistAndOnline(database, persistedNLI);
managementService.shutdown();
// Remove check point from shutdown, store upgrade, and shutdown done when creating the 4.2 store.
RecoveryHelpers.removeLastCheckpointRecordFromLastLogFile(layout, fileSystem);
RecoveryHelpers.removeLastCheckpointRecordFromLastLogFile(layout, fileSystem);
RecoveryHelpers.removeLastCheckpointRecordFromLastLogFile(layout, fileSystem);
try (PageCache pageCache = pageCacheExtension.getPageCache(fileSystem)) {
recoverDatabaseOfOlderVersion(layout, pageCache);
}
GraphDatabaseService recoveredDatabase = startDatabaseOfOlderVersion();
// Verify that the persisted version of the NLI still exist
verifyIndexExistAndOnline(recoveredDatabase, persistedNLI);
try (Transaction tx = recoveredDatabase.beginTx()) {
assertEquals(numberOfEntities, tx.findNodes(label).stream().count());
assertEquals(numberOfEntities, tx.findRelationships(type).stream().count());
}
}
Aggregations