use of org.neo4j.internal.kernel.api.InternalIndexState in project neo4j by neo4j.
the class SchemaStatementProcedure method includeConstraint.
private static boolean includeConstraint(SchemaReadCore schemaRead, ConstraintDescriptor constraint) {
// - Owned index must have this constraint as owning constraint
if (constraint.isIndexBackedConstraint()) {
IndexBackedConstraintDescriptor indexBackedConstraint = constraint.asIndexBackedConstraint();
if (indexBackedConstraint.hasOwnedIndexId()) {
IndexDescriptor backingIndex = schemaRead.indexGetForName(constraint.getName());
if (backingIndex.getId() == indexBackedConstraint.ownedIndexId()) {
try {
InternalIndexState internalIndexState = schemaRead.indexGetState(backingIndex);
OptionalLong owningConstraintId = backingIndex.getOwningConstraintId();
return internalIndexState == InternalIndexState.ONLINE && owningConstraintId.orElse(-1) == constraint.getId();
} catch (IndexNotFoundKernelException e) {
return false;
}
}
}
return false;
}
return true;
}
use of org.neo4j.internal.kernel.api.InternalIndexState in project neo4j by neo4j.
the class IndexingService method start.
// Recovery semantics: This is to be called after init, and after the database has run recovery.
@Override
public void start() throws Exception {
state = State.STARTING;
// Recovery will not do refresh (update read views) while applying recovered transactions and instead
// do it at one point after recovery... i.e. here
indexMapRef.indexMapSnapshot().forEachIndexProxy(indexProxyOperation("refresh", IndexProxy::refresh));
final MutableLongObjectMap<IndexDescriptor> rebuildingDescriptors = new LongObjectHashMap<>();
indexMapRef.modify(indexMap -> {
Map<InternalIndexState, List<IndexLogRecord>> indexStates = new EnumMap<>(InternalIndexState.class);
Map<IndexProviderDescriptor, List<IndexLogRecord>> indexProviders = new HashMap<>();
// Find all indexes that are not already online, do not require rebuilding, and create them
indexMap.forEachIndexProxy((indexId, proxy) -> {
InternalIndexState state = proxy.getState();
IndexDescriptor descriptor = proxy.getDescriptor();
IndexProviderDescriptor providerDescriptor = descriptor.getIndexProvider();
IndexLogRecord indexLogRecord = new IndexLogRecord(descriptor);
indexStates.computeIfAbsent(state, internalIndexState -> new ArrayList<>()).add(indexLogRecord);
indexProviders.computeIfAbsent(providerDescriptor, indexProviderDescriptor -> new ArrayList<>()).add(indexLogRecord);
internalLog.debug(indexStateInfo("start", state, descriptor));
switch(state) {
case ONLINE:
case FAILED:
proxy.start();
break;
case POPULATING:
// Remember for rebuilding right below in this method
rebuildingDescriptors.put(indexId, descriptor);
break;
default:
throw new IllegalStateException("Unknown state: " + state);
}
});
logIndexStateSummary("start", indexStates);
logIndexProviderSummary(indexProviders);
dontRebuildIndexesInReadOnlyMode(rebuildingDescriptors);
// Drop placeholder proxies for indexes that need to be rebuilt
dropRecoveringIndexes(indexMap, rebuildingDescriptors.keySet());
// Rebuild indexes by recreating and repopulating them
populateIndexesOfAllTypes(rebuildingDescriptors, indexMap);
return indexMap;
});
indexStatisticsStore.start();
samplingController.recoverIndexSamples();
samplingController.start();
// So at this point we've started population of indexes that needs to be rebuilt in the background.
// Indexes backing uniqueness constraints are normally built within the transaction creating the constraint
// and so we shouldn't leave such indexes in a populating state after recovery.
// This is why we now go and wait for those indexes to be fully populated.
rebuildingDescriptors.forEachKeyValue((indexId, index) -> {
if (!index.isUnique()) {
// It's not a uniqueness constraint, so don't wait for it to be rebuilt
return;
}
IndexProxy proxy;
try {
proxy = getIndexProxy(index);
} catch (IndexNotFoundKernelException e) {
throw new IllegalStateException("What? This index was seen during recovery just now, why isn't it available now?", e);
}
if (proxy.getDescriptor().getOwningConstraintId().isEmpty()) {
// so there's no gain in waiting for this index.
return;
}
monitor.awaitingPopulationOfRecoveredIndex(index);
awaitOnlineAfterRecovery(proxy);
});
state = State.RUNNING;
}
use of org.neo4j.internal.kernel.api.InternalIndexState in project neo4j by neo4j.
the class IndexingService method logIndexStateSummary.
private void logIndexStateSummary(String method, Map<InternalIndexState, List<IndexLogRecord>> indexStates) {
if (indexStates.isEmpty()) {
return;
}
int mostPopularStateCount = Integer.MIN_VALUE;
InternalIndexState mostPopularState = null;
for (Map.Entry<InternalIndexState, List<IndexLogRecord>> indexStateEntry : indexStates.entrySet()) {
if (indexStateEntry.getValue().size() > mostPopularStateCount) {
mostPopularState = indexStateEntry.getKey();
mostPopularStateCount = indexStateEntry.getValue().size();
}
}
indexStates.remove(mostPopularState);
for (Map.Entry<InternalIndexState, List<IndexLogRecord>> indexStateEntry : indexStates.entrySet()) {
InternalIndexState state = indexStateEntry.getKey();
List<IndexLogRecord> logRecords = indexStateEntry.getValue();
for (IndexLogRecord logRecord : logRecords) {
internalLog.info(indexStateInfo(method, state, logRecord.getDescriptor()));
}
}
internalLog.info(format("IndexingService.%s: indexes not specifically mentioned above are %s", method, mostPopularState));
}
use of org.neo4j.internal.kernel.api.InternalIndexState in project neo4j by neo4j.
the class FusionIndexProviderTest method shouldReportFailedIfAnyIsFailed.
@Test
void shouldReportFailedIfAnyIsFailed() {
// given
IndexProvider provider = fusionIndexProvider;
for (InternalIndexState state : InternalIndexState.values()) {
for (IndexProvider failedProvider : aliveProviders) {
// when
for (IndexProvider aliveProvider : aliveProviders) {
setInitialState(aliveProvider, failedProvider == aliveProvider ? InternalIndexState.FAILED : state);
}
InternalIndexState initialState = provider.getInitialState(AN_INDEX, NULL);
// then
assertEquals(InternalIndexState.FAILED, initialState);
}
}
}
use of org.neo4j.internal.kernel.api.InternalIndexState in project neo4j by neo4j.
the class FusionIndexProviderTest method shouldReportPopulatingIfAnyIsPopulating.
@Test
void shouldReportPopulatingIfAnyIsPopulating() {
// given
for (InternalIndexState state : array(InternalIndexState.ONLINE, InternalIndexState.POPULATING)) {
for (IndexProvider populatingProvider : aliveProviders) {
// when
for (IndexProvider aliveProvider : aliveProviders) {
setInitialState(aliveProvider, populatingProvider == aliveProvider ? InternalIndexState.POPULATING : state);
}
InternalIndexState initialState = fusionIndexProvider.getInitialState(AN_INDEX, NULL);
// then
assertEquals(InternalIndexState.POPULATING, initialState);
}
}
}
Aggregations