Search in sources :

Example 1 with SchemaStorage

use of org.neo4j.internal.recordstorage.SchemaStorage in project neo4j by neo4j.

the class RecordStorageMigratorIT method mustMigrateSchemaStoreToNewFormat.

@ParameterizedTest
@MethodSource("versions")
void mustMigrateSchemaStoreToNewFormat(String version, LogPosition expectedLogPosition, Function<TransactionId, Boolean> txIdComparator) throws Exception {
    // Given we have an old store full of random schema rules.
    Path prepare = testDirectory.directory("prepare");
    var fs = testDirectory.getFileSystem();
    MigrationTestUtils.prepareSampleLegacyDatabase(version, fs, databaseLayout.databaseDirectory(), prepare);
    // and a state of the migration saying that it has done the actual migration
    LogService logService = NullLogService.getInstance();
    // Uses this special scan-on-open IGF because when the new IndexedIdGenerator was introduced this test would break
    // when trying to open an older store, before doing migration.
    IdGeneratorFactory igf = new ScanOnOpenOverwritingIdGeneratorFactory(fs, databaseLayout.getDatabaseName());
    LogProvider logProvider = logService.getInternalLogProvider();
    // Prepare all the tokens we'll need.
    StoreFactory legacyStoreFactory = new StoreFactory(databaseLayout, CONFIG, igf, pageCache, fs, StandardV3_4.RECORD_FORMATS, logProvider, PageCacheTracer.NULL, writable(), immutable.empty());
    NeoStores stores = legacyStoreFactory.openNeoStores(false, StoreType.LABEL_TOKEN, StoreType.LABEL_TOKEN_NAME, StoreType.RELATIONSHIP_TYPE_TOKEN, StoreType.RELATIONSHIP_TYPE_TOKEN_NAME, StoreType.PROPERTY_KEY_TOKEN, StoreType.PROPERTY_KEY_TOKEN_NAME);
    createTokens(stores.getLabelTokenStore(), MAX_LABEL_ID);
    createTokens(stores.getRelationshipTypeTokenStore(), MAX_RELATIONSHIP_TYPE_ID);
    createTokens(stores.getPropertyKeyTokenStore(), MAX_PROPERTY_KEY_ID);
    stores.close();
    // Prepare the legacy schema store we'll migrate.
    Path storeFile = databaseLayout.schemaStore();
    Path idFile = databaseLayout.idSchemaStore();
    SchemaStore35 schemaStore35 = new SchemaStore35(storeFile, idFile, CONFIG, IdType.SCHEMA, igf, pageCache, logProvider, StandardV3_4.RECORD_FORMATS, writable(), DEFAULT_DATABASE_NAME, immutable.empty());
    schemaStore35.initialise(false, NULL);
    SplittableRandom rng = new SplittableRandom(randomRule.seed());
    LongHashSet indexes = new LongHashSet();
    LongHashSet constraints = new LongHashSet();
    for (int i = 0; i < 10; i++) {
        long id = schemaStore35.nextId(NULL);
        MutableLongSet target = rng.nextInt(3) < 2 ? indexes : constraints;
        target.add(id);
    }
    List<SchemaRule> generatedRules = new ArrayList<>();
    RealIdsRandomSchema randomSchema = new RealIdsRandomSchema(rng, indexes, constraints);
    while (randomSchema.hasMoreIds()) {
        try {
            SchemaRule schemaRule = randomSchema.nextSchemaRule();
            if (schemaRule instanceof ConstraintDescriptor) {
                ConstraintDescriptor constraint = (ConstraintDescriptor) schemaRule;
                if (constraint.isIndexBackedConstraint() && !constraint.asIndexBackedConstraint().hasOwnedIndexId()) {
                    // Filter out constraints that are supposed to own indexes, but don't, because those are illegal to persist.
                    randomSchema.rollback();
                    continue;
                }
            }
            randomSchema.commit();
            generatedRules.add(schemaRule);
            List<DynamicRecord> dynamicRecords = allocateFrom(schemaStore35, schemaRule, NULL);
            for (DynamicRecord dynamicRecord : dynamicRecords) {
                schemaStore35.updateRecord(dynamicRecord, NULL);
            }
        } catch (NoSuchElementException ignore) {
        // We're starting to run low on ids, but just ignore this and loop as along as there are still some left.
        }
    }
    schemaStore35.flush(NULL);
    schemaStore35.close();
    RecordStoreVersionCheck check = getVersionCheck(pageCache, databaseLayout);
    String versionToMigrateFrom = getVersionToMigrateFrom(check);
    MigrationProgressMonitor progressMonitor = SILENT;
    RecordStorageMigrator migrator = new RecordStorageMigrator(fs, pageCache, CONFIG, logService, jobScheduler, PageCacheTracer.NULL, batchImporterFactory, INSTANCE);
    // When we migrate it to the new store format.
    String versionToMigrateTo = getVersionToMigrateTo(check);
    ProgressReporter reporter = progressMonitor.startSection("section");
    migrator.migrate(databaseLayout, migrationLayout, reporter, versionToMigrateFrom, versionToMigrateTo, EMPTY);
    migrator.moveMigratedFiles(migrationLayout, databaseLayout, versionToMigrateFrom, versionToMigrateTo);
    generatedRules.sort(Comparator.comparingLong(SchemaRule::getId));
    // Then the new store should retain an exact representation of the old-format schema rules.
    StoreFactory storeFactory = new StoreFactory(databaseLayout, CONFIG, igf, pageCache, fs, logProvider, PageCacheTracer.NULL, writable());
    try (NeoStores neoStores = storeFactory.openAllNeoStores()) {
        SchemaStore schemaStore = neoStores.getSchemaStore();
        TokenHolders tokenHolders = StoreTokens.readOnlyTokenHolders(neoStores, NULL);
        SchemaStorage storage = new SchemaStorage(schemaStore, tokenHolders, () -> KernelVersion.LATEST);
        List<SchemaRule> migratedRules = new ArrayList<>();
        storage.getAll(NULL).iterator().forEachRemaining(migratedRules::add);
        // Nerf the rule names, since migration may change those around.
        migratedRules = migratedRules.stream().map(r -> r.withName("a")).collect(Collectors.toList());
        generatedRules = generatedRules.stream().map(r -> r.withName("a")).collect(Collectors.toList());
        assertThat(migratedRules).isEqualTo(generatedRules);
    }
}
Also used : DynamicRecord(org.neo4j.kernel.impl.store.record.DynamicRecord) ArrayList(java.util.ArrayList) SchemaRule(org.neo4j.internal.schema.SchemaRule) DefaultIdGeneratorFactory(org.neo4j.internal.id.DefaultIdGeneratorFactory) ScanOnOpenOverwritingIdGeneratorFactory(org.neo4j.internal.id.ScanOnOpenOverwritingIdGeneratorFactory) IdGeneratorFactory(org.neo4j.internal.id.IdGeneratorFactory) StoreFactory(org.neo4j.kernel.impl.store.StoreFactory) SchemaStorage(org.neo4j.internal.recordstorage.SchemaStorage) TokenHolders(org.neo4j.token.TokenHolders) Path(java.nio.file.Path) SchemaStore(org.neo4j.kernel.impl.store.SchemaStore) ProgressReporter(org.neo4j.common.ProgressReporter) SchemaStore35(org.neo4j.kernel.impl.storemigration.legacy.SchemaStore35) AssertableLogProvider(org.neo4j.logging.AssertableLogProvider) NullLogProvider.nullLogProvider(org.neo4j.logging.NullLogProvider.nullLogProvider) LogProvider(org.neo4j.logging.LogProvider) LongHashSet(org.eclipse.collections.impl.set.mutable.primitive.LongHashSet) MutableLongSet(org.eclipse.collections.api.set.primitive.MutableLongSet) MigrationProgressMonitor(org.neo4j.storageengine.migration.MigrationProgressMonitor) NeoStores(org.neo4j.kernel.impl.store.NeoStores) ConstraintDescriptor(org.neo4j.internal.schema.ConstraintDescriptor) SplittableRandom(java.util.SplittableRandom) NullLogService(org.neo4j.logging.internal.NullLogService) SimpleLogService(org.neo4j.logging.internal.SimpleLogService) LogService(org.neo4j.logging.internal.LogService) NoSuchElementException(java.util.NoSuchElementException) ScanOnOpenOverwritingIdGeneratorFactory(org.neo4j.internal.id.ScanOnOpenOverwritingIdGeneratorFactory) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 2 with SchemaStorage

