Skip to content

Commit

Permalink
IGNITE-19553 Add metrics for operations on secondary indexes - Fixes #…
Browse files Browse the repository at this point in the history
…10731.

Signed-off-by: Aleksey Plekhanov <plehanov.alex@gmail.com>
  • Loading branch information
alex-plekhanov committed Sep 25, 2023
1 parent a688b1d commit 29c4b6e
Show file tree
Hide file tree
Showing 7 changed files with 356 additions and 24 deletions.
17 changes: 15 additions & 2 deletions docs/_docs/monitoring-metrics/new-metrics.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ Register name: `io.statistics.cacheGroups.{group_name}`
|===


== Sorted Indexes
== Sorted Indexes I/O statistics

Register name: `io.statistics.sortedIndexes.{cache_name}.{index_name}`

Expand All @@ -257,8 +257,21 @@ Register name: `io.statistics.sortedIndexes.{cache_name}.{index_name}`
|startTime| long| Statistics collection start time
|===

== Sorted Indexes operations

== Hash Indexes
Contains metrics about low-level operations (such as `Insert`, `Search`, etc.) on pages of sorted secondary indexes.

Register name: `index.{schema_name}.{table_name}.{index_name}`

[cols="2,1,3",opts="header"]
|===
|Name | Type | Description
|{opType}Count| long| Count of {opType} operations on index.
|{opType}Time| long| Total duration (nanoseconds) of {opType} operations on index.
|===


== Hash Indexes I/O statistics

Register name: `io.statistics.hashIndexes.{cache_name}.{index_name}`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,12 @@ public final class IgniteSystemProperties {
defaults = "" + IGNITE_BPLUS_TREE_LOCK_RETRIES_DEFAULT)
public static final String IGNITE_BPLUS_TREE_LOCK_RETRIES = "IGNITE_BPLUS_TREE_LOCK_RETRIES";

/**
* Disables secondary indexes B+Tree metrics.
*/
@SystemProperty(value = "Disables secondary indexes B+Tree metrics", defaults = "false")
public static final String IGNITE_BPLUS_TREE_DISABLE_METRICS = "IGNITE_BPLUS_TREE_DISABLE_METRICS";

