You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ignite.apache.org by "rpuch (via GitHub)" <gi...@apache.org> on 2026/02/20 11:25:18 UTC
Re: [PR] IGNITE-27359 Add storage consistency metrics [ignite-3]
rpuch commented on code in PR #7422:
URL: https://github.com/apache/ignite-3/pull/7422#discussion_r2832625275
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java:
##########
Review Comment:
That code without `try` protection looks a bit worrying. As far as I remember, according to Java VM spec, an exception can happen at any line. And we have a memory allocation here that can throw an OOME. How about adding another `try` block? Its contents could be extracted to a method to make the code less ugly
##########
modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorageTest.java:
##########
@@ -537,4 +540,83 @@ void writeIntentsCursorRespectsStorageClosure() {
assertThrows(StorageClosedException.class, cursor::next);
}
}
+
+ @Test
+ void verifyRunConsistentlyMetrics() {
+ RunConsistentlyMetrics metrics = ((PersistentPageMemoryMvPartitionStorage) storage).consistencyMetrics;
+
+ // Verify metrics start at zero
+ assertDistributionMetricRecordsCount(metrics.runConsistentlyDuration(), 0L);
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 0);
+
+ // Execute a simple operation within runConsistently
+ storage.runConsistently(locker -> {
+ // Verify active count is incremented
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 1);
+
+ insert(binaryRow, txId);
+
+ return null;
+ });
+
+ // Verify duration was recorded
+ assertDistributionMetricRecordsCount(metrics.runConsistentlyDuration(), 1L);
+
+ // Verify active count is decremented back to zero
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 0);
+
+ // Execute another operation
+ storage.runConsistently(locker -> {
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 1);
+
+ return null;
+ });
+
+ // Verify another duration was recorded
+ assertDistributionMetricRecordsCount(metrics.runConsistentlyDuration(), 2L);
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 0);
+ }
+
+ @Test
+ void verifyNestedRunConsistentlyDoesNotDoubleCountMetrics() {
+ RunConsistentlyMetrics metrics = ((PersistentPageMemoryMvPartitionStorage) storage).consistencyMetrics;
+
+ storage.runConsistently(outerLocker -> {
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 1);
+
+ // Nested call
+ storage.runConsistently(innerLocker -> {
+ // Active count should not increase for nested calls
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 1);
+
+ return null;
+ });
+
+ return null;
+ });
+
+ // Only one duration should be recorded for the outer call
+ assertDistributionMetricRecordsCount(metrics.runConsistentlyDuration(), 1L);
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 0);
+ }
+
+ private static void assertMetricValue(AtomicIntMetric metric, int value) {
+ assertThat(metric.value(), is(value));
+ }
+
+ /**
+ * Verifies that the specified distribution metric has recorded the expected total number of measurements.
+ *
+ * <p>
+ * Rather than checking individual histogram buckets, this method aggregates all recorded measurements across every bucket
+ * and confirms that the expected interaction was captured in at least one of them.
+ */
+ private static void assertDistributionMetricRecordsCount(DistributionMetric metric, long expectedMeasuresCount) {
Review Comment:
I think I saw something similar before. Could it be extracted to reduce code duplication?
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java:
##########
@@ -208,6 +218,10 @@ public <V> V runConsistently(WriteClosure<V> closure) throws StorageException {
locker0.unlockAll();
checkpointTimeoutLock.checkpointReadUnlock();
+
+ long duration = System.nanoTime() - startTime;
+ consistencyMetrics.recordRunConsistentlyDuration(duration);
+ consistencyMetrics.decrementActiveCount();
Review Comment:
Will we still pay the toll of maintaining these values if the corresponding metric source is disabled? Can we avoid it?
##########
modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorageTest.java:
##########
@@ -537,4 +540,83 @@ void writeIntentsCursorRespectsStorageClosure() {
assertThrows(StorageClosedException.class, cursor::next);
}
}
+
+ @Test
+ void verifyRunConsistentlyMetrics() {
+ RunConsistentlyMetrics metrics = ((PersistentPageMemoryMvPartitionStorage) storage).consistencyMetrics;
+
+ // Verify metrics start at zero
+ assertDistributionMetricRecordsCount(metrics.runConsistentlyDuration(), 0L);
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 0);
+
+ // Execute a simple operation within runConsistently
+ storage.runConsistently(locker -> {
+ // Verify active count is incremented
+ assertMetricValue(metrics.runConsistentlyActiveCount(), 1);
+
+ insert(binaryRow, txId);
Review Comment:
Do we need this insertion at all for this test?
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RunConsistentlyMetrics.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.mv;
+
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.pagememory.metrics.CollectionMetricSource;
+
+/**
+ * Metrics for runConsistently operation.
+ *
+ * <p>Tracks runConsistently closure execution performance including duration
+ * and active call count.
+ */
+public class RunConsistentlyMetrics {
+ /**
+ * Histogram buckets for runConsistently duration in nanoseconds.
+ *
+ * <p>Covers operations from fast single-row writes to slow bulk operations with checkpoint contention:
+ * <ul>
+ * <li>10µs: Fast single-row operations without lock contention</li>
+ * <li>100µs: Multi-row operations, small index operations</li>
+ * <li>1ms: Medium-sized operations</li>
+ * <li>10ms: Larger operations, small vacuum operations</li>
+ * <li>100ms: Large operations, significant vacuum work</li>
+ * <li>1s: Very slow operations, likely checkpoint write lock contention</li>
+ * <li>10s: Pathological cases requiring investigation</li>
+ * </ul>
+ */
+ private static final long[] RUN_CONSISTENTLY_NANOS = {
Review Comment:
This is an array of bounds, should `bounds` be included in the name?
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RunConsistentlyMetrics.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.mv;
+
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.pagememory.metrics.CollectionMetricSource;
+
+/**
+ * Metrics for runConsistently operation.
+ *
+ * <p>Tracks runConsistently closure execution performance including duration
+ * and active call count.
+ */
+public class RunConsistentlyMetrics {
+ /**
+ * Histogram buckets for runConsistently duration in nanoseconds.
+ *
+ * <p>Covers operations from fast single-row writes to slow bulk operations with checkpoint contention:
+ * <ul>
+ * <li>10µs: Fast single-row operations without lock contention</li>
+ * <li>100µs: Multi-row operations, small index operations</li>
+ * <li>1ms: Medium-sized operations</li>
+ * <li>10ms: Larger operations, small vacuum operations</li>
+ * <li>100ms: Large operations, significant vacuum work</li>
+ * <li>1s: Very slow operations, likely checkpoint write lock contention</li>
+ * <li>10s: Pathological cases requiring investigation</li>
+ * </ul>
+ */
+ private static final long[] RUN_CONSISTENTLY_NANOS = {
+ 10_000, // 10µs
+ 100_000, // 100µs
+ 1_000_000, // 1ms
+ 10_000_000, // 10ms
+ 100_000_000, // 100ms
+ 1_000_000_000, // 1s
+ 10_000_000_000L, // 10s
+ };
+
+ private final DistributionMetric runConsistentlyDuration;
+ private final AtomicIntMetric runConsistentlyActiveCount;
+
+ /**
+ * Constructor.
+ *
+ * @param metricSource Metric source to register metrics with.
+ */
+ public RunConsistentlyMetrics(CollectionMetricSource metricSource) {
+ runConsistentlyDuration = metricSource.addMetric(new DistributionMetric(
+ "RunConsistentlyDuration",
+ "Time spent in runConsistently closures in nanoseconds.",
+ RUN_CONSISTENTLY_NANOS
+ ));
+
+ runConsistentlyActiveCount = metricSource.addMetric(new AtomicIntMetric(
Review Comment:
In this case, this metric is going to be updated under heavy contention, so `LongAdderMetric` seems to be preferable
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java:
##########
@@ -99,6 +99,9 @@ public class PersistentPageMemoryMvPartitionStorage extends AbstractPageMemoryMv
*/
private final Object leaseInfoLock = new Object();
+ /** RunConsistently metrics. */
+ final RunConsistentlyMetrics consistencyMetrics;
Review Comment:
'Consistency metrics' doesn't seem to be the perfect term here. When I read it, I immediately start thinking about 'how bad the consistency is broken' or 'how much we are paying for consistency guarantees'. But here it's just 'metrics of runConsistently primitive'. Should it be called just `runConsistentlyMetrics`, like its type, to avoid confusion?
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java:
##########
@@ -99,6 +99,9 @@ public class PersistentPageMemoryMvPartitionStorage extends AbstractPageMemoryMv
*/
private final Object leaseInfoLock = new Object();
+ /** RunConsistently metrics. */
+ final RunConsistentlyMetrics consistencyMetrics;
Review Comment:
Let's expose it via a package-local (test-only) method and not a package local field
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java:
##########
@@ -65,29 +66,35 @@ public class PersistentPageMemoryTableStorage extends AbstractPageMemoryTableSto
private final FailureProcessor failureProcessor;
+ private final RunConsistentlyMetrics consistencyMetrics;
Review Comment:
`runConsistentlyMetrics`
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RunConsistentlyMetrics.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.mv;
+
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.pagememory.metrics.CollectionMetricSource;
+
+/**
+ * Metrics for runConsistently operation.
+ *
+ * <p>Tracks runConsistently closure execution performance including duration
+ * and active call count.
+ */
+public class RunConsistentlyMetrics {
+ /**
+ * Histogram buckets for runConsistently duration in nanoseconds.
+ *
+ * <p>Covers operations from fast single-row writes to slow bulk operations with checkpoint contention:
+ * <ul>
+ * <li>10µs: Fast single-row operations without lock contention</li>
+ * <li>100µs: Multi-row operations, small index operations</li>
+ * <li>1ms: Medium-sized operations</li>
+ * <li>10ms: Larger operations, small vacuum operations</li>
+ * <li>100ms: Large operations, significant vacuum work</li>
+ * <li>1s: Very slow operations, likely checkpoint write lock contention</li>
+ * <li>10s: Pathological cases requiring investigation</li>
+ * </ul>
+ */
+ private static final long[] RUN_CONSISTENTLY_NANOS = {
+ 10_000, // 10µs
+ 100_000, // 100µs
+ 1_000_000, // 1ms
+ 10_000_000, // 10ms
+ 100_000_000, // 100ms
+ 1_000_000_000, // 1s
+ 10_000_000_000L, // 10s
+ };
+
+ private final DistributionMetric runConsistentlyDuration;
+ private final AtomicIntMetric runConsistentlyActiveCount;
+
+ /**
+ * Constructor.
+ *
+ * @param metricSource Metric source to register metrics with.
+ */
+ public RunConsistentlyMetrics(CollectionMetricSource metricSource) {
+ runConsistentlyDuration = metricSource.addMetric(new DistributionMetric(
+ "RunConsistentlyDuration",
+ "Time spent in runConsistently closures in nanoseconds.",
+ RUN_CONSISTENTLY_NANOS
+ ));
+
+ runConsistentlyActiveCount = metricSource.addMetric(new AtomicIntMetric(
+ "RunConsistentlyActiveCount",
+ "Current number of active runConsistently calls."
+ ));
+ }
+
+ /**
+ * Records the duration of a runConsistently closure execution in nanoseconds.
+ */
+ public void recordRunConsistentlyDuration(long durationNanos) {
+ runConsistentlyDuration.add(durationNanos);
+ }
+
+ /**
+ * Increments the active count of runConsistently calls.
+ */
+ public void incrementActiveCount() {
+ runConsistentlyActiveCount.increment();
+ }
+
+ /**
+ * Decrements the active count of runConsistently calls.
+ */
+ public void decrementActiveCount() {
+ runConsistentlyActiveCount.decrement();
+ }
+
+ /** Returns the runConsistently duration metric for testing. */
+ DistributionMetric runConsistentlyDuration() {
Review Comment:
Should it be annotated as `@TestOnly` if it's only for testing?
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RunConsistentlyMetrics.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.mv;
+
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.pagememory.metrics.CollectionMetricSource;
+
+/**
+ * Metrics for runConsistently operation.
+ *
+ * <p>Tracks runConsistently closure execution performance including duration
+ * and active call count.
+ */
+public class RunConsistentlyMetrics {
+ /**
+ * Histogram buckets for runConsistently duration in nanoseconds.
+ *
+ * <p>Covers operations from fast single-row writes to slow bulk operations with checkpoint contention:
+ * <ul>
+ * <li>10µs: Fast single-row operations without lock contention</li>
+ * <li>100µs: Multi-row operations, small index operations</li>
+ * <li>1ms: Medium-sized operations</li>
+ * <li>10ms: Larger operations, small vacuum operations</li>
+ * <li>100ms: Large operations, significant vacuum work</li>
+ * <li>1s: Very slow operations, likely checkpoint write lock contention</li>
+ * <li>10s: Pathological cases requiring investigation</li>
Review Comment:
Are those comments are results of experiments or they are just guesses? If it's the latter, let's remove them to avoid confusion. A ladder of values each of them is 10 times the previous one seems to be useful by itself, even without those interpretations
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RunConsistentlyMetrics.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.mv;
+
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.pagememory.metrics.CollectionMetricSource;
+
+/**
+ * Metrics for runConsistently operation.
+ *
+ * <p>Tracks runConsistently closure execution performance including duration
+ * and active call count.
+ */
+public class RunConsistentlyMetrics {
+ /**
+ * Histogram buckets for runConsistently duration in nanoseconds.
+ *
+ * <p>Covers operations from fast single-row writes to slow bulk operations with checkpoint contention:
+ * <ul>
+ * <li>10µs: Fast single-row operations without lock contention</li>
+ * <li>100µs: Multi-row operations, small index operations</li>
+ * <li>1ms: Medium-sized operations</li>
+ * <li>10ms: Larger operations, small vacuum operations</li>
+ * <li>100ms: Large operations, significant vacuum work</li>
+ * <li>1s: Very slow operations, likely checkpoint write lock contention</li>
+ * <li>10s: Pathological cases requiring investigation</li>
+ * </ul>
+ */
+ private static final long[] RUN_CONSISTENTLY_NANOS = {
+ 10_000, // 10µs
+ 100_000, // 100µs
+ 1_000_000, // 1ms
+ 10_000_000, // 10ms
+ 100_000_000, // 100ms
+ 1_000_000_000, // 1s
+ 10_000_000_000L, // 10s
Review Comment:
Please use TimeUnit.XXX.toNanos() here to make the code more readable. The tail comments will become unnecessary, and it will be a lot more difficult to make a mistake
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RunConsistentlyMetrics.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.mv;
+
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.pagememory.metrics.CollectionMetricSource;
+
+/**
+ * Metrics for runConsistently operation.
+ *
+ * <p>Tracks runConsistently closure execution performance including duration
+ * and active call count.
+ */
+public class RunConsistentlyMetrics {
+ /**
+ * Histogram buckets for runConsistently duration in nanoseconds.
+ *
+ * <p>Covers operations from fast single-row writes to slow bulk operations with checkpoint contention:
+ * <ul>
+ * <li>10µs: Fast single-row operations without lock contention</li>
+ * <li>100µs: Multi-row operations, small index operations</li>
+ * <li>1ms: Medium-sized operations</li>
+ * <li>10ms: Larger operations, small vacuum operations</li>
+ * <li>100ms: Large operations, significant vacuum work</li>
+ * <li>1s: Very slow operations, likely checkpoint write lock contention</li>
+ * <li>10s: Pathological cases requiring investigation</li>
+ * </ul>
+ */
+ private static final long[] RUN_CONSISTENTLY_NANOS = {
+ 10_000, // 10µs
+ 100_000, // 100µs
+ 1_000_000, // 1ms
+ 10_000_000, // 10ms
+ 100_000_000, // 100ms
+ 1_000_000_000, // 1s
+ 10_000_000_000L, // 10s
+ };
+
+ private final DistributionMetric runConsistentlyDuration;
+ private final AtomicIntMetric runConsistentlyActiveCount;
+
+ /**
+ * Constructor.
+ *
+ * @param metricSource Metric source to register metrics with.
+ */
+ public RunConsistentlyMetrics(CollectionMetricSource metricSource) {
+ runConsistentlyDuration = metricSource.addMetric(new DistributionMetric(
+ "RunConsistentlyDuration",
+ "Time spent in runConsistently closures in nanoseconds.",
+ RUN_CONSISTENTLY_NANOS
+ ));
+
+ runConsistentlyActiveCount = metricSource.addMetric(new AtomicIntMetric(
+ "RunConsistentlyActiveCount",
+ "Current number of active runConsistently calls."
+ ));
+ }
+
+ /**
+ * Records the duration of a runConsistently closure execution in nanoseconds.
+ */
+ public void recordRunConsistentlyDuration(long durationNanos) {
+ runConsistentlyDuration.add(durationNanos);
+ }
+
+ /**
+ * Increments the active count of runConsistently calls.
+ */
+ public void incrementActiveCount() {
+ runConsistentlyActiveCount.increment();
+ }
+
+ /**
+ * Decrements the active count of runConsistently calls.
+ */
+ public void decrementActiveCount() {
+ runConsistentlyActiveCount.decrement();
+ }
+
+ /** Returns the runConsistently duration metric for testing. */
+ DistributionMetric runConsistentlyDuration() {
+ return runConsistentlyDuration;
+ }
+
+ /** Returns the runConsistently active count metric for testing. */
+ AtomicIntMetric runConsistentlyActiveCount() {
Review Comment:
`@TestOnly`?
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java:
##########
@@ -130,6 +131,8 @@ public class PersistentPageMemoryStorageEngine extends AbstractPageMemoryStorage
/** For unspecified tasks, i.e. throttling log. */
private final ExecutorService commonExecutorService;
+ private RunConsistentlyMetrics consistencyMetrics;
Review Comment:
Same thing about field name
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RunConsistentlyMetrics.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.mv;
+
+import org.apache.ignite.internal.metrics.AtomicIntMetric;
+import org.apache.ignite.internal.metrics.DistributionMetric;
+import org.apache.ignite.internal.pagememory.metrics.CollectionMetricSource;
+
+/**
+ * Metrics for runConsistently operation.
+ *
+ * <p>Tracks runConsistently closure execution performance including duration
+ * and active call count.
+ */
+public class RunConsistentlyMetrics {
+ /**
+ * Histogram buckets for runConsistently duration in nanoseconds.
+ *
+ * <p>Covers operations from fast single-row writes to slow bulk operations with checkpoint contention:
+ * <ul>
+ * <li>10µs: Fast single-row operations without lock contention</li>
+ * <li>100µs: Multi-row operations, small index operations</li>
+ * <li>1ms: Medium-sized operations</li>
+ * <li>10ms: Larger operations, small vacuum operations</li>
+ * <li>100ms: Large operations, significant vacuum work</li>
+ * <li>1s: Very slow operations, likely checkpoint write lock contention</li>
+ * <li>10s: Pathological cases requiring investigation</li>
+ * </ul>
+ */
+ private static final long[] RUN_CONSISTENTLY_NANOS = {
+ 10_000, // 10µs
+ 100_000, // 100µs
+ 1_000_000, // 1ms
+ 10_000_000, // 10ms
+ 100_000_000, // 100ms
+ 1_000_000_000, // 1s
+ 10_000_000_000L, // 10s
+ };
+
+ private final DistributionMetric runConsistentlyDuration;
+ private final AtomicIntMetric runConsistentlyActiveCount;
+
+ /**
+ * Constructor.
+ *
+ * @param metricSource Metric source to register metrics with.
+ */
+ public RunConsistentlyMetrics(CollectionMetricSource metricSource) {
+ runConsistentlyDuration = metricSource.addMetric(new DistributionMetric(
+ "RunConsistentlyDuration",
+ "Time spent in runConsistently closures in nanoseconds.",
Review Comment:
```suggestion
"Accumulated time spent in runConsistently closures in nanoseconds.",
```
If it never goes down
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org