use of org.neo4j.internal.recordstorage.SchemaStorage in project neo4j by neo4j.

the class SchemaChecker method checkSchema.

private void checkSchema(MutableIntObjectMap<MutableIntSet> mandatoryNodeProperties, MutableIntObjectMap<MutableIntSet> mandatoryRelationshipProperties, CursorContext cursorContext) {
    long highId = schemaStore.getHighId();
    try (RecordReader<SchemaRecord> schemaReader = new RecordReader<>(schemaStore, true, cursorContext)) {
        Map<Long, SchemaRecord> indexObligations = new HashMap<>();
        Map<Long, SchemaRecord> constraintObligations = new HashMap<>();
        Map<SchemaRuleKey, SchemaRecord> verifiedRulesWithRecords = new HashMap<>();
        // KernelVersion only controls if there will be an injected NLI on non-upgraded stores. That index is not in the store and will
        // not be found when going through the file in performSchemaCheck anyway so we can use latest KernelVersion here.
        // If an injected NLI exist but is not online that will not be reported, but this is an unlikely corner case that we
        // ignore. The index itself will be checked as long as it is online (it is found by IndexAccessors).
        SchemaStorage schemaStorage = new SchemaStorage(schemaStore, tokenHolders, () -> KernelVersion.LATEST);
        // Build map of obligations and such
        buildObligationsMap(highId, schemaReader, schemaStorage, indexObligations, constraintObligations, verifiedRulesWithRecords, cursorContext);
        // Verify all things, now that we have the complete map of obligations back and forth
        performSchemaCheck(highId, schemaReader, indexObligations, constraintObligations, schemaStorage, mandatoryNodeProperties, mandatoryRelationshipProperties, cursorContext);
    }
}
Also used : SchemaStorage(org.neo4j.internal.recordstorage.SchemaStorage) SchemaRecord(org.neo4j.kernel.impl.store.record.SchemaRecord) HashMap(java.util.HashMap) OptionalLong(java.util.OptionalLong) SchemaRuleKey(org.neo4j.consistency.checking.SchemaRuleKey)

