Ejemplo n.º 1
0
 // We do this last to ensure noone is cheating with dependency access
 private void satisfyDependencies(Object... modules) {
   for (Object module : modules) {
     for (Method method : module.getClass().getMethods()) {
       if (!method.getDeclaringClass().equals(Object.class)) {
         try {
           dependencies.satisfyDependency(method.invoke(module));
         } catch (IllegalAccessException | InvocationTargetException e) {
           throw new RuntimeException(e);
         }
       }
     }
   }
 }
Ejemplo n.º 2
0
  private TransactionLogModule buildTransactionLogs(
      Config config,
      Logging logging,
      LabelScanStore labelScanStore,
      FileSystemAbstraction fileSystemAbstraction,
      NeoStore neoStore,
      CacheAccessBackDoor cacheAccess,
      IndexingService indexingService,
      Iterable<IndexImplementation> indexProviders) {
    File directory = config.get(GraphDatabaseSettings.store_dir);
    TransactionMetadataCache transactionMetadataCache = new TransactionMetadataCache(1000, 100_000);
    final PhysicalLogFiles logFiles =
        new PhysicalLogFiles(directory, PhysicalLogFile.DEFAULT_NAME, fileSystemAbstraction);

    IdOrderingQueue legacyIndexTransactionOrdering = new SynchronizedArrayIdOrderingQueue(20);
    final TransactionRepresentationStoreApplier storeApplier =
        dependencies.satisfyDependency(
            new TransactionRepresentationStoreApplier(
                indexingService,
                labelScanStore,
                neoStore,
                cacheAccess,
                lockService,
                legacyIndexProviderLookup,
                indexConfigStore,
                legacyIndexTransactionOrdering));

    final PhysicalLogFile logFile =
        new PhysicalLogFile(
            fileSystemAbstraction,
            logFiles,
            config.get(GraphDatabaseSettings.logical_log_rotation_threshold),
            neoStore,
            neoStore,
            physicalLogMonitor,
            transactionMetadataCache);

    final PhysicalLogFileInformation.SPI logInformation =
        new PhysicalLogFileInformation.SPI() {
          @Override
          public long getTimestampForVersion(long version) throws IOException {
            LogPosition position = new LogPosition(version, LOG_HEADER_SIZE);
            try (ReadableVersionableLogChannel channel = logFile.getReader(position)) {
              final LogEntryReader<ReadableVersionableLogChannel> reader =
                  new LogEntryReaderFactory().versionable();
              LogEntry entry;
              while ((entry = reader.readLogEntry(channel)) != null) {
                if (entry instanceof LogEntryStart) {
                  return entry.<LogEntryStart>as().getTimeWritten();
                }
              }
            }
            return -1;
          }
        };
    final LogFileInformation logFileInformation =
        new PhysicalLogFileInformation(
            logFiles, transactionMetadataCache, neoStore, logInformation);

    LogPruneStrategy logPruneStrategy =
        LogPruneStrategyFactory.fromConfigValue(
            fs,
            logFileInformation,
            logFiles,
            neoStore,
            config.get(GraphDatabaseSettings.keep_logical_logs));

    monitors.addMonitorListener(new LogPruning(logPruneStrategy));

    final LogRotationControl logRotationControl =
        new LogRotationControl(neoStore, indexingService, labelScanStore, indexProviders);

    final LogRotation logRotation =
        new LogRotationImpl(
            monitors.newMonitor(LogRotation.Monitor.class), logFile, logRotationControl);

    final LogicalTransactionStore logicalTransactionStore =
        new PhysicalLogicalTransactionStore(
            logFile,
            logRotation,
            transactionMetadataCache,
            neoStore,
            legacyIndexTransactionOrdering,
            config.get(GraphDatabaseSettings.batched_writes));

    life.add(logFile);
    life.add(logicalTransactionStore);

    return new TransactionLogModule() {
      @Override
      public TransactionRepresentationStoreApplier storeApplier() {
        return storeApplier;
      }

      @Override
      public LogicalTransactionStore logicalTransactionStore() {
        return logicalTransactionStore;
      }

      @Override
      public LogFileInformation logFileInformation() {
        return logFileInformation;
      }

      @Override
      public PhysicalLogFiles logFiles() {
        return logFiles;
      }

      @Override
      public LogFile logFile() {
        return logFile;
      }

      @Override
      public LogRotationControl logRotationControl() {
        return logRotationControl;
      }

      @Override
      public LogRotation logRotation() {
        return logRotation;
      }
    };
  }
