This is an automated email from the ASF dual-hosted git repository.
ibessonov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 61d0735110e IGNITE-26600 Add TotalAllocatedSize table metric (#6692)
61d0735110e is described below
commit 61d0735110ef53b9622f61bfc417b0d7fb63322f
Author: Ivan Bessonov <[email protected]>
AuthorDate: Thu Oct 9 11:58:39 2025 +0300
IGNITE-26600 Add TotalAllocatedSize table metric (#6692)
---
.../internal/storage/engine/StorageEngine.java | 11 +++
.../storage/engine/StorageTableDescriptor.java | 7 ++
.../metrics/StorageEngineTablesMetricSource.java | 86 ++++++++++++++++++++++
.../internal/storage/util/MvPartitionStorages.java | 13 ++++
.../storage/engine/AbstractStorageEngineTest.java | 21 ++++++
.../pagememory/PersistentPageMemoryDataRegion.java | 40 ++++++++--
.../PersistentPageMemoryStorageEngine.java | 10 +++
...PageMemoryStorageEngineConfigurationSchema.java | 5 +-
.../mv/PersistentPageMemoryMvPartitionStorage.java | 7 ++
.../PersistentPageMemoryStorageEngineTest.java | 51 +++++++++++++
...entPageMemoryMvTableStorageConcurrencyTest.java | 5 --
.../internal/table/distributed/TableManager.java | 51 ++++++++++---
.../internal/table/metrics/TableMetricSource.java | 9 ++-
13 files changed, 292 insertions(+), 24 deletions(-)
diff --git
a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageEngine.java
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageEngine.java
index af931962128..7c32e1a9786 100644
---
a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageEngine.java
+++
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageEngine.java
@@ -23,6 +23,7 @@ import static
org.apache.ignite.internal.util.IgniteUtils.getTotalMemoryAvailabl
import java.util.Set;
import org.apache.ignite.internal.storage.StorageException;
import org.apache.ignite.internal.storage.index.StorageIndexDescriptorSupplier;
+import
org.apache.ignite.internal.storage.metrics.StorageEngineTablesMetricSource;
/**
* General storage engine interface.
@@ -73,6 +74,16 @@ public interface StorageEngine {
*/
void destroyMvTable(int tableId);
+ /**
+ * Adds metrics related to the table to the given metric source.
+ *
+ * @param tableDescriptor Table descriptor.
+ * @param metricSource Metric source.
+ */
+ default void addTableMetrics(StorageTableDescriptor tableDescriptor,
StorageEngineTablesMetricSource metricSource) {
+ // No-op.
+ }
+
/**
* Default size of a data region, maximum between 256 MiB and 20% of the
total physical memory.
*
diff --git
a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageTableDescriptor.java
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageTableDescriptor.java
index 265b5c42588..aed8c77e5c7 100644
---
a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageTableDescriptor.java
+++
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/StorageTableDescriptor.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.storage.engine;
+import org.apache.ignite.internal.tostring.S;
+
/**
* Table descriptor.
*/
@@ -60,4 +62,9 @@ public class StorageTableDescriptor {
public String getStorageProfile() {
return storageProfile;
}
+
+ @Override
+ public String toString() {
+ return S.toString(StorageTableDescriptor.class, this);
+ }
}
diff --git
a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/metrics/StorageEngineTablesMetricSource.java
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/metrics/StorageEngineTablesMetricSource.java
new file mode 100644
index 00000000000..d9b68a35a48
--- /dev/null
+++
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/metrics/StorageEngineTablesMetricSource.java
@@ -0,0 +1,86 @@
+/*
+ * 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.metrics;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.ignite.internal.metrics.AbstractMetricSource;
+import org.apache.ignite.internal.metrics.Metric;
+import org.apache.ignite.table.QualifiedName;
+
+/**
+ * Metric source for storage engine metrics related to a specific table.
+ */
+public class StorageEngineTablesMetricSource extends
AbstractMetricSource<StorageEngineTablesMetricSource.Holder> {
+ public static final String METRIC_GROUP = "storage";
+
+ private final Set<Metric> extraMetrics = new HashSet<>();
+
+ /**
+ * Creates a new metric source for the given storage engine and table,
with a name {@code storage.<engine>.tables.<tableName>} and
+ * group {@value METRIC_GROUP}.
+ *
+ * @param engine Storage engine name.
+ * @param tableName Table qualified name.
+ */
+ public StorageEngineTablesMetricSource(String engine, QualifiedName
tableName) {
+ super(sourceName(engine, tableName), "\"" + engine + "\" storage
engine metrics for the specific table.", METRIC_GROUP);
+ }
+
+ /**
+ * Returns a metric source name for the given storage engine and table.
+ */
+ public static String sourceName(String engine, QualifiedName tableName) {
+ return METRIC_GROUP + '.' + engine + ".tables." +
tableName.toCanonicalForm();
+ }
+
+ /**
+ * Adds a custom metric to the source.
+ *
+ * <p>Note: This method cannot be called when the source is enabled.
+ *
+ * @param metric Metric to add.
+ */
+ public void addMetric(Metric metric) {
+ assert holder() == null : "Cannot add metrics when source is enabled";
+
+ extraMetrics.add(metric);
+ }
+
+ @Override
+ protected Holder createHolder() {
+ return new Holder(extraMetrics);
+ }
+
+ /**
+ * Holder for the storage engine table metrics.
+ */
+ public static class Holder implements AbstractMetricSource.Holder<Holder> {
+ private final List<Metric> metrics;
+
+ protected Holder(Set<Metric> extraMetrics) {
+ metrics = List.copyOf(extraMetrics);
+ }
+
+ @Override
+ public Iterable<Metric> metrics() {
+ return metrics;
+ }
+ }
+}
diff --git
a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/MvPartitionStorages.java
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/MvPartitionStorages.java
index 9ed8b1db1b9..3079470b9cb 100644
---
a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/MvPartitionStorages.java
+++
b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/MvPartitionStorages.java
@@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.IntStream;
+import java.util.stream.Stream;
import org.apache.ignite.internal.lang.IgniteStringFormatter;
import org.apache.ignite.internal.storage.MvPartitionStorage;
import org.apache.ignite.internal.storage.StorageException;
@@ -454,6 +455,18 @@ public class MvPartitionStorages<T extends
MvPartitionStorage> {
return list;
}
+ /**
+ * Returns a stream of all existing storages.
+ *
+ * <p>Note: this method may produce races when a rebalance is happening
concurrently as the underlying storage array may change.
+ * The callers of this method should resolve these races themselves.
+ */
+ public Stream<T> stream() {
+ return IntStream.range(0, storageByPartitionId.length())
+ .mapToObj(storageByPartitionId::get)
+ .filter(Objects::nonNull);
+ }
+
/**
* Returns all storages for closing or destroying after completion of
operations for all storages.
*
diff --git
a/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/engine/AbstractStorageEngineTest.java
b/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/engine/AbstractStorageEngineTest.java
index d034daf27e0..af4cd6e3efd 100644
---
a/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/engine/AbstractStorageEngineTest.java
+++
b/modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/engine/AbstractStorageEngineTest.java
@@ -17,13 +17,20 @@
package org.apache.ignite.internal.storage.engine;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.emptyIterable;
+import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.mock;
+import org.apache.ignite.internal.catalog.CatalogService;
import org.apache.ignite.internal.components.LogSyncer;
import org.apache.ignite.internal.storage.AbstractMvTableStorageTest;
import org.apache.ignite.internal.storage.BaseMvStoragesTest;
+import
org.apache.ignite.internal.storage.metrics.StorageEngineTablesMetricSource;
+import org.apache.ignite.table.QualifiedName;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -57,4 +64,18 @@ public abstract class AbstractStorageEngineTest extends
BaseMvStoragesTest {
* directory.
*/
protected abstract StorageEngine createEngine();
+
+ @Test
+ protected void tableMetrics() {
+ var tableDescriptor = new StorageTableDescriptor(10, 1,
CatalogService.DEFAULT_STORAGE_PROFILE);
+ storageEngine.createMvTable(tableDescriptor, indexId -> null);
+
+ QualifiedName tableName =
QualifiedName.of(QualifiedName.DEFAULT_SCHEMA_NAME, "foo");
+
+ StorageEngineTablesMetricSource metricSource = new
StorageEngineTablesMetricSource(storageEngine.name(), tableName);
+ storageEngine.addTableMetrics(tableDescriptor, metricSource);
+
+ metricSource.enable();
+ assertThat(metricSource.holder().metrics(), is(emptyIterable()));
+ }
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
index 45b54e3dc78..afedfe68ecc 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
@@ -28,8 +28,8 @@ import static org.apache.ignite.internal.util.Constants.MiB;
import java.nio.ByteBuffer;
import java.util.Arrays;
-import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
@@ -59,6 +59,8 @@ import
org.apache.ignite.internal.pagememory.persistence.throttling.TargetRatioP
import
org.apache.ignite.internal.pagememory.persistence.throttling.ThrottlingType;
import org.apache.ignite.internal.storage.StorageException;
import org.apache.ignite.internal.storage.engine.StorageEngine;
+import org.apache.ignite.internal.storage.engine.StorageTableDescriptor;
+import
org.apache.ignite.internal.storage.metrics.StorageEngineTablesMetricSource;
import
org.apache.ignite.internal.storage.pagememory.configuration.schema.PersistentPageMemoryProfileConfiguration;
import
org.apache.ignite.internal.storage.pagememory.configuration.schema.PersistentPageMemoryProfileView;
import
org.apache.ignite.internal.storage.pagememory.mv.PersistentPageMemoryMvPartitionStorage;
@@ -111,7 +113,7 @@ public class PersistentPageMemoryDataRegion implements
DataRegion<PersistentPage
private final PersistentPageMemoryMetricSource metricSource;
- private final Collection<PersistentPageMemoryTableStorage> tableStorages =
ConcurrentHashMap.newKeySet();
+ private final ConcurrentMap<Integer, PersistentPageMemoryTableStorage>
tableStorages = new ConcurrentHashMap<>();
/**
* Constructor.
@@ -437,13 +439,13 @@ public class PersistentPageMemoryDataRegion implements
DataRegion<PersistentPage
/** Adds a table storage to the data region. */
@VisibleForTesting
public void addTableStorage(PersistentPageMemoryTableStorage tableStorage)
{
- boolean add = tableStorages.add(tableStorage);
+ PersistentPageMemoryTableStorage old =
tableStorages.put(tableStorage.getTableId(), tableStorage);
- assert add : tableStorage.getTableId();
+ assert old == null : "Table storage for tableId=" +
tableStorage.getTableId() + " already exists";
}
void removeTableStorage(PersistentPageMemoryTableStorage tableStorage) {
- tableStorages.remove(tableStorage);
+ tableStorages.remove(tableStorage.getTableId());
}
private void initMetrics() {
@@ -459,10 +461,34 @@ public class PersistentPageMemoryDataRegion implements
DataRegion<PersistentPage
));
}
+ /**
+ * Registers region-specific metrics for the given table.
+ *
+ * @param tableDescriptor Table descriptor.
+ * @param metricSource Metric source for registering metrics.
+ */
+ void addTableMetrics(StorageTableDescriptor tableDescriptor,
StorageEngineTablesMetricSource metricSource) {
+ PersistentPageMemoryTableStorage tableStorage =
tableStorages.get(tableDescriptor.getId());
+
+ assert tableStorage != null : "Adding metrics for a non-existent
table: " + tableDescriptor;
+
+ metricSource.addMetric(new LongGauge(
+ "TotalAllocatedSize",
+ "Total size of all pages allocated by '" + ENGINE_NAME + "'
storage engine for a given table, in bytes.",
+ () -> {
+ long totalPages = tableStorage.mvPartitionStorages.stream()
+
.mapToLong(PersistentPageMemoryMvPartitionStorage::pageCount)
+ .sum();
+
+ return pageSize * totalPages;
+ }
+ ));
+ }
+
private long totalAllocatedPagesSizeOnDiskInBytes() {
long pageCount = 0;
- for (PersistentPageMemoryTableStorage tableStorage : tableStorages) {
+ for (PersistentPageMemoryTableStorage tableStorage :
tableStorages.values()) {
for (PersistentPageMemoryMvPartitionStorage partitionStorage :
tableStorage.mvPartitionStorages.getAll()) {
pageCount +=
allocatedPageCountOnDisk(tableStorage.getTableId(),
partitionStorage.partitionId());
}
@@ -474,7 +500,7 @@ public class PersistentPageMemoryDataRegion implements
DataRegion<PersistentPage
private long totalNonEmptyAllocatedPagesSizeOnDiskInBytes() {
long pageCount = 0;
- for (PersistentPageMemoryTableStorage tableStorage : tableStorages) {
+ for (PersistentPageMemoryTableStorage tableStorage :
tableStorages.values()) {
for (PersistentPageMemoryMvPartitionStorage partitionStorage :
tableStorage.mvPartitionStorages.getAll()) {
pageCount +=
allocatedPageCountOnDisk(tableStorage.getTableId(),
partitionStorage.partitionId());
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
index 8d257645863..767c153b92a 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryStorageEngine.java
@@ -57,6 +57,7 @@ import
org.apache.ignite.internal.storage.configurations.StorageProfileView;
import org.apache.ignite.internal.storage.engine.MvTableStorage;
import org.apache.ignite.internal.storage.engine.StorageTableDescriptor;
import org.apache.ignite.internal.storage.index.StorageIndexDescriptorSupplier;
+import
org.apache.ignite.internal.storage.metrics.StorageEngineTablesMetricSource;
import
org.apache.ignite.internal.storage.pagememory.configuration.schema.PageMemoryCheckpointConfiguration;
import
org.apache.ignite.internal.storage.pagememory.configuration.schema.PersistentPageMemoryProfileConfiguration;
import
org.apache.ignite.internal.storage.pagememory.configuration.schema.PersistentPageMemoryProfileView;
@@ -332,6 +333,15 @@ public class PersistentPageMemoryStorageEngine extends
AbstractPageMemoryStorage
}
}
+ @Override
+ public void addTableMetrics(StorageTableDescriptor tableDescriptor,
StorageEngineTablesMetricSource metricSource) {
+ PersistentPageMemoryDataRegion region =
regions.get(tableDescriptor.getStorageProfile());
+
+ assert region != null : "Adding metrics to the table with non-existent
data region. [tableDescriptor=" + tableDescriptor + ']';
+
+ region.addTableMetrics(tableDescriptor, metricSource);
+ }
+
/**
* Returns checkpoint manager, {@code null} if engine not started.
*/
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/configuration/schema/PersistentPageMemoryStorageEngineConfigurationSchema.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/configuration/schema/PersistentPageMemoryStorageEngineConfigurationSchema.java
index 6d1ac110398..893f7b50bf4 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/configuration/schema/PersistentPageMemoryStorageEngineConfigurationSchema.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/configuration/schema/PersistentPageMemoryStorageEngineConfigurationSchema.java
@@ -31,12 +31,15 @@ import
org.apache.ignite.internal.storage.pagememory.PersistentPageMemoryStorage
*/
@Config
public class PersistentPageMemoryStorageEngineConfigurationSchema {
+ /** Default page size for the engine. */
+ public static final int DEFAULT_PAGE_SIZE = 16 * 1024;
+
@Immutable
@PowerOfTwo
@Range(min = 1024, max = 16 * 1024)
@Value(hasDefault = true)
@PublicName(legacyNames = "pageSize")
- public int pageSizeBytes = 16 * 1024;
+ public int pageSizeBytes = DEFAULT_PAGE_SIZE;
/* Checkpoint configuration for persistent data regions. */
@ConfigValue
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
index 59626b843f4..4d18553fde2 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvPartitionStorage.java
@@ -555,6 +555,13 @@ public class PersistentPageMemoryMvPartitionStorage
extends AbstractPageMemoryMv
return meta.estimatedSize();
}
+ /**
+ * Returns a total number of allocated pages for the storage, including
pages that are not in the memory currently.
+ */
+ public int pageCount() {
+ return meta.pageCount();
+ }
+
@Override
public void incrementEstimatedSize() {
updateMeta((lastCheckpointId, meta) ->
meta.incrementEstimatedSize(lastCheckpointId));
diff --git
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/engine/PersistentPageMemoryStorageEngineTest.java
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/engine/PersistentPageMemoryStorageEngineTest.java
index 49742c22cd4..ffc41c2a40b 100644
---
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/engine/PersistentPageMemoryStorageEngineTest.java
+++
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/engine/PersistentPageMemoryStorageEngineTest.java
@@ -17,27 +17,41 @@
package org.apache.ignite.internal.storage.pagememory.engine;
+import static
org.apache.ignite.internal.storage.pagememory.configuration.schema.PersistentPageMemoryStorageEngineConfigurationSchema.DEFAULT_PAGE_SIZE;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import java.nio.file.Path;
+import java.util.Iterator;
import java.util.concurrent.ExecutorService;
+import org.apache.ignite.internal.catalog.CatalogService;
import
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
import org.apache.ignite.internal.failure.FailureManager;
+import org.apache.ignite.internal.metrics.LongMetric;
+import org.apache.ignite.internal.metrics.Metric;
import org.apache.ignite.internal.metrics.MetricManager;
import org.apache.ignite.internal.pagememory.io.PageIoRegistry;
import org.apache.ignite.internal.storage.configurations.StorageConfiguration;
import org.apache.ignite.internal.storage.configurations.StorageProfileView;
import
org.apache.ignite.internal.storage.engine.AbstractPersistentStorageEngineTest;
import org.apache.ignite.internal.storage.engine.AbstractStorageEngineTest;
+import org.apache.ignite.internal.storage.engine.MvTableStorage;
import org.apache.ignite.internal.storage.engine.StorageEngine;
+import org.apache.ignite.internal.storage.engine.StorageTableDescriptor;
+import
org.apache.ignite.internal.storage.metrics.StorageEngineTablesMetricSource;
import
org.apache.ignite.internal.storage.pagememory.PersistentPageMemoryStorageEngine;
import
org.apache.ignite.internal.storage.pagememory.configuration.schema.PersistentPageMemoryProfileView;
import org.apache.ignite.internal.testframework.ExecutorServiceExtension;
import org.apache.ignite.internal.testframework.InjectExecutorService;
import org.apache.ignite.internal.testframework.WorkDirectory;
import org.apache.ignite.internal.testframework.WorkDirectoryExtension;
+import org.apache.ignite.table.QualifiedName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -98,4 +112,41 @@ public class PersistentPageMemoryStorageEngineTest extends
AbstractPersistentSto
protected void persistTableDestructionIfNeeded() {
// No-op as table destruction is durable for this engine.
}
+
+ @Test
+ @Override
+ protected void tableMetrics() {
+ var engine = (PersistentPageMemoryStorageEngine) storageEngine;
+
+ var tableDescriptor = new StorageTableDescriptor(10, 1,
CatalogService.DEFAULT_STORAGE_PROFILE);
+ MvTableStorage table = engine.createMvTable(tableDescriptor, indexId
-> null);
+
+ QualifiedName tableName =
QualifiedName.of(QualifiedName.DEFAULT_SCHEMA_NAME, "foo");
+
+ StorageEngineTablesMetricSource metricSource = new
StorageEngineTablesMetricSource(storageEngine.name(), tableName);
+ storageEngine.addTableMetrics(tableDescriptor, metricSource);
+
+ metricSource.enable();
+ Iterator<Metric> metrics = metricSource.holder().metrics().iterator();
+ assertTrue(metrics.hasNext());
+
+ Metric metric = metrics.next();
+ assertThat(metric.name(), is("TotalAllocatedSize"));
+ assertThat(metric, is(instanceOf(LongMetric.class)));
+
+ assertFalse(metrics.hasNext());
+
+ LongMetric totalAllocatedSize = (LongMetric) metric;
+ assertEquals(0, totalAllocatedSize.value());
+
+ var otherTableDescriptor = new StorageTableDescriptor(20, 1,
CatalogService.DEFAULT_STORAGE_PROFILE);
+ MvTableStorage otherTable = engine.createMvTable(otherTableDescriptor,
indexId -> null);
+
+ otherTable.createMvPartition(0);
+ assertEquals(0, totalAllocatedSize.value());
+
+ table.createMvPartition(0);
+ assertThat(totalAllocatedSize.value(), is(greaterThan(0L)));
+ assertEquals(0, totalAllocatedSize.value() % DEFAULT_PAGE_SIZE);
+ }
}
diff --git
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvTableStorageConcurrencyTest.java
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvTableStorageConcurrencyTest.java
index 89313528847..85ab3220166 100644
---
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvTableStorageConcurrencyTest.java
+++
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/PersistentPageMemoryMvTableStorageConcurrencyTest.java
@@ -75,11 +75,6 @@ class PersistentPageMemoryMvTableStorageConcurrencyTest
extends AbstractMvTableS
engine.start();
- tableStorage = engine.createMvTable(
- new StorageTableDescriptor(1, DEFAULT_PARTITION_COUNT,
DEFAULT_STORAGE_PROFILE),
- indexDescriptorSupplier
- );
-
initialize();
}
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
index eb7c7e92c97..1da94c5d46c 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
@@ -211,6 +211,7 @@ import
org.apache.ignite.internal.storage.StorageDestroyedException;
import org.apache.ignite.internal.storage.engine.MvTableStorage;
import org.apache.ignite.internal.storage.engine.StorageEngine;
import org.apache.ignite.internal.storage.engine.StorageTableDescriptor;
+import
org.apache.ignite.internal.storage.metrics.StorageEngineTablesMetricSource;
import org.apache.ignite.internal.table.IgniteTablesInternal;
import org.apache.ignite.internal.table.InternalTable;
import org.apache.ignite.internal.table.LongPriorityQueue;
@@ -1840,7 +1841,7 @@ public class TableManager implements
IgniteTablesInternal, IgniteComponent {
() -> txCfg.value().readWriteTimeoutMillis(),
() -> txCfg.value().readOnlyTimeoutMillis(),
nodeProperties.colocationEnabled(),
- createAndRegisterMetricsSource(tableName)
+
createAndRegisterMetricsSource(tableStorage.getTableDescriptor(), tableName)
);
return new TableImpl(
@@ -3637,29 +3638,59 @@ public class TableManager implements
IgniteTablesInternal, IgniteComponent {
}
}
- private TableMetricSource createAndRegisterMetricsSource(QualifiedName
tableName) {
+ private TableMetricSource
createAndRegisterMetricsSource(StorageTableDescriptor tableDescriptor,
QualifiedName tableName) {
+ StorageEngine engine =
dataStorageMgr.engineByStorageProfile(tableDescriptor.getStorageProfile());
+
+ // Engine can be null sometimes, see "TableManager.createTableStorage".
+ if (engine != null) {
+ StorageEngineTablesMetricSource engineMetricSource = new
StorageEngineTablesMetricSource(engine.name(), tableName);
+
+ engine.addTableMetrics(tableDescriptor, engineMetricSource);
+
+ try {
+ metricManager.registerSource(engineMetricSource);
+ metricManager.enable(engineMetricSource);
+ } catch (Exception e) {
+ String message = "Failed to register storage engine metrics
source for table [id={}, name={}].";
+ LOG.warn(message, e, tableDescriptor.getId(), tableName);
+ }
+ }
+
TableMetricSource source = new TableMetricSource(tableName);
try {
metricManager.registerSource(source);
metricManager.enable(source);
} catch (Exception e) {
- LOG.warn("Failed to register metrics source for table [name={}].",
e, source.qualifiedTableName());
+ LOG.warn("Failed to register metrics source for table [id={},
name={}].", e, tableDescriptor.getId(), tableName);
}
return source;
}
private void unregisterMetricsSource(int tableId) {
- try {
- TableViewInternal table = startedTables.get(tableId);
- if (table == null) {
- return;
- }
+ TableViewInternal table = startedTables.get(tableId);
+ if (table == null) {
+ return;
+ }
- metricManager.unregisterSource(table.metrics());
+ QualifiedName tableName = table.qualifiedName();
+
+ try {
+
metricManager.unregisterSource(TableMetricSource.sourceName(tableName));
} catch (Exception e) {
- LOG.warn("Failed to unregister metrics source for table
[tableId={}].", e, tableId);
+ LOG.warn("Failed to unregister metrics source for table [id={},
name={}].", e, tableId, tableName);
+ }
+
+ String storageProfile =
table.internalTable().storage().getTableDescriptor().getStorageProfile();
+ StorageEngine engine =
dataStorageMgr.engineByStorageProfile(storageProfile);
+ // Engine can be null sometimes, see "TableManager.createTableStorage".
+ if (engine != null) {
+ try {
+
metricManager.unregisterSource(StorageEngineTablesMetricSource.sourceName(engine.name(),
tableName));
+ } catch (Exception e) {
+ LOG.warn("Failed to unregister storage engine metrics source
for table [id={}, name={}].", e, tableId, tableName);
+ }
}
}
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/metrics/TableMetricSource.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/metrics/TableMetricSource.java
index 0348a4f9b79..732c6b55f24 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/metrics/TableMetricSource.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/metrics/TableMetricSource.java
@@ -124,10 +124,17 @@ public class TableMetricSource extends
AbstractMetricSource<Holder> {
* @param tableName Qualified table name.
*/
public TableMetricSource(QualifiedName tableName) {
- super(SOURCE_NAME + '.' + tableName.toCanonicalForm(), "Table
metrics.", "tables");
+ super(sourceName(tableName), "Table metrics.", "tables");
this.tableName = tableName;
}
+ /**
+ * Returns a metric source name for the given table.
+ */
+ public static String sourceName(QualifiedName tableName) {
+ return SOURCE_NAME + '.' + tableName.toCanonicalForm();
+ }
+
/**
* Returns the qualified name of the table.
*