Example 3 with SchemaStorage

use of org.neo4j.internal.recordstorage.SchemaStorage in project neo4j by neo4j.

the class SchemaStorageIT method initStorage.

@BeforeEach
void initStorage() throws Exception {
    try (Transaction transaction = db.beginTx()) {
        TokenWrite tokenWrite = ((InternalTransaction) transaction).kernelTransaction().tokenWrite();
        tokenWrite.propertyKeyGetOrCreateForName(PROP1);
        tokenWrite.propertyKeyGetOrCreateForName(PROP2);
        tokenWrite.labelGetOrCreateForName(LABEL1);
        tokenWrite.labelGetOrCreateForName(LABEL2);
        tokenWrite.relationshipTypeGetOrCreateForName(TYPE1);
        transaction.commit();
    }
    schemaStore = storageEngine.testAccessNeoStores().getSchemaStore();
    storage = new SchemaStorage(schemaStore, tokenHolders, () -> KernelVersion.LATEST);
}
Also used : InternalTransaction(org.neo4j.kernel.impl.coreapi.InternalTransaction) Transaction(org.neo4j.graphdb.Transaction) SchemaStorage(org.neo4j.internal.recordstorage.SchemaStorage) TokenWrite(org.neo4j.internal.kernel.api.TokenWrite) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 4 with SchemaStorage

use of org.neo4j.internal.recordstorage.SchemaStorage in project neo4j by neo4j.

the class CheckerTestBase method setUpDb.