/**
* Amount of memory reserved in the heap at node start, which can be dropped to increase the chances of success when
* handling OutOfMemoryError.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,15 @@

import static org.apache.ignite.cluster.ClusterState.INACTIVE;
import static org.apache.ignite.failure.FailureType.CRITICAL_ERROR;
import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;

/**
* Sorted index implementation.
*/
public class InlineIndexImpl extends AbstractIndex implements InlineIndex {
/** */
public static final String INDEX_METRIC_PREFIX = "index";

/** Unique ID. */
private final UUID id = UUID.randomUUID();

Expand Down Expand Up @@ -553,6 +557,7 @@ private void destroy0(boolean softDel) throws IgniteCheckedException {
}

cctx.kernalContext().metric().remove(stats.metricRegistryName());
cctx.kernalContext().metric().remove(metricName(INDEX_METRIC_PREFIX, def.idxName().fullName()));

if (cctx.group().persistenceEnabled() ||
cctx.shared().kernalContext().state().clusterState().state() != INACTIVE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.apache.ignite.internal.pagemem.PageIdUtils;
import org.apache.ignite.internal.pagemem.PageMemory;
import org.apache.ignite.internal.processors.cache.CacheGroupContext;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager;
import org.apache.ignite.internal.processors.cache.mvcc.MvccUtils;
import org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter;
Expand All @@ -53,18 +54,25 @@
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIoResolver;
import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandler;
import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandlerWrapper;
import org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataRow;
import org.apache.ignite.internal.processors.metric.MetricRegistry;
import org.apache.ignite.internal.processors.metric.impl.LongAdderMetric;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.maintenance.MaintenanceTask;
import org.jetbrains.annotations.Nullable;

import static org.apache.ignite.IgniteSystemProperties.IGNITE_BPLUS_TREE_DISABLE_METRICS;
import static org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexImpl.INDEX_METRIC_PREFIX;
import static org.apache.ignite.internal.cache.query.index.sorted.inline.types.NullableInlineIndexKeyType.CANT_BE_COMPARE;
import static org.apache.ignite.internal.cache.query.index.sorted.inline.types.NullableInlineIndexKeyType.COMPARE_UNSUPPORTED;
import static org.apache.ignite.internal.cache.query.index.sorted.maintenance.MaintenanceRebuildIndexUtils.mergeTasks;
import static org.apache.ignite.internal.cache.query.index.sorted.maintenance.MaintenanceRebuildIndexUtils.toMaintenanceTask;
import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;

/**
* BPlusTree where nodes stores inlined index keys.
Expand Down Expand Up @@ -139,7 +147,8 @@ public InlineIndexTree(
PageIdAllocator.FLAG_IDX,
grpCtx.shared().kernalContext().failure(),
grpCtx.shared().diagnostic().pageLockTracker(),
pageIoResolver
pageIoResolver,
wrapper(def)
);

this.grpCtx = grpCtx;
Expand Down Expand Up @@ -667,4 +676,69 @@ private int mvccCompare(IndexRow r1, IndexRow r2) {
", schemaName=" + idxName.schemaName() + ", tblName=" + idxName.tableName() + ", idxName=" +
idxName.idxName() + ']';
}

/** */
private static PageHandlerWrapper<Result> wrapper(SortedIndexDefinition def) {
if (def == null || def.cacheInfo().cacheContext() == null)
return null;

if (IgniteSystemProperties.getBoolean(IGNITE_BPLUS_TREE_DISABLE_METRICS))
return null;

return new PageHandlerWrapper<Result>() {
@Override public PageHandler<?, Result> wrap(BPlusTree<?, ?> tree, PageHandler<?, Result> hnd) {
GridCacheContext<?, ?> cctx = def.cacheInfo().cacheContext();

MetricRegistry mreg = cctx.shared().kernalContext().metric().registry(
metricName(INDEX_METRIC_PREFIX, def.idxName().fullName()));

LongAdderMetric cnt = mreg.longAdderMetric(hnd.getClass().getSimpleName() + "Count",
"Count of " + hnd.getClass().getSimpleName() + " operations");
LongAdderMetric time = mreg.longAdderMetric(hnd.getClass().getSimpleName() + "Time",
"Total time of " + hnd.getClass().getSimpleName() + " operations (nanoseconds)");

return new PageHandler<Object, Result>() {
@Override public Result run(
int cacheId,
long pageId,
long page,
long pageAddr,
PageIO io,
Boolean walPlc,
Object arg,
int intArg,
IoStatisticsHolder statHolder
) throws IgniteCheckedException {
if (!cctx.statisticsEnabled()) {
return ((PageHandler<Object, Result>)hnd).run(cacheId, pageId, page, pageAddr, io, walPlc,
arg, intArg, statHolder);
}

long ts = System.nanoTime();

try {
return ((PageHandler<Object, Result>)hnd).run(cacheId, pageId, page, pageAddr, io, walPlc,
arg, intArg, statHolder);
}
finally {
cnt.increment();
time.add(System.nanoTime() - ts);
}
}

@Override public boolean releaseAfterWrite(
int cacheId,
long pageId,
long page,
long pageAddr,
Object arg,
int intArg
) {
return ((PageHandler<Object, Result>)hnd).releaseAfterWrite(cacheId, pageId, page, pageAddr,
arg, intArg);
}
};
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,8 @@ protected BPlusTree(
pageFlag,
failureProcessor,
pageLockTrackerManager,
DEFAULT_PAGE_IO_RESOLVER
DEFAULT_PAGE_IO_RESOLVER,
null
);

setIos(innerIos, leafIos);
Expand Down Expand Up @@ -1018,7 +1019,8 @@ protected BPlusTree(
byte pageFlag,
@Nullable FailureProcessor failureProcessor,
PageLockTrackerManager pageLockTrackerManager,
PageIoResolver pageIoRslvr
PageIoResolver pageIoRslvr,
@Nullable PageHandlerWrapper<Result> hndWrapper
) {
super(name, cacheGrpId, grpName, pageMem, wal, pageLockTrackerManager, pageIoRslvr, pageFlag);

Expand All @@ -1034,31 +1036,33 @@ protected BPlusTree(
this.failureProcessor = failureProcessor;

// Initialize page handlers.
askNeighbor = (PageHandler<Get, Result>)wrap(this, new AskNeighbor());
search = (PageHandler<Get, Result>)wrap(this, new Search());
lockTailExact = (PageHandler<Update, Result>)wrap(this, new LockTailExact());
lockTail = (PageHandler<Remove, Result>)wrap(this, new LockTail());
lockTailForward = (PageHandler<Remove, Result>)wrap(this, new LockTailForward());
lockBackAndTail = (PageHandler<Remove, Result>)wrap(this, new LockBackAndTail());
lockBackAndRmvFromLeaf = (PageHandler<Remove, Result>)wrap(this, new LockBackAndRmvFromLeaf());
rmvFromLeaf = (PageHandler<Remove, Result>)wrap(this, new RemoveFromLeaf());
insert = (PageHandler<Put, Result>)wrap(this, new Insert());
replace = (PageHandler<Put, Result>)wrap(this, new Replace());
rmvRangeFromLeaf = (PageHandler<Remove, Result>)wrap(this, new RemoveRangeFromLeaf());
askNeighbor = wrap(hndWrapper, new AskNeighbor());
search = wrap(hndWrapper, new Search());
lockTailExact = wrap(hndWrapper, new LockTailExact());
lockTail = wrap(hndWrapper, new LockTail());
lockTailForward = wrap(hndWrapper, new LockTailForward());
lockBackAndTail = wrap(hndWrapper, new LockBackAndTail());
lockBackAndRmvFromLeaf = wrap(hndWrapper, new LockBackAndRmvFromLeaf());
rmvFromLeaf = wrap(hndWrapper, new RemoveFromLeaf<>());
insert = wrap(hndWrapper, new Insert());
replace = wrap(hndWrapper, new Replace());
rmvRangeFromLeaf = wrap(hndWrapper, new RemoveRangeFromLeaf());
}

/**
* Returns a wrapper for page handler. By default, there is no wrapper.
* Returns a wrapped page handler. By default, there is no wrapper.
*
* @param tree B-plus tree.
* @param hndWrapper Page handler wrapper for this tree.
* @param hnd Page handler.
* @return Page handler wrapper.
* @return Wrapped page handler.
*/
private PageHandler<?, Result> wrap(BPlusTree<?, ?> tree, PageHandler<?, Result> hnd) {
if (testHndWrapper == null)
return hnd;
else
return testHndWrapper.wrap(tree, hnd);
private <X> PageHandler<X, Result> wrap(PageHandlerWrapper<Result> hndWrapper, PageHandler<?, Result> hnd) {
// Wrap handler using test wrapper.
if (testHndWrapper != null)
hnd = testHndWrapper.wrap(this, hnd);

// Additionally wrap using tree page handler wrapper, if it's specified.
return (PageHandler<X, Result>)(hndWrapper == null ? hnd : hndWrapper.wrap(this, hnd));
}

/**
Expand Down
Loading

0 comments on commit 29c4b6e

Please sign in to comment.