Ejemplo n.º 3
0
  @Override
  public void start() throws IOException {
    dependencies = new Dependencies();
    life = new LifeSupport();
    storeDir = config.get(Configuration.store_dir);
    File store = config.get(Configuration.neo_store);
    if (!storeFactory.storeExists()) {
      storeFactory.createNeoStore().close();
    }

    indexProvider =
        dependencyResolver.resolveDependency(
            SchemaIndexProvider.class, SchemaIndexProvider.HIGHEST_PRIORITIZED_OR_NONE);

    // Monitor listeners
    LoggingLogFileMonitor loggingLogMonitor =
        new LoggingLogFileMonitor(logging.getMessagesLog(getClass()));
    monitors.addMonitorListener(loggingLogMonitor);
    monitors.addMonitorListener(
        new RecoveryVisitor.Monitor() {
          @Override
          public void transactionRecovered(long txId) {
            recoveredCount.incrementAndGet();
          }
        });

    // Upgrade the store before we begin
    upgradeStore(store, storeMigrationProcess, indexProvider);

    // Build all modules and their services
    try {
      final NeoStoreModule neoStoreModule =
          buildNeoStore(storeFactory, labelTokens, relationshipTypeTokens, propertyKeyTokenHolder);
      this.neoStoreModule =
          neoStoreModule; // TODO The only reason this is here is because of the provider-stuff for
      // DiskLayer. Remove when possible

      CacheModule cacheModule =
          buildCaches(
              neoStoreModule.neoStore(),
              cacheProvider,
              nodeManager,
              labelTokens,
              relationshipTypeTokens,
              propertyKeyTokenHolder);

      IndexingModule indexingModule =
          buildIndexing(
              config,
              scheduler,
              indexProvider,
              lockService,
              tokenNameLookup,
              logging,
              indexingServiceMonitor,
              neoStoreModule.neoStore(),
              cacheModule.updateableSchemaState());

      StoreLayerModule storeLayerModule =
          buildStoreLayer(
              config,
              neoStoreModule.neoStore(),
              cacheModule.persistenceCache(),
              propertyKeyTokenHolder,
              labelTokens,
              relationshipTypeTokens,
              indexingModule.indexingService(),
              cacheModule.schemaCache());

      TransactionLogModule transactionLogModule =
          buildTransactionLogs(
              config,
              logging,
              indexingModule.labelScanStore(),
              fs,
              neoStoreModule.neoStore(),
              cacheModule.cacheAccess(),
              indexingModule.indexingService(),
              indexProviders.values());

      buildRecovery(
          fs,
          cacheModule.cacheAccess(),
          indexingModule.indexingService(),
          indexingModule.labelScanStore(),
          neoStoreModule.neoStore(),
          monitors.newMonitor(RecoveryVisitor.Monitor.class),
          monitors.newMonitor(Recovery.Monitor.class),
          transactionLogModule.logFiles(),
          transactionLogModule.logRotationControl(),
          startupStatistics);

      KernelModule kernelModule =
          buildKernel(
              indexingModule.integrityValidator(),
              transactionLogModule.logicalTransactionStore(),
              neoStoreModule.neoStore(),
              transactionLogModule.storeApplier(),
              indexingModule.indexingService(),
              storeLayerModule.storeLayer(),
              cacheModule.updateableSchemaState(),
              indexingModule.labelScanStore(),
              cacheModule.persistenceCache(),
              indexingModule.schemaIndexProviderMap());

      // Do these assignments last so that we can ensure no cyclical dependencies exist
      this.cacheModule = cacheModule;
      this.indexingModule = indexingModule;
      this.storeLayerModule = storeLayerModule;
      this.transactionLogModule = transactionLogModule;
      this.kernelModule = kernelModule;

      dependencies.satisfyDependency(this);
      satisfyDependencies(
          neoStoreModule,
          cacheModule,
          indexingModule,
          storeLayerModule,
          transactionLogModule,
          kernelModule);
    } catch (Throwable e) { // Something unexpected happened during startup
      try { // Close the neostore, so that locks are released properly
        neoStoreModule.neoStore().close();
      } catch (Exception closeException) {
        msgLog.logMessage("Couldn't close neostore after startup failure");
      }
      throw Exceptions.launderedException(e);
    }

    try {
      life.start();
    } catch (Throwable e) { // Something unexpected happened during startup

      try { // Close the neostore, so that locks are released properly
        neoStoreModule.neoStore().close();
      } catch (Exception closeException) {
        msgLog.logMessage("Couldn't close neostore after startup failure");
      }
      throw Exceptions.launderedException(e);
    }
  }