@BeforeEach
void setUpDb() throws Exception {
    TestDatabaseManagementServiceBuilder builder = new TestDatabaseManagementServiceBuilder(directory.homePath());
    builder.setFileSystem(directory.getFileSystem());
    dbms = builder.build();
    db = (GraphDatabaseAPI) dbms.database(GraphDatabaseSettings.DEFAULT_DATABASE_NAME);
    // Create our tokens
    Kernel kernel = db.getDependencyResolver().resolveDependency(Kernel.class);
    try (KernelTransaction tx = kernel.beginTransaction(KernelTransaction.Type.EXPLICIT, LoginContext.AUTH_DISABLED)) {
        initialData(tx);
        tx.commit();
    }
    DependencyResolver dependencies = db.getDependencyResolver();
    neoStores = dependencies.resolveDependency(RecordStorageEngine.class).testAccessNeoStores();
    nodeStore = neoStores.getNodeStore();
    relationshipGroupStore = neoStores.getRelationshipGroupStore();
    propertyStore = neoStores.getPropertyStore();
    relationshipStore = neoStores.getRelationshipStore();
    schemaStore = neoStores.getSchemaStore();
    tokenHolders = dependencies.resolveDependency(TokenHolders.class);
    schemaStorage = new SchemaStorage(schemaStore, tokenHolders, neoStores.getMetaDataStore());
    cacheAccess = new DefaultCacheAccess(NumberArrayFactories.HEAP.newDynamicByteArray(10_000, new byte[MAX_BYTES], INSTANCE), Counts.NONE, NUMBER_OF_THREADS);
    cacheAccess.setCacheSlotSizes(DEFAULT_SLOT_SIZES);
    pageCache = dependencies.resolveDependency(PageCache.class);
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) TestDatabaseManagementServiceBuilder(org.neo4j.test.TestDatabaseManagementServiceBuilder) SchemaStorage(org.neo4j.internal.recordstorage.SchemaStorage) TokenHolders(org.neo4j.token.TokenHolders) Kernel(org.neo4j.kernel.api.Kernel) PageCache(org.neo4j.io.pagecache.PageCache) DependencyResolver(org.neo4j.common.DependencyResolver) DefaultCacheAccess(org.neo4j.consistency.checking.cache.DefaultCacheAccess) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 5 with SchemaStorage

use of org.neo4j.internal.recordstorage.SchemaStorage in project neo4j by neo4j.

the class FulltextIndexProviderTest method indexWithUnknownAnalyzerWillBeMarkedAsFailedOnStartup.

