use of org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure in project ignite by apache.
the class GridQueryProcessor method processSchemaOperationLocal.
/**
* Process schema operation.
*
* @param op Operation.
* @param type Type descriptor.
* @param depId Cache deployment ID.
* @param cancelTok Cancel token.
* @throws SchemaOperationException If failed.
*/
public void processSchemaOperationLocal(SchemaAbstractOperation op, QueryTypeDescriptorImpl type, IgniteUuid depId, IndexRebuildCancelToken cancelTok) throws SchemaOperationException {
if (log.isDebugEnabled())
log.debug("Started local index operation [opId=" + op.id() + ']');
String cacheName = op.cacheName();
GridCacheContextInfo<?, ?> cacheInfo = null;
if (op instanceof SchemaAddQueryEntityOperation) {
GridCacheContext<?, ?> cctx = ctx.cache().context().cacheContext(CU.cacheId(cacheName));
if (cctx != null)
cacheInfo = new GridCacheContextInfo<>(cctx, false);
else
return;
} else
cacheInfo = idx.registeredCacheInfo(cacheName);
if (cacheInfo == null || !F.eq(depId, cacheInfo.dynamicDeploymentId()))
throw new SchemaOperationException(SchemaOperationException.CODE_CACHE_NOT_FOUND, cacheName);
try {
if (op instanceof SchemaIndexCreateOperation) {
SchemaIndexCreateOperation op0 = (SchemaIndexCreateOperation) op;
QueryIndexDescriptorImpl idxDesc = QueryUtils.createIndexDescriptor(type, op0.index());
SchemaIndexCacheVisitor visitor;
if (cacheInfo.isCacheContextInited()) {
int buildIdxPoolSize = ctx.config().getBuildIndexThreadPoolSize();
int parallel = op0.parallel();
if (parallel > buildIdxPoolSize) {
String idxName = op0.indexName();
log.warning("Provided parallelism " + parallel + " for creation of index " + idxName + " is greater than the number of index building threads. Will use " + buildIdxPoolSize + " threads to build index. Increase by IgniteConfiguration.setBuildIndexThreadPoolSize" + " and restart the node if you want to use more threads. [tableName=" + op0.tableName() + ", indexName=" + idxName + ", requestedParallelism=" + parallel + ", buildIndexPoolSize=" + buildIdxPoolSize + "]");
}
GridFutureAdapter<Void> createIdxFut = new GridFutureAdapter<>();
GridCacheContext<?, ?> cacheCtx = cacheInfo.cacheContext();
visitor = new SchemaIndexCacheVisitorImpl(cacheCtx, cancelTok, createIdxFut) {
/**
* {@inheritDoc}
*/
@Override
public void visit(SchemaIndexCacheVisitorClosure clo) {
idxBuildStatusStorage.onStartBuildNewIndex(cacheCtx);
try {
super.visit(clo);
buildIdxFut.get();
} catch (Exception e) {
throw new IgniteException(e);
} finally {
idxBuildStatusStorage.onFinishBuildNewIndex(cacheName);
}
}
};
} else
// For not started caches we shouldn't add any data to index.
visitor = clo -> {
};
idx.dynamicIndexCreate(op0.schemaName(), op0.tableName(), idxDesc, op0.ifNotExists(), visitor);
} else if (op instanceof SchemaIndexDropOperation) {
SchemaIndexDropOperation op0 = (SchemaIndexDropOperation) op;
idx.dynamicIndexDrop(op0.schemaName(), op0.indexName(), op0.ifExists());
} else if (op instanceof SchemaAlterTableAddColumnOperation) {
SchemaAlterTableAddColumnOperation op0 = (SchemaAlterTableAddColumnOperation) op;
processDynamicAddColumn(type, op0.columns());
idx.dynamicAddColumn(op0.schemaName(), op0.tableName(), op0.columns(), op0.ifTableExists(), op0.ifNotExists());
} else if (op instanceof SchemaAlterTableDropColumnOperation) {
SchemaAlterTableDropColumnOperation op0 = (SchemaAlterTableDropColumnOperation) op;
processDynamicDropColumn(type, op0.columns());
idx.dynamicDropColumn(op0.schemaName(), op0.tableName(), op0.columns(), op0.ifTableExists(), op0.ifExists());
} else if (op instanceof SchemaAddQueryEntityOperation) {
SchemaAddQueryEntityOperation op0 = (SchemaAddQueryEntityOperation) op;
if (!cacheNames.contains(op0.cacheName())) {
cacheInfo.onSchemaAddQueryEntity(op0);
T3<Collection<QueryTypeCandidate>, Map<String, QueryTypeDescriptorImpl>, Map<String, QueryTypeDescriptorImpl>> candRes = createQueryCandidates(op0.cacheName(), op0.schemaName(), cacheInfo, op0.entities(), op0.isSqlEscape());
registerCache0(op0.cacheName(), op.schemaName(), cacheInfo, candRes.get1(), false);
}
if (idxRebuildFutStorage.prepareRebuildIndexes(singleton(cacheInfo.cacheId()), null).isEmpty())
rebuildIndexesFromHash0(cacheInfo.cacheContext(), false, cancelTok);
else {
if (log.isInfoEnabled())
log.info("Rebuilding indexes for the cache is already in progress: " + cacheInfo.name());
}
} else
throw new SchemaOperationException("Unsupported operation: " + op);
} catch (Throwable e) {
if (e instanceof SchemaOperationException)
throw (SchemaOperationException) e;
else
throw new SchemaOperationException("Schema change operation failed: " + e.getMessage(), e);
}
}
use of org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure in project ignite by apache.
the class IgniteH2Indexing method dynamicIndexCreate.
/**
* {@inheritDoc}
*/
@Override
public void dynamicIndexCreate(final String schemaName, final String tblName, final QueryIndexDescriptorImpl idxDesc, boolean ifNotExists, SchemaIndexCacheVisitor cacheVisitor) throws IgniteCheckedException {
// Locate table.
H2Schema schema = schemas.get(schemaName);
H2TableDescriptor desc = (schema != null ? schema.tableByName(tblName) : null);
if (desc == null)
throw new IgniteCheckedException("Table not found in internal H2 database [schemaName=" + schemaName + ", tblName=" + tblName + ']');
GridH2Table h2Tbl = desc.table();
// Create index.
final GridH2IndexBase h2Idx = desc.createUserIndex(idxDesc);
h2Tbl.proposeUserIndex(h2Idx);
try {
// Populate index with existing cache data.
final GridH2RowDescriptor rowDesc = h2Tbl.rowDescriptor();
SchemaIndexCacheVisitorClosure clo = new SchemaIndexCacheVisitorClosure() {
@Override
public void apply(CacheDataRow row) throws IgniteCheckedException {
GridH2Row h2Row = rowDesc.createRow(row);
h2Idx.putx(h2Row);
}
};
cacheVisitor.visit(clo);
// At this point index is in consistent state, promote it through H2 SQL statement, so that cached
// prepared statements are re-built.
String sql = H2Utils.indexCreateSql(desc.fullTableName(), h2Idx, ifNotExists);
executeSql(schemaName, sql);
} catch (Exception e) {
// Rollback and re-throw.
h2Tbl.rollbackUserIndex(h2Idx.getName());
throw e;
}
}
use of org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure in project ignite by apache.
the class IndexesRebuildTask method rebuild.
/**
* Start to rebuild.
*
* @param cctx Cache context.
* @param force Force rebuild indexes.
* @return A future of rebuilding cache indexes.
*/
@Nullable
public IgniteInternalFuture<?> rebuild(GridCacheContext<?, ?> cctx, boolean force, IndexRebuildCancelToken cancelTok) {
assert cctx != null;
if (!CU.affinityNode(cctx.localNode(), cctx.config().getNodeFilter()))
return null;
IgnitePageStoreManager pageStore = cctx.shared().pageStore();
SchemaIndexCacheVisitorClosure clo;
String cacheName = cctx.name();
if (pageStore == null || !pageStore.hasIndexStore(cctx.groupId())) {
boolean mvccEnabled = cctx.mvccEnabled();
// If there are no index store, rebuild all indexes.
clo = row -> cctx.queries().store(row, null, mvccEnabled);
} else {
Collection<InlineIndex> toRebuild = cctx.kernalContext().indexProcessor().treeIndexes(cctx, !force);
if (F.isEmpty(toRebuild))
return null;
clo = row -> cctx.kernalContext().indexProcessor().store(toRebuild, row, null, false);
}
// Closure prepared, do rebuild.
cctx.kernalContext().query().markAsRebuildNeeded(cctx, true);
GridFutureAdapter<Void> rebuildCacheIdxFut = new GridFutureAdapter<>();
// To avoid possible data race.
GridFutureAdapter<Void> outRebuildCacheIdxFut = new GridFutureAdapter<>();
IgniteLogger log = cctx.kernalContext().grid().log();
// An internal future for the ability to cancel index rebuilding.
SchemaIndexCacheFuture intRebFut = new SchemaIndexCacheFuture(cancelTok);
SchemaIndexCacheFuture prevIntRebFut = idxRebuildFuts.put(cctx.cacheId(), intRebFut);
// Check that the previous rebuild is completed.
assert prevIntRebFut == null;
cctx.kernalContext().query().onStartRebuildIndexes(cctx);
rebuildCacheIdxFut.listen(fut -> {
Throwable err = fut.error();
if (err == null) {
try {
cctx.kernalContext().query().markAsRebuildNeeded(cctx, false);
} catch (Throwable t) {
err = t;
}
}
if (err != null)
U.error(log, "Failed to rebuild indexes for cache: " + cacheName, err);
else
cctx.kernalContext().query().onFinishRebuildIndexes(cctx);
idxRebuildFuts.remove(cctx.cacheId(), intRebFut);
intRebFut.onDone(err);
outRebuildCacheIdxFut.onDone(err);
});
startRebuild(cctx, rebuildCacheIdxFut, clo, intRebFut.cancelToken());
return outRebuildCacheIdxFut;
}
Aggregations