Ejemplo n.º 4
0
  @Override
  public void start() throws IOException {
    life = new LifeSupport();
    readOnly = config.get(Configuration.read_only);
    storeDir = config.get(Configuration.store_dir);
    File store = config.get(Configuration.neo_store);
    if (!storeFactory.storeExists()) {
      storeFactory.createNeoStore().close();
    }
    indexProvider =
        dependencyResolver.resolveDependency(
            SchemaIndexProvider.class, SchemaIndexProvider.HIGHEST_PRIORITIZED_OR_NONE);
    storeMigrationProcess.addParticipant(indexProvider.storeMigrationParticipant());
    // TODO: Build a real provider map
    final DefaultSchemaIndexProviderMap providerMap =
        new DefaultSchemaIndexProviderMap(indexProvider);
    storeMigrationProcess.migrateIfNeeded(store.getParentFile());
    neoStore = dependencies.satisfyDependency(storeFactory.newNeoStore(false));
    dependencies.satisfyDependency(TransactionIdStore.class, neoStore);

    schemaCache = new SchemaCache(Collections.<SchemaRule>emptyList());

    nodeCache = new AutoLoadingCache<>(cacheProvider.node(), nodeLoader(neoStore.getNodeStore()));
    relationshipCache =
        new AutoLoadingCache<>(
            cacheProvider.relationship(), relationshipLoader(neoStore.getRelationshipStore()));
    RelationshipLoader relationshipLoader =
        new RelationshipLoader(relationshipCache, new RelationshipChainLoader(neoStore));
    PersistenceCache persistenceCache =
        new PersistenceCache(
            nodeCache,
            relationshipCache,
            nodeManager,
            relationshipLoader,
            propertyKeyTokenHolder,
            relationshipTypeTokens,
            labelTokens);
    CacheAccessBackDoor cacheAccess =
        new BridgingCacheAccess(schemaCache, updateableSchemaState, persistenceCache);
    try {
      indexingService =
          new IndexingService(
              scheduler,
              providerMap,
              new NeoStoreIndexStoreView(lockService, neoStore),
              tokenNameLookup,
              updateableSchemaState,
              indexRuleLoader(),
              logging,
              indexingServiceMonitor); // TODO 2.2-future What index rules should be
      final IntegrityValidator integrityValidator =
          new IntegrityValidator(neoStore, indexingService);
      labelScanStore =
          dependencyResolver
              .resolveDependency(
                  LabelScanStoreProvider.class, LabelScanStoreProvider.HIGHEST_PRIORITIZED)
              .getLabelScanStore();
      fileListing =
          new NeoStoreFileListing(
              storeDir, labelScanStore, indexingService, legacyIndexProviderLookup);
      Provider<NeoStore> neoStoreProvider =
          new Provider<NeoStore>() {
            @Override
            public NeoStore instance() {
              return getNeoStore();
            }
          };

      if (config.get(GraphDatabaseSettings.cache_type).equals(CacheLayer.EXPERIMENTAL_OFF)) {
        storeLayer =
            new DiskLayer(
                propertyKeyTokenHolder,
                labelTokens,
                relationshipTypeTokens,
                new SchemaStorage(neoStore.getSchemaStore()),
                neoStoreProvider,
                indexingService);
      } else {
        storeLayer =
            new CacheLayer(
                new DiskLayer(
                    propertyKeyTokenHolder,
                    labelTokens,
                    relationshipTypeTokens,
                    new SchemaStorage(neoStore.getSchemaStore()),
                    neoStoreProvider,
                    indexingService),
                persistenceCache,
                indexingService,
                schemaCache);
      }

      LegacyPropertyTrackers legacyPropertyTrackers =
          new LegacyPropertyTrackers(
              propertyKeyTokenHolder,
              nodeManager.getNodePropertyTrackers(),
              nodeManager.getRelationshipPropertyTrackers(),
              nodeManager);
      StatisticsService statisticsService =
          new StatisticsServiceRepository(fs, config, storeLayer, scheduler).loadStatistics();
      final NeoStoreTransactionContextSupplier neoStoreTransactionContextSupplier =
          new NeoStoreTransactionContextSupplier(neoStore);

      final TransactionHooks hooks = new TransactionHooks();
      File directory = config.get(GraphDatabaseSettings.store_dir);
      TransactionMetadataCache transactionMetadataCache =
          new TransactionMetadataCache(1000, 100_000);
      PhysicalLogFiles logFiles = new PhysicalLogFiles(directory, PhysicalLogFile.DEFAULT_NAME, fs);

      LogFileInformation logFileInformation =
          dependencies.satisfyDependency(
              LogFileInformation.class,
              new PhysicalLogFileInformation(
                  logFiles,
                  transactionMetadataCache,
                  neoStore,
                  new PhysicalLogFileInformation.SPI() {
                    @Override
                    public long getTimestampForVersion(long version) throws IOException {
                      LogPosition position = new LogPosition(version, LOG_HEADER_SIZE);
                      try (ReadableLogChannel channel = logFile.getReader(position)) {
                        LogEntryReader<ReadableLogChannel> reader =
                            new VersionAwareLogEntryReader();
                        LogEntry entry;
                        while ((entry = reader.readLogEntry(channel)) != null) {
                          if (entry instanceof LogEntryStart) {
                            return ((LogEntryStart) entry).getTimeWritten();
                          }
                        }
                      }
                      return -1;
                    }
                  }));

      LogPruneStrategy logPruneStrategy =
          LogPruneStrategyFactory.fromConfigValue(
              fs,
              logFileInformation,
              logFiles,
              neoStore,
              config.get(GraphDatabaseSettings.keep_logical_logs));

      final TransactionRepresentationStoreApplier storeApplier =
          dependencies.satisfyDependency(
              new TransactionRepresentationStoreApplier(
                  indexingService,
                  labelScanStore,
                  neoStore,
                  cacheAccess,
                  lockService,
                  legacyIndexProviderLookup,
                  indexConfigStore,
                  DEFAULT_HIGH_ID_TRACKING));

      LoggingLogFileMonitor logMonitor =
          new LoggingLogFileMonitor(logging.getMessagesLog(getClass()));
      RecoveryVisitor recoveryVisitor =
          new RecoveryVisitor(neoStore, storeApplier, recoveredCount, logMonitor);
      Visitor<ReadableLogChannel, IOException> logFileRecoverer =
          new LogFileRecoverer(new VersionAwareLogEntryReader(), recoveryVisitor);
      logFile =
          dependencies.satisfyDependency(
              new PhysicalLogFile(
                  fs,
                  logFiles,
                  config.get(GraphDatabaseSettings.logical_log_rotation_threshold),
                  logPruneStrategy,
                  neoStore,
                  neoStore,
                  logMonitor,
                  this,
                  transactionMetadataCache,
                  logFileRecoverer));

      final LogicalTransactionStore logicalTransactionStore =
          dependencies.satisfyDependency(
              LogicalTransactionStore.class,
              new PhysicalLogicalTransactionStore(
                  logFile,
                  txIdGenerator,
                  transactionMetadataCache,
                  neoStore,
                  config.get(GraphDatabaseSettings.batched_writes)));

      TransactionCommitProcess transactionCommitProcess =
          dependencies.satisfyDependency(
              TransactionCommitProcess.class,
              commitProcessFactory.create(
                  logicalTransactionStore,
                  kernelHealth,
                  neoStore,
                  storeApplier,
                  new NeoStoreInjectedTransactionValidator(integrityValidator),
                  false));

      /*
       * This is used by legacy indexes and constraint indexes whenever a transaction is to be spawned
       * from within an existing transaction. It smells, and we should look over alternatives when time permits.
       */
      Provider<KernelAPI> kernelProvider =
          new Provider<KernelAPI>() {
            @Override
            public KernelAPI instance() {
              return kernel;
            }
          };

      ConstraintIndexCreator constraintIndexCreator =
          new ConstraintIndexCreator(kernelProvider, indexingService);

      LegacyIndexStore legacyIndexStore =
          new LegacyIndexStore(config, indexConfigStore, kernelProvider, legacyIndexProviderLookup);

      StatementOperationParts statementOperations =
          buildStatementOperations(
              storeLayer,
              legacyPropertyTrackers,
              constraintIndexCreator,
              updateableSchemaState,
              guard,
              legacyIndexStore);

      kernelTransactions =
          life.add(
              new KernelTransactions(
                  neoStoreTransactionContextSupplier,
                  neoStore,
                  locks,
                  integrityValidator,
                  constraintIndexCreator,
                  indexingService,
                  labelScanStore,
                  statementOperations,
                  updateableSchemaState,
                  schemaWriteGuard,
                  providerMap,
                  transactionHeaderInformationFactory,
                  persistenceCache,
                  storeLayer,
                  transactionCommitProcess,
                  indexConfigStore,
                  legacyIndexProviderLookup,
                  hooks,
                  transactionMonitor,
                  life,
                  readOnly));

      kernel =
          new Kernel(
              statisticsService, kernelTransactions, hooks, kernelHealth, transactionMonitor);

      life.add(logFile);
      life.add(logicalTransactionStore);
      life.add(
          new LifecycleAdapter() {
            @Override
            public void start() throws Throwable {
              startupStatistics.setNumberOfRecoveredTransactions(recoveredCount.get());
              recoveredCount.set(0);
              loadSchemaCache();
            }
          });
      life.add(statisticsService);
      life.add(
          new LifecycleAdapter() {
            @Override
            public void start() {
              neoStore.makeStoreOk();
            }
          });
      life.add(indexingService);
      life.add(labelScanStore);

      kernel.registerTransactionHook(transactionEventHandlers);
      neoStore.setRecoveredStatus(true);
      try {
        life.start();
      } finally {
        neoStore.setRecoveredStatus(false);
      }

      propertyKeyTokenHolder.addTokens(
          neoStore.getPropertyKeyTokenStore().getTokens(Integer.MAX_VALUE));
      relationshipTypeTokens.addTokens(
          neoStore.getRelationshipTypeTokenStore().getTokens(Integer.MAX_VALUE));
      labelTokens.addTokens(neoStore.getLabelTokenStore().getTokens(Integer.MAX_VALUE));
    } catch (Throwable e) { // Something unexpected happened during startup
      try { // Close the neostore, so that locks are released properly
        neoStore.close();
      } catch (Exception closeException) {
        msgLog.logMessage("Couldn't close neostore after startup failure");
      }
      throw Exceptions.launderedException(e);
    }
  }