@Test
void indexWithUnknownAnalyzerWillBeMarkedAsFailedOnStartup() throws Exception {
    // Create a full-text index.
    long indexId;
    try (KernelTransactionImplementation transaction = getKernelTransaction()) {
        int[] propertyIds = { propIdHa };
        SchemaDescriptor schema = SchemaDescriptor.fulltext(EntityType.NODE, new int[] { labelIdHa }, propertyIds);
        IndexPrototype prototype = IndexPrototype.forSchema(schema).withIndexType(FULLTEXT).withName(NAME);
        SchemaWrite schemaWrite = transaction.schemaWrite();
        IndexDescriptor index = schemaWrite.indexCreate(prototype);
        indexId = index.getId();
        transaction.success();
    }
    // Modify the full-text index such that it has an analyzer configured that does not exist.
    controller.restartDbms(builder -> {
        var cacheTracer = NULL;
        FileSystemAbstraction fs = builder.getFileSystem();
        DatabaseLayout databaseLayout = Neo4jLayout.of(builder.getHomeDirectory()).databaseLayout(DEFAULT_DATABASE_NAME);
        DefaultIdGeneratorFactory idGenFactory = new DefaultIdGeneratorFactory(fs, RecoveryCleanupWorkCollector.ignore(), databaseLayout.getDatabaseName());
        try (JobScheduler scheduler = JobSchedulerFactory.createInitialisedScheduler();
            PageCache pageCache = StandalonePageCacheFactory.createPageCache(fs, scheduler, cacheTracer)) {
            StoreFactory factory = new StoreFactory(databaseLayout, Config.defaults(), idGenFactory, pageCache, fs, NullLogProvider.getInstance(), cacheTracer, writable());
            var cursorContext = CursorContext.NULL;
            try (NeoStores neoStores = factory.openAllNeoStores(false)) {
                TokenHolders tokens = StoreTokens.readOnlyTokenHolders(neoStores, CursorContext.NULL);
                SchemaStore schemaStore = neoStores.getSchemaStore();
                SchemaStorage storage = new SchemaStorage(schemaStore, tokens, () -> KernelVersion.LATEST);
                IndexDescriptor index = (IndexDescriptor) storage.loadSingleSchemaRule(indexId, CursorContext.NULL);
                Map<String, Value> indexConfigMap = new HashMap<>(index.getIndexConfig().asMap());
                for (Map.Entry<String, Value> entry : indexConfigMap.entrySet()) {
                    if (entry.getKey().contains("analyzer")) {
                        // This analyzer does not exist!
                        entry.setValue(Values.stringValue("bla-bla-lyzer"));
                    }
                }
                index = index.withIndexConfig(IndexConfig.with(indexConfigMap));
                storage.writeSchemaRule(index, cursorContext, INSTANCE);
                schemaStore.flush(cursorContext);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return builder;
    });
    // Verify that the index comes up in a failed state.
    try (Transaction tx = db.beginTx()) {
        IndexDefinition index = tx.schema().getIndexByName(NAME);
        Schema.IndexState indexState = tx.schema().getIndexState(index);
        assertThat(indexState).isEqualTo(Schema.IndexState.FAILED);
        String indexFailure = tx.schema().getIndexFailure(index);
        assertThat(indexFailure).contains("bla-bla-lyzer");
    }
    // Verify that the failed index can be dropped.
    try (Transaction tx = db.beginTx()) {
        tx.schema().getIndexByName(NAME).drop();
        assertThrows(IllegalArgumentException.class, () -> tx.schema().getIndexByName(NAME));
        tx.commit();
    }
    try (Transaction tx = db.beginTx()) {
        assertThrows(IllegalArgumentException.class, () -> tx.schema().getIndexByName(NAME));
    }
    controller.restartDbms();
    try (Transaction tx = db.beginTx()) {
        assertThrows(IllegalArgumentException.class, () -> tx.schema().getIndexByName(NAME));
    }
}
Also used : FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) HashMap(java.util.HashMap) Schema(org.neo4j.graphdb.schema.Schema) IndexPrototype(org.neo4j.internal.schema.IndexPrototype) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) StoreFactory(org.neo4j.kernel.impl.store.StoreFactory) SchemaStorage(org.neo4j.internal.recordstorage.SchemaStorage) IndexDefinition(org.neo4j.graphdb.schema.IndexDefinition) KernelTransactionImplementation(org.neo4j.kernel.impl.api.KernelTransactionImplementation) DatabaseLayout(org.neo4j.io.layout.DatabaseLayout) TokenHolders(org.neo4j.token.TokenHolders) PageCache(org.neo4j.io.pagecache.PageCache) JobScheduler(org.neo4j.scheduler.JobScheduler) SchemaDescriptor(org.neo4j.internal.schema.SchemaDescriptor) SchemaWrite(org.neo4j.internal.kernel.api.SchemaWrite) SchemaStore(org.neo4j.kernel.impl.store.SchemaStore) DefaultIdGeneratorFactory(org.neo4j.internal.id.DefaultIdGeneratorFactory) IndexNotApplicableKernelException(org.neo4j.internal.kernel.api.exceptions.schema.IndexNotApplicableKernelException) KernelException(org.neo4j.exceptions.KernelException) TransactionFailureException(org.neo4j.internal.kernel.api.exceptions.TransactionFailureException) InternalTransaction(org.neo4j.kernel.impl.coreapi.InternalTransaction) Transaction(org.neo4j.graphdb.Transaction) KernelTransaction(org.neo4j.kernel.api.KernelTransaction) NeoStores(org.neo4j.kernel.impl.store.NeoStores) Value(org.neo4j.values.storable.Value) Map(java.util.Map) HashMap(java.util.HashMap) Test(org.junit.jupiter.api.Test)

Aggregations

SchemaStorage (org.neo4j.internal.recordstorage.SchemaStorage)5 TokenHolders (org.neo4j.token.TokenHolders)3 HashMap (java.util.HashMap)2 BeforeEach (org.junit.jupiter.api.BeforeEach)2 Transaction (org.neo4j.graphdb.Transaction)2 DefaultIdGeneratorFactory (org.neo4j.internal.id.DefaultIdGeneratorFactory)2 PageCache (org.neo4j.io.pagecache.PageCache)2 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)2 InternalTransaction (org.neo4j.kernel.impl.coreapi.InternalTransaction)2 NeoStores (org.neo4j.kernel.impl.store.NeoStores)2 SchemaStore (org.neo4j.kernel.impl.store.SchemaStore)2 StoreFactory (org.neo4j.kernel.impl.store.StoreFactory)2 Path (java.nio.file.Path)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 NoSuchElementException (java.util.NoSuchElementException)1 OptionalLong (java.util.OptionalLong)1 SplittableRandom (java.util.SplittableRandom)1 MutableLongSet (org.eclipse.collections.api.set.primitive.MutableLongSet)1 LongHashSet (org.eclipse.collections.impl.set.mutable.primitive.LongHashSet)1