This is an automated email from the ASF dual-hosted git repository.
jinsongzhou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git
The following commit(s) were added to refs/heads/master by this push:
new 854f8d40c [AMORO-3104] Added table summary metrics (#3109)
854f8d40c is described below
commit 854f8d40c216a0bc4ba706742499d755fc54ce94
Author: Marig_Weizhi <[email protected]>
AuthorDate: Fri Aug 30 14:16:51 2024 +0800
[AMORO-3104] Added table summary metrics (#3109)
* add table summary metrics
* remove pendingInput
* update metrics doc
* add unit test
* update for table summary metrics
* add unit test
* update unit test for table summary metrics
* update unit test for table summary metrics
* update test for table summary metrics
* Update
amoro-ams/amoro-ams-server/src/main/resources/postgres/ams-postgres-init.sql
Co-authored-by: ZhouJinsong <[email protected]>
* Update amoro-ams/amoro-ams-server/src/main/resources/postgres/upgrade.sql
Co-authored-by: ZhouJinsong <[email protected]>
---------
Co-authored-by: ZhouJinsong <[email protected]>
---
.../optimizing/plan/AbstractPartitionPlan.java | 20 ++
.../optimizing/plan/CommonPartitionEvaluator.java | 39 ++++
.../optimizing/plan/OptimizingEvaluator.java | 39 +++-
.../server/optimizing/plan/PartitionEvaluator.java | 12 +
.../server/persistence/mapper/TableMetaMapper.java | 12 +-
.../apache/amoro/server/table/TableRuntime.java | 19 +-
.../amoro/server/table/TableRuntimeMeta.java | 13 ++
.../amoro/server/table/TableSummaryMetrics.java | 241 +++++++++++++++++++++
.../executor/TableRuntimeRefreshExecutor.java | 3 +-
.../src/main/resources/derby/ams-derby-init.sql | 1 +
.../src/main/resources/mysql/ams-mysql-init.sql | 1 +
.../src/main/resources/mysql/upgrade.sql | 3 +
.../main/resources/postgres/ams-postgres-init.sql | 2 +
.../src/main/resources/postgres/upgrade.sql | 4 +
.../optimizing/plan/TestOptimizingEvaluator.java | 6 +-
.../server/table/TestTableSummaryMetrics.java | 223 +++++++++++++++++++
docs/user-guides/metrics.md | 28 ++-
17 files changed, 651 insertions(+), 15 deletions(-)
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/AbstractPartitionPlan.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/AbstractPartitionPlan.java
index a97512b55..5a87cd9e2 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/AbstractPartitionPlan.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/AbstractPartitionPlan.java
@@ -191,6 +191,11 @@ public abstract class AbstractPartitionPlan implements
PartitionEvaluator {
return evaluator().getFragmentFileSize();
}
+ @Override
+ public long getFragmentFileRecords() {
+ return evaluator().getFragmentFileRecords();
+ }
+
@Override
public int getSegmentFileCount() {
return evaluator().getSegmentFileCount();
@@ -201,6 +206,11 @@ public abstract class AbstractPartitionPlan implements
PartitionEvaluator {
return evaluator().getSegmentFileSize();
}
+ @Override
+ public long getSegmentFileRecords() {
+ return evaluator().getSegmentFileRecords();
+ }
+
@Override
public int getEqualityDeleteFileCount() {
return evaluator().getEqualityDeleteFileCount();
@@ -211,6 +221,11 @@ public abstract class AbstractPartitionPlan implements
PartitionEvaluator {
return evaluator().getEqualityDeleteFileSize();
}
+ @Override
+ public long getEqualityDeleteFileRecords() {
+ return evaluator().getEqualityDeleteFileRecords();
+ }
+
@Override
public int getPosDeleteFileCount() {
return evaluator().getPosDeleteFileCount();
@@ -221,6 +236,11 @@ public abstract class AbstractPartitionPlan implements
PartitionEvaluator {
return evaluator().getPosDeleteFileSize();
}
+ @Override
+ public long getPosDeleteFileRecords() {
+ return evaluator().getPosDeleteFileRecords();
+ }
+
@Override
public Weight getWeight() {
return evaluator().getWeight();
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/CommonPartitionEvaluator.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/CommonPartitionEvaluator.java
index cded0ca33..ffdb2660c 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/CommonPartitionEvaluator.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/CommonPartitionEvaluator.java
@@ -52,23 +52,29 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
// fragment files
protected int fragmentFileCount = 0;
protected long fragmentFileSize = 0;
+ protected long fragmentFileRecords = 0;
// segment files
protected int rewriteSegmentFileCount = 0;
protected long rewriteSegmentFileSize = 0L;
+ protected long rewriteSegmentFileRecords = 0L;
protected int undersizedSegmentFileCount = 0;
protected long undersizedSegmentFileSize = 0;
+ protected long undersizedSegmentFileRecords = 0;
protected int rewritePosSegmentFileCount = 0;
protected int combinePosSegmentFileCount = 0;
protected long rewritePosSegmentFileSize = 0L;
+ protected long rewritePosSegmentFileRecords = 0L;
protected long min1SegmentFileSize = Integer.MAX_VALUE;
protected long min2SegmentFileSize = Integer.MAX_VALUE;
// delete files
protected int equalityDeleteFileCount = 0;
protected long equalityDeleteFileSize = 0L;
+ protected long equalityDeleteFileRecords = 0L;
protected int posDeleteFileCount = 0;
protected long posDeleteFileSize = 0L;
+ protected long posDeleteFileRecords = 0L;
private long cost = -1;
private Boolean necessary = null;
@@ -132,6 +138,7 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
private boolean addFragmentFile(DataFile dataFile, List<ContentFile<?>>
deletes) {
fragmentFileSize += dataFile.fileSizeInBytes();
fragmentFileCount++;
+ fragmentFileRecords += dataFile.recordCount();
for (ContentFile<?> delete : deletes) {
addDelete(delete);
@@ -149,6 +156,7 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
if (fileShouldRewrite(dataFile, deletes)) {
rewriteSegmentFileSize += dataFile.fileSizeInBytes();
rewriteSegmentFileCount++;
+ rewriteSegmentFileRecords += dataFile.recordCount();
return true;
}
@@ -162,6 +170,7 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
undersizedSegmentFileSize += dataFile.fileSizeInBytes();
undersizedSegmentFileCount++;
+ undersizedSegmentFileRecords += dataFile.recordCount();
return true;
}
@@ -169,6 +178,7 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
if (fileShouldRewrite(dataFile, deletes)) {
rewriteSegmentFileSize += dataFile.fileSizeInBytes();
rewriteSegmentFileCount++;
+ rewriteSegmentFileRecords += dataFile.recordCount();
for (ContentFile<?> delete : deletes) {
addDelete(delete);
}
@@ -178,6 +188,7 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
if (segmentShouldRewritePos(dataFile, deletes)) {
rewritePosSegmentFileSize += dataFile.fileSizeInBytes();
rewritePosSegmentFileCount++;
+ rewritePosSegmentFileRecords += dataFile.recordCount();
for (ContentFile<?> delete : deletes) {
addDelete(delete);
}
@@ -241,9 +252,11 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
if (delete.content() == FileContent.POSITION_DELETES) {
posDeleteFileCount++;
posDeleteFileSize += delete.fileSizeInBytes();
+ posDeleteFileRecords += delete.recordCount();
} else {
equalityDeleteFileCount++;
equalityDeleteFileSize += delete.fileSizeInBytes();
+ equalityDeleteFileRecords += delete.recordCount();
}
}
@@ -366,6 +379,11 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
return fragmentFileSize;
}
+ @Override
+ public long getFragmentFileRecords() {
+ return fragmentFileRecords;
+ }
+
@Override
public int getSegmentFileCount() {
return rewriteSegmentFileCount + undersizedSegmentFileCount +
rewritePosSegmentFileCount;
@@ -376,6 +394,11 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
return rewriteSegmentFileSize + undersizedSegmentFileSize +
rewritePosSegmentFileSize;
}
+ @Override
+ public long getSegmentFileRecords() {
+ return rewriteSegmentFileRecords + undersizedSegmentFileRecords +
rewritePosSegmentFileRecords;
+ }
+
@Override
public int getEqualityDeleteFileCount() {
return equalityDeleteFileCount;
@@ -386,6 +409,11 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
return equalityDeleteFileSize;
}
+ @Override
+ public long getEqualityDeleteFileRecords() {
+ return equalityDeleteFileRecords;
+ }
+
@Override
public int getPosDeleteFileCount() {
return posDeleteFileCount;
@@ -396,6 +424,11 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
return posDeleteFileSize;
}
+ @Override
+ public long getPosDeleteFileRecords() {
+ return posDeleteFileRecords;
+ }
+
public static class Weight implements PartitionEvaluator.Weight {
private final long cost;
@@ -423,18 +456,24 @@ public class CommonPartitionEvaluator implements
PartitionEvaluator {
.add("lastFullOptimizeTime", tableRuntime.getLastFullOptimizingTime())
.add("fragmentFileCount", fragmentFileCount)
.add("fragmentFileSize", fragmentFileSize)
+ .add("fragmentFileRecords", fragmentFileRecords)
.add("rewriteSegmentFileCount", rewriteSegmentFileCount)
.add("rewriteSegmentFileSize", rewriteSegmentFileSize)
+ .add("rewriteSegmentFileRecords", rewriteSegmentFileRecords)
.add("undersizedSegmentFileCount", undersizedSegmentFileCount)
.add("undersizedSegmentFileSize", undersizedSegmentFileSize)
+ .add("undersizedSegmentFileRecords", undersizedSegmentFileRecords)
.add("rewritePosSegmentFileCount", rewritePosSegmentFileCount)
.add("rewritePosSegmentFileSize", rewritePosSegmentFileSize)
+ .add("rewritePosSegmentFileRecords", rewritePosSegmentFileRecords)
.add("min1SegmentFileSize", min1SegmentFileSize)
.add("min2SegmentFileSize", min2SegmentFileSize)
.add("equalityDeleteFileCount", equalityDeleteFileCount)
.add("equalityDeleteFileSize", equalityDeleteFileSize)
+ .add("equalityDeleteFileRecords", equalityDeleteFileRecords)
.add("posDeleteFileCount", posDeleteFileCount)
.add("posDeleteFileSize", posDeleteFileSize)
+ .add("posDeleteFileRecords", posDeleteFileRecords)
.toString();
}
}
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/OptimizingEvaluator.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/OptimizingEvaluator.java
index cadf5ae2a..7ce4c3e2d 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/OptimizingEvaluator.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/OptimizingEvaluator.java
@@ -50,6 +50,7 @@ import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
public class OptimizingEvaluator {
@@ -60,6 +61,7 @@ public class OptimizingEvaluator {
protected final TableSnapshot currentSnapshot;
protected boolean isInitialized = false;
+ protected Map<String, PartitionEvaluator> needOptimizingPlanMap =
Maps.newHashMap();
protected Map<String, PartitionEvaluator> partitionPlanMap =
Maps.newHashMap();
public OptimizingEvaluator(TableRuntime tableRuntime, MixedTable table) {
@@ -95,7 +97,7 @@ public class OptimizingEvaluator {
LOG.info(
"{} finished evaluating, found {} partitions that need optimizing in
{} ms",
mixedTable.id(),
- partitionPlanMap.size(),
+ needOptimizingPlanMap.size(),
System.currentTimeMillis() - startTime);
}
@@ -129,7 +131,10 @@ public class OptimizingEvaluator {
mixedTable.id(),
count,
System.currentTimeMillis() - startTime);
- partitionPlanMap.values().removeIf(plan -> !plan.isNecessary());
+ needOptimizingPlanMap.putAll(
+ partitionPlanMap.entrySet().stream()
+ .filter(entry -> entry.getValue().isNecessary())
+ .collect(Collectors.toMap(entry -> entry.getKey(), entry ->
entry.getValue())));
}
private Map<String, String> partitionProperties(Pair<Integer, StructLike>
partition) {
@@ -165,7 +170,7 @@ public class OptimizingEvaluator {
if (!isInitialized) {
initEvaluator();
}
- return !partitionPlanMap.isEmpty();
+ return !needOptimizingPlanMap.isEmpty();
}
public PendingInput getPendingInput() {
@@ -175,16 +180,26 @@ public class OptimizingEvaluator {
return new PendingInput(partitionPlanMap.values());
}
+ public PendingInput getOptimizingPendingInput() {
+ if (!isInitialized) {
+ initEvaluator();
+ }
+ return new PendingInput(needOptimizingPlanMap.values());
+ }
+
public static class PendingInput {
@JsonIgnore private final Map<Integer, Set<StructLike>> partitions =
Maps.newHashMap();
private int dataFileCount = 0;
private long dataFileSize = 0;
+ private long dataFileRecords = 0;
private int equalityDeleteFileCount = 0;
private int positionalDeleteFileCount = 0;
private long positionalDeleteBytes = 0L;
private long equalityDeleteBytes = 0L;
+ private long equalityDeleteFileRecords = 0L;
+ private long positionalDeleteFileRecords = 0L;
public PendingInput() {}
@@ -195,9 +210,12 @@ public class OptimizingEvaluator {
.add(evaluator.getPartition().second());
dataFileCount += evaluator.getFragmentFileCount() +
evaluator.getSegmentFileCount();
dataFileSize += evaluator.getFragmentFileSize() +
evaluator.getSegmentFileSize();
+ dataFileRecords += evaluator.getFragmentFileRecords() +
evaluator.getSegmentFileRecords();
positionalDeleteBytes += evaluator.getPosDeleteFileSize();
+ positionalDeleteFileRecords += evaluator.getPosDeleteFileRecords();
positionalDeleteFileCount += evaluator.getPosDeleteFileCount();
equalityDeleteBytes += evaluator.getEqualityDeleteFileSize();
+ equalityDeleteFileRecords += evaluator.getEqualityDeleteFileRecords();
equalityDeleteFileCount += evaluator.getEqualityDeleteFileCount();
}
}
@@ -214,6 +232,10 @@ public class OptimizingEvaluator {
return dataFileSize;
}
+ public long getDataFileRecords() {
+ return dataFileRecords;
+ }
+
public int getEqualityDeleteFileCount() {
return equalityDeleteFileCount;
}
@@ -230,16 +252,27 @@ public class OptimizingEvaluator {
return equalityDeleteBytes;
}
+ public long getEqualityDeleteFileRecords() {
+ return equalityDeleteFileRecords;
+ }
+
+ public long getPositionalDeleteFileRecords() {
+ return positionalDeleteFileRecords;
+ }
+
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("partitions", partitions)
.add("dataFileCount", dataFileCount)
.add("dataFileSize", dataFileSize)
+ .add("dataFileRecords", dataFileRecords)
.add("equalityDeleteFileCount", equalityDeleteFileCount)
.add("positionalDeleteFileCount", positionalDeleteFileCount)
.add("positionalDeleteBytes", positionalDeleteBytes)
.add("equalityDeleteBytes", equalityDeleteBytes)
+ .add("equalityDeleteFileRecords", equalityDeleteFileRecords)
+ .add("positionalDeleteFileRecords", positionalDeleteFileRecords)
.toString();
}
}
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/PartitionEvaluator.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/PartitionEvaluator.java
index 02d59b9a9..974703bf0 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/PartitionEvaluator.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/optimizing/plan/PartitionEvaluator.java
@@ -87,21 +87,33 @@ public interface PartitionEvaluator {
/** Get the total size of fragment files involved in optimizing. */
long getFragmentFileSize();
+ /** Get the total records of fragment files involved in optimizing. */
+ long getFragmentFileRecords();
+
/** Get the count of segment files involved in optimizing. */
int getSegmentFileCount();
/** Get the total size of segment files involved in optimizing. */
long getSegmentFileSize();
+ /** Get the total records of segment files involved in optimizing. */
+ long getSegmentFileRecords();
+
/** Get the count of equality delete files involved in optimizing. */
int getEqualityDeleteFileCount();
/** Get the total size of equality delete files involved in optimizing. */
long getEqualityDeleteFileSize();
+ /** Get the total records of equality delete files involved in optimizing. */
+ long getEqualityDeleteFileRecords();
+
/** Get the count of positional delete files involved in optimizing. */
int getPosDeleteFileCount();
/** Get the total size of positional delete files involved in optimizing. */
long getPosDeleteFileSize();
+
+ /** Get the total records of positional delete files involved in optimizing.
*/
+ long getPosDeleteFileRecords();
}
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java
index 69cb2303c..f056dcb5e 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java
@@ -329,6 +329,8 @@ public interface TableMetaMapper {
+ " table_config = #{runtime.tableConfiguration,"
+ "
typeHandler=org.apache.amoro.server.persistence.converter.JsonObjectConverter},"
+ " pending_input = #{runtime.pendingInput, jdbcType=VARCHAR,"
+ + "
typeHandler=org.apache.amoro.server.persistence.converter.JsonObjectConverter},"
+ + " table_summary = #{runtime.tableSummary, jdbcType=VARCHAR,"
+ "
typeHandler=org.apache.amoro.server.persistence.converter.JsonObjectConverter}"
+ " WHERE table_id = #{runtime.tableIdentifier.id}")
void updateTableRuntime(@Param("runtime") TableRuntime runtime);
@@ -341,7 +343,7 @@ public interface TableMetaMapper {
+ " current_change_snapshotId, last_optimized_snapshotId,
last_optimized_change_snapshotId,"
+ " last_major_optimizing_time, last_minor_optimizing_time,"
+ " last_full_optimizing_time, optimizing_status,
optimizing_status_start_time, optimizing_process_id,"
- + " optimizer_group, table_config, pending_input) VALUES"
+ + " optimizer_group, table_config, pending_input, table_summary)
VALUES"
+ " (#{runtime.tableIdentifier.id},
#{runtime.tableIdentifier.catalog},"
+ " #{runtime.tableIdentifier.database},
#{runtime.tableIdentifier.tableName}, #{runtime"
+ ".currentSnapshotId},"
@@ -359,6 +361,8 @@ public interface TableMetaMapper {
+ " #{runtime.tableConfiguration,"
+ "
typeHandler=org.apache.amoro.server.persistence.converter.JsonObjectConverter},"
+ " #{runtime.pendingInput, jdbcType=VARCHAR,"
+ + "
typeHandler=org.apache.amoro.server.persistence.converter.JsonObjectConverter},"
+ + " #{runtime.tableSummary, jdbcType=VARCHAR,"
+ "
typeHandler=org.apache.amoro.server.persistence.converter.JsonObjectConverter})")
void insertTableRuntime(@Param("runtime") TableRuntime runtime);
@@ -367,7 +371,7 @@ public interface TableMetaMapper {
+ ".current_change_snapshotId, a.last_optimized_snapshotId,
a.last_optimized_change_snapshotId,"
+ " a.last_major_optimizing_time, a.last_minor_optimizing_time,
a.last_full_optimizing_time, a.optimizing_status,"
+ " a.optimizing_status_start_time, a.optimizing_process_id,"
- + " a.optimizer_group, a.table_config, a.pending_input,
b.optimizing_type, b.target_snapshot_id,"
+ + " a.optimizer_group, a.table_config, a.pending_input,
a.table_summary, b.optimizing_type, b.target_snapshot_id,"
+ " b.target_change_snapshot_id, b.plan_time, b.from_sequence,
b.to_sequence FROM table_runtime a"
+ " INNER JOIN table_identifier i ON a.table_id = i.table_id "
+ " LEFT JOIN table_optimizing_process b ON a.optimizing_process_id
= b.process_id")
@@ -410,6 +414,10 @@ public interface TableMetaMapper {
property = "pendingInput",
column = "pending_input",
typeHandler = JsonObjectConverter.class),
+ @Result(
+ property = "tableSummary",
+ column = "table_summary",
+ typeHandler = JsonObjectConverter.class),
@Result(property = "optimizingType", column = "optimizing_type"),
@Result(property = "targetSnapshotId", column = "target_snapshot_id"),
@Result(property = "targetChangeSnapshotId", column =
"target_change_napshot_id"),
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntime.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntime.java
index dbe245f3a..9884d2e78 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntime.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntime.java
@@ -88,9 +88,11 @@ public class TableRuntime extends StatedPersistentBase {
@StateField private volatile TableConfiguration tableConfiguration;
@StateField private volatile long processId;
@StateField private volatile OptimizingEvaluator.PendingInput pendingInput;
+ @StateField private volatile OptimizingEvaluator.PendingInput tableSummary;
private volatile long lastPlanTime;
private final TableOptimizingMetrics optimizingMetrics;
private final TableOrphanFilesCleaningMetrics orphanFilesCleaningMetrics;
+ private final TableSummaryMetrics tableSummaryMetrics;
protected TableRuntime(
ServerTableIdentifier tableIdentifier,
@@ -105,6 +107,7 @@ public class TableRuntime extends StatedPersistentBase {
persistTableRuntime();
optimizingMetrics = new TableOptimizingMetrics(tableIdentifier);
orphanFilesCleaningMetrics = new
TableOrphanFilesCleaningMetrics(tableIdentifier);
+ tableSummaryMetrics = new TableSummaryMetrics(tableIdentifier);
}
protected TableRuntime(TableRuntimeMeta tableRuntimeMeta,
TableRuntimeHandler tableHandler) {
@@ -134,12 +137,15 @@ public class TableRuntime extends StatedPersistentBase {
? OptimizingStatus.PENDING
: tableRuntimeMeta.getTableStatus();
this.pendingInput = tableRuntimeMeta.getPendingInput();
+ this.tableSummary = tableRuntimeMeta.getTableSummary();
optimizingMetrics = new TableOptimizingMetrics(tableIdentifier);
optimizingMetrics.statusChanged(optimizingStatus,
this.currentStatusStartTime);
optimizingMetrics.lastOptimizingTime(OptimizingType.MINOR,
this.lastMinorOptimizingTime);
optimizingMetrics.lastOptimizingTime(OptimizingType.MAJOR,
this.lastMajorOptimizingTime);
optimizingMetrics.lastOptimizingTime(OptimizingType.FULL,
this.lastFullOptimizingTime);
orphanFilesCleaningMetrics = new
TableOrphanFilesCleaningMetrics(tableIdentifier);
+ tableSummaryMetrics = new TableSummaryMetrics(tableIdentifier);
+ tableSummaryMetrics.refresh(tableSummary);
}
public void recover(OptimizingProcess optimizingProcess) {
@@ -153,6 +159,7 @@ public class TableRuntime extends StatedPersistentBase {
public void registerMetric(MetricRegistry metricRegistry) {
this.optimizingMetrics.register(metricRegistry);
this.orphanFilesCleaningMetrics.register(metricRegistry);
+ this.tableSummaryMetrics.register(metricRegistry);
}
public void dispose() {
@@ -167,6 +174,7 @@ public class TableRuntime extends StatedPersistentBase {
});
optimizingMetrics.unregister();
orphanFilesCleaningMetrics.unregister();
+ tableSummaryMetrics.unregister();
}
public void beginPlanning() {
@@ -243,6 +251,15 @@ public class TableRuntime extends StatedPersistentBase {
});
}
+ public void setTableSummary(OptimizingEvaluator.PendingInput tableSummary) {
+ invokeConsistency(
+ () -> {
+ this.tableSummary = tableSummary;
+ tableSummaryMetrics.refresh(tableSummary);
+ persistUpdatingRuntime();
+ });
+ }
+
/**
* When there is no task to be optimized, clean pendingInput and update
`lastOptimizedSnapshotId`
* to `currentSnapshotId`.
@@ -322,7 +339,7 @@ public class TableRuntime extends StatedPersistentBase {
private boolean refreshSnapshots(AmoroTable<?> amoroTable) {
MixedTable table = (MixedTable) amoroTable.originalTable();
-
+ tableSummaryMetrics.refreshSnapshots(table);
long lastSnapshotId = currentSnapshotId;
if (table.isKeyedTable()) {
long changeSnapshotId = currentChangeSnapshotId;
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntimeMeta.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntimeMeta.java
index e34bf5363..9fd8c05ea 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntimeMeta.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableRuntimeMeta.java
@@ -45,6 +45,7 @@ public class TableRuntimeMeta {
private String optimizerGroup;
private TableConfiguration tableConfig;
private OptimizingEvaluator.PendingInput pendingInput;
+ private OptimizingEvaluator.PendingInput tableSummary;
private long optimizingProcessId = 0;
private OptimizingProcess.Status processStatus;
private OptimizingType optimizingType;
@@ -203,6 +204,18 @@ public class TableRuntimeMeta {
this.lastOptimizedSnapshotId = lastOptimizedSnapshotId;
}
+ public OptimizingEvaluator.PendingInput getTableSummary() {
+ return tableSummary;
+ }
+
+ public void setTableSummary(OptimizingEvaluator.PendingInput tableSummary) {
+ this.tableSummary = tableSummary;
+ }
+
+ public void setTableRuntime(TableRuntime tableRuntime) {
+ this.tableRuntime = tableRuntime;
+ }
+
public void setLastOptimizedChangeSnapshotId(long
lastOptimizedChangeSnapshotId) {
this.lastOptimizedChangeSnapshotId = lastOptimizedChangeSnapshotId;
}
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableSummaryMetrics.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableSummaryMetrics.java
new file mode 100644
index 000000000..cf476c10c
--- /dev/null
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/TableSummaryMetrics.java
@@ -0,0 +1,241 @@
+/*
+ * 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.amoro.server.table;
+
+import static org.apache.amoro.api.metrics.MetricDefine.defineGauge;
+
+import org.apache.amoro.api.ServerTableIdentifier;
+import org.apache.amoro.api.metrics.Gauge;
+import org.apache.amoro.api.metrics.Metric;
+import org.apache.amoro.api.metrics.MetricDefine;
+import org.apache.amoro.api.metrics.MetricKey;
+import org.apache.amoro.server.metrics.MetricRegistry;
+import org.apache.amoro.server.optimizing.plan.OptimizingEvaluator;
+import org.apache.amoro.shade.guava32.com.google.common.collect.ImmutableMap;
+import org.apache.amoro.shade.guava32.com.google.common.collect.Lists;
+import org.apache.amoro.table.MixedTable;
+import org.apache.amoro.table.UnkeyedTable;
+
+import java.util.List;
+
+/** Table Summary metrics. */
+public class TableSummaryMetrics {
+
+ // table summary files number metrics
+ public static final MetricDefine TABLE_SUMMARY_TOTAL_FILES =
+ defineGauge("table_summary_total_files")
+ .withDescription("Total number of files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_DATA_FILES =
+ defineGauge("table_summary_data_files")
+ .withDescription("Number of data files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_EQUALITY_DELETE_FILES =
+ defineGauge("table_summary_equality_delete_files")
+ .withDescription("Number of equality delete files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_POSITION_DELETE_FILES =
+ defineGauge("table_summary_position_delete_files")
+ .withDescription("Number of position delete files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ // table summary files size metrics
+ public static final MetricDefine TABLE_SUMMARY_TOTAL_FILES_SIZE =
+ defineGauge("table_summary_total_files_size")
+ .withDescription("Total size of files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_DATA_FILES_SIZE =
+ defineGauge("table_summary_data_files_size")
+ .withDescription("Size of data files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_EQUALITY_DELETE_FILES_SIZE =
+ defineGauge("table_summary_equality_delete_files_size")
+ .withDescription("Size of equality delete files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_POSITION_DELETE_FILES_SIZE =
+ defineGauge("table_summary_position_delete_files_size")
+ .withDescription("Size of position delete files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ // table summary files records metrics
+ public static final MetricDefine TABLE_SUMMARY_TOTAL_RECORDS =
+ defineGauge("table_summary_total_records")
+ .withDescription("Total records in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_DATA_FILES_RECORDS =
+ defineGauge("table_summary_data_files_records")
+ .withDescription("Records of data files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_EQUALITY_DELETE_FILES_RECORDS
=
+ defineGauge("table_summary_equality_delete_files_records")
+ .withDescription("Records of equality delete files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ public static final MetricDefine TABLE_SUMMARY_POSITION_DELETE_FILES_RECORDS
=
+ defineGauge("table_summary_position_delete_files_records")
+ .withDescription("Records of position delete files in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ // table summary snapshots number metrics
+ public static final MetricDefine TABLE_SUMMARY_SNAPSHOTS =
+ defineGauge("table_summary_snapshots")
+ .withDescription("Number of snapshots in the table")
+ .withTags("catalog", "database", "table")
+ .build();
+
+ private final ServerTableIdentifier identifier;
+ private final List<MetricKey> registeredMetricKeys = Lists.newArrayList();
+ private MetricRegistry globalRegistry;
+
+ private long totalFiles = 0L;
+ private long dataFiles = 0L;
+ private long positionDeleteFiles = 0L;
+ private long equalityDeleteFiles = 0L;
+ private long totalFilesSize = 0L;
+ private long positionDeleteFilesSize = 0L;
+ private long dataFilesSize = 0L;
+ private long equalityDeleteFilesSize = 0L;
+ private long positionDeleteFilesRecords = 0L;
+ private long totalRecords = 0L;
+ private long dataFilesRecords = 0L;
+ private long equalityDeleteFilesRecords = 0L;
+ private long snapshots = 0L;
+
+ public TableSummaryMetrics(ServerTableIdentifier identifier) {
+ this.identifier = identifier;
+ }
+
+ private void registerMetric(MetricRegistry registry, MetricDefine define,
Metric metric) {
+ MetricKey key =
+ registry.register(
+ define,
+ ImmutableMap.of(
+ "catalog",
+ identifier.getCatalog(),
+ "database",
+ identifier.getDatabase(),
+ "table",
+ identifier.getTableName()),
+ metric);
+ registeredMetricKeys.add(key);
+ }
+
+ public void register(MetricRegistry registry) {
+ if (globalRegistry == null) {
+ // register files number metrics
+ registerMetric(registry, TABLE_SUMMARY_TOTAL_FILES, (Gauge<Long>) () ->
totalFiles);
+ registerMetric(registry, TABLE_SUMMARY_DATA_FILES, (Gauge<Long>) () ->
dataFiles);
+ registerMetric(
+ registry, TABLE_SUMMARY_POSITION_DELETE_FILES, (Gauge<Long>) () ->
positionDeleteFiles);
+ registerMetric(
+ registry, TABLE_SUMMARY_EQUALITY_DELETE_FILES, (Gauge<Long>) () ->
equalityDeleteFiles);
+
+ // register files size metrics
+ registerMetric(registry, TABLE_SUMMARY_TOTAL_FILES_SIZE, (Gauge<Long>)
() -> totalFilesSize);
+ registerMetric(registry, TABLE_SUMMARY_DATA_FILES_SIZE, (Gauge<Long>) ()
-> dataFilesSize);
+ registerMetric(
+ registry,
+ TABLE_SUMMARY_POSITION_DELETE_FILES_SIZE,
+ (Gauge<Long>) () -> positionDeleteFilesSize);
+ registerMetric(
+ registry,
+ TABLE_SUMMARY_EQUALITY_DELETE_FILES_SIZE,
+ (Gauge<Long>) () -> equalityDeleteFilesSize);
+
+ // register files records metrics
+ registerMetric(registry, TABLE_SUMMARY_TOTAL_RECORDS, (Gauge<Long>) ()
-> totalRecords);
+ registerMetric(
+ registry, TABLE_SUMMARY_DATA_FILES_RECORDS, (Gauge<Long>) () ->
dataFilesRecords);
+ registerMetric(
+ registry,
+ TABLE_SUMMARY_POSITION_DELETE_FILES_RECORDS,
+ (Gauge<Long>) () -> positionDeleteFilesRecords);
+ registerMetric(
+ registry,
+ TABLE_SUMMARY_EQUALITY_DELETE_FILES_RECORDS,
+ (Gauge<Long>) () -> equalityDeleteFilesRecords);
+
+ // register snapshots number metrics
+ registerMetric(registry, TABLE_SUMMARY_SNAPSHOTS, (Gauge<Long>) () ->
snapshots);
+
+ globalRegistry = registry;
+ }
+ }
+
+ public void unregister() {
+ registeredMetricKeys.forEach(globalRegistry::unregister);
+ registeredMetricKeys.clear();
+ globalRegistry = null;
+ }
+
+ public void refresh(OptimizingEvaluator.PendingInput tableSummary) {
+ if (tableSummary == null) {
+ return;
+ }
+ totalFiles =
+ tableSummary.getDataFileCount()
+ + tableSummary.getEqualityDeleteFileCount()
+ + tableSummary.getPositionalDeleteFileCount();
+ dataFiles = tableSummary.getDataFileCount();
+ positionDeleteFiles = tableSummary.getPositionalDeleteFileCount();
+ equalityDeleteFiles = tableSummary.getEqualityDeleteFileCount();
+
+ totalFilesSize =
+ tableSummary.getDataFileSize()
+ + tableSummary.getEqualityDeleteBytes()
+ + tableSummary.getPositionalDeleteBytes();
+ positionDeleteFilesSize = tableSummary.getPositionalDeleteBytes();
+ dataFilesSize = tableSummary.getDataFileSize();
+ equalityDeleteFilesSize = tableSummary.getEqualityDeleteBytes();
+
+ totalRecords =
+ tableSummary.getDataFileRecords()
+ + tableSummary.getEqualityDeleteFileRecords()
+ + tableSummary.getPositionalDeleteFileRecords();
+ positionDeleteFilesRecords = tableSummary.getPositionalDeleteFileRecords();
+ dataFilesRecords = tableSummary.getDataFileRecords();
+ equalityDeleteFilesRecords = tableSummary.getEqualityDeleteFileRecords();
+ }
+
+ public void refreshSnapshots(MixedTable table) {
+ UnkeyedTable unkeyedTable =
+ table.isKeyedTable() ? table.asKeyedTable().baseTable() :
table.asUnkeyedTable();
+ snapshots = Lists.newArrayList(unkeyedTable.snapshots().iterator()).size();
+ }
+}
diff --git
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/executor/TableRuntimeRefreshExecutor.java
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/executor/TableRuntimeRefreshExecutor.java
index e36c7413e..4fa3598a8 100644
---
a/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/executor/TableRuntimeRefreshExecutor.java
+++
b/amoro-ams/amoro-ams-server/src/main/java/org/apache/amoro/server/table/executor/TableRuntimeRefreshExecutor.java
@@ -50,7 +50,7 @@ public class TableRuntimeRefreshExecutor extends
BaseTableExecutor {
if (tableRuntime.isOptimizingEnabled() &&
!tableRuntime.getOptimizingStatus().isProcessing()) {
OptimizingEvaluator evaluator = new OptimizingEvaluator(tableRuntime,
table);
if (evaluator.isNecessary()) {
- OptimizingEvaluator.PendingInput pendingInput =
evaluator.getPendingInput();
+ OptimizingEvaluator.PendingInput pendingInput =
evaluator.getOptimizingPendingInput();
logger.debug(
"{} optimizing is necessary and get pending input {}",
tableRuntime.getTableIdentifier(),
@@ -59,6 +59,7 @@ public class TableRuntimeRefreshExecutor extends
BaseTableExecutor {
} else {
tableRuntime.optimizingNotNecessary();
}
+ tableRuntime.setTableSummary(evaluator.getPendingInput());
}
}
diff --git
a/amoro-ams/amoro-ams-server/src/main/resources/derby/ams-derby-init.sql
b/amoro-ams/amoro-ams-server/src/main/resources/derby/ams-derby-init.sql
index a7dc2ecf1..f41cdaf27 100644
--- a/amoro-ams/amoro-ams-server/src/main/resources/derby/ams-derby-init.sql
+++ b/amoro-ams/amoro-ams-server/src/main/resources/derby/ams-derby-init.sql
@@ -118,6 +118,7 @@ CREATE TABLE table_runtime (
table_config CLOB(64m),
optimizing_config CLOB(64m),
pending_input CLOB(64m),
+ table_summary CLOB(64m),
CONSTRAINT table_runtime_pk PRIMARY KEY (table_id),
CONSTRAINT table_runtime_table_name_idx UNIQUE (catalog_name, db_name,
table_name)
);
diff --git
a/amoro-ams/amoro-ams-server/src/main/resources/mysql/ams-mysql-init.sql
b/amoro-ams/amoro-ams-server/src/main/resources/mysql/ams-mysql-init.sql
index 45bc86092..76e16147a 100644
--- a/amoro-ams/amoro-ams-server/src/main/resources/mysql/ams-mysql-init.sql
+++ b/amoro-ams/amoro-ams-server/src/main/resources/mysql/ams-mysql-init.sql
@@ -129,6 +129,7 @@ CREATE TABLE `table_runtime`
`table_config` mediumtext,
`optimizing_config` mediumtext,
`pending_input` mediumtext,
+ `table_summary` mediumtext,
PRIMARY KEY (`table_id`),
UNIQUE KEY `table_index` (`catalog_name`,`db_name`,`table_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT 'Optimize running information
of each table' ROW_FORMAT=DYNAMIC;
diff --git a/amoro-ams/amoro-ams-server/src/main/resources/mysql/upgrade.sql
b/amoro-ams/amoro-ams-server/src/main/resources/mysql/upgrade.sql
index a457d458d..31ab7604d 100644
--- a/amoro-ams/amoro-ams-server/src/main/resources/mysql/upgrade.sql
+++ b/amoro-ams/amoro-ams-server/src/main/resources/mysql/upgrade.sql
@@ -21,3 +21,6 @@ TRUNCATE TABLE `table_blocker`;
ALTER TABLE `table_blocker` DROP INDEX `table_index`;
ALTER TABLE `table_blocker` ADD COLUMN `prev_blocker_id` bigint(20) NOT NULL
DEFAULT -1 COMMENT 'prev blocker id when created';
ALTER TABLE `table_blocker` ADD UNIQUE KEY `uq_prev`
(`catalog_name`,`db_name`,`table_name`, `prev_blocker_id`);
+
+-- ADD COLUMN table_summary FOR TABLE_RUNTIME
+ALTER TABLE `table_runtime` ADD COLUMN `table_summary` mediumtext AFTER
`pending_input`;
\ No newline at end of file
diff --git
a/amoro-ams/amoro-ams-server/src/main/resources/postgres/ams-postgres-init.sql
b/amoro-ams/amoro-ams-server/src/main/resources/postgres/ams-postgres-init.sql
index 40688a5ed..83c3f6d0f 100644
---
a/amoro-ams/amoro-ams-server/src/main/resources/postgres/ams-postgres-init.sql
+++
b/amoro-ams/amoro-ams-server/src/main/resources/postgres/ams-postgres-init.sql
@@ -189,6 +189,7 @@ CREATE TABLE table_runtime
table_config TEXT,
optimizing_config TEXT,
pending_input TEXT,
+ table_summary TEXT,
PRIMARY KEY (table_id),
UNIQUE (catalog_name, db_name, table_name)
);
@@ -211,6 +212,7 @@ COMMENT ON COLUMN table_runtime.optimizer_group IS
'Optimizer group';
COMMENT ON COLUMN table_runtime.table_config IS 'Table-specific configuration';
COMMENT ON COLUMN table_runtime.optimizing_config IS 'Optimizing
configuration';
COMMENT ON COLUMN table_runtime.pending_input IS 'Pending input data';
+COMMENT ON COLUMN table_runtime.table_summary IS 'Table summary data';
CREATE TABLE table_optimizing_process
(
diff --git a/amoro-ams/amoro-ams-server/src/main/resources/postgres/upgrade.sql
b/amoro-ams/amoro-ams-server/src/main/resources/postgres/upgrade.sql
index 0b07e8805..0267468c2 100644
--- a/amoro-ams/amoro-ams-server/src/main/resources/postgres/upgrade.sql
+++ b/amoro-ams/amoro-ams-server/src/main/resources/postgres/upgrade.sql
@@ -22,3 +22,7 @@ ALTER TABLE `table_blocker` DROP INDEX `table_index`;
ALTER TABLE `table_blocker` ADD COLUMN `prev_blocker_id` bigint(20) NOT NULL
DEFAULT -1;
COMMENT ON COLUMN table_blocker.prev_blocker_id IS 'prev blocker id when
created';
ALTER TABLE `table_blocker` ADD UNIQUE KEY `uq_prev`
(`catalog_name`,`db_name`,`table_name`, `prev_blocker_id`);
+
+-- ADD COLUMN table_summary FOR TABLE_RUNTIME
+ALTER TABLE table_runtime ADD COLUMN table_summary TEXT;
+COMMENT ON COLUMN table_runtime.table_summary IS 'Table summary data';
diff --git
a/amoro-ams/amoro-ams-server/src/test/java/org/apache/amoro/server/optimizing/plan/TestOptimizingEvaluator.java
b/amoro-ams/amoro-ams-server/src/test/java/org/apache/amoro/server/optimizing/plan/TestOptimizingEvaluator.java
index 07c77179b..63a853fe1 100644
---
a/amoro-ams/amoro-ams-server/src/test/java/org/apache/amoro/server/optimizing/plan/TestOptimizingEvaluator.java
+++
b/amoro-ams/amoro-ams-server/src/test/java/org/apache/amoro/server/optimizing/plan/TestOptimizingEvaluator.java
@@ -71,7 +71,7 @@ public class TestOptimizingEvaluator extends
MixedTablePlanTestBase {
public void testEmpty() {
OptimizingEvaluator optimizingEvaluator = buildOptimizingEvaluator();
Assert.assertFalse(optimizingEvaluator.isNecessary());
- OptimizingEvaluator.PendingInput pendingInput =
optimizingEvaluator.getPendingInput();
+ OptimizingEvaluator.PendingInput pendingInput =
optimizingEvaluator.getOptimizingPendingInput();
assertEmptyInput(pendingInput);
}
@@ -90,7 +90,7 @@ public class TestOptimizingEvaluator extends
MixedTablePlanTestBase {
OptimizingEvaluator optimizingEvaluator = buildOptimizingEvaluator();
Assert.assertFalse(optimizingEvaluator.isNecessary());
- OptimizingEvaluator.PendingInput pendingInput =
optimizingEvaluator.getPendingInput();
+ OptimizingEvaluator.PendingInput pendingInput =
optimizingEvaluator.getOptimizingPendingInput();
assertEmptyInput(pendingInput);
// add more files
@@ -104,7 +104,7 @@ public class TestOptimizingEvaluator extends
MixedTablePlanTestBase {
optimizingEvaluator = buildOptimizingEvaluator();
Assert.assertTrue(optimizingEvaluator.isNecessary());
- pendingInput = optimizingEvaluator.getPendingInput();
+ pendingInput = optimizingEvaluator.getOptimizingPendingInput();
assertInput(pendingInput, FileInfo.buildFileInfo(dataFiles));
}
diff --git
a/amoro-ams/amoro-ams-server/src/test/java/org/apache/amoro/server/table/TestTableSummaryMetrics.java
b/amoro-ams/amoro-ams-server/src/test/java/org/apache/amoro/server/table/TestTableSummaryMetrics.java
new file mode 100644
index 000000000..f3b4f20dc
--- /dev/null
+++
b/amoro-ams/amoro-ams-server/src/test/java/org/apache/amoro/server/table/TestTableSummaryMetrics.java
@@ -0,0 +1,223 @@
+/*
+ * 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.amoro.server.table;
+
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_DATA_FILES;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_DATA_FILES_RECORDS;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_DATA_FILES_SIZE;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_EQUALITY_DELETE_FILES;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_EQUALITY_DELETE_FILES_RECORDS;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_EQUALITY_DELETE_FILES_SIZE;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_POSITION_DELETE_FILES;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_POSITION_DELETE_FILES_RECORDS;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_POSITION_DELETE_FILES_SIZE;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_SNAPSHOTS;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_TOTAL_FILES;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_TOTAL_FILES_SIZE;
+import static
org.apache.amoro.server.table.TableSummaryMetrics.TABLE_SUMMARY_TOTAL_RECORDS;
+
+import org.apache.amoro.BasicTableTestHelper;
+import org.apache.amoro.TableFormat;
+import org.apache.amoro.TableTestHelper;
+import org.apache.amoro.api.ServerTableIdentifier;
+import org.apache.amoro.api.metrics.Gauge;
+import org.apache.amoro.api.metrics.Metric;
+import org.apache.amoro.api.metrics.MetricDefine;
+import org.apache.amoro.api.metrics.MetricKey;
+import org.apache.amoro.catalog.BasicCatalogTestHelper;
+import org.apache.amoro.catalog.CatalogTestHelper;
+import org.apache.amoro.io.MixedDataTestHelpers;
+import org.apache.amoro.server.manager.MetricManager;
+import org.apache.amoro.server.optimizing.OptimizingTestHelpers;
+import org.apache.amoro.server.table.executor.TableRuntimeRefreshExecutor;
+import org.apache.amoro.shade.guava32.com.google.common.collect.ImmutableMap;
+import org.apache.amoro.shade.guava32.com.google.common.collect.Lists;
+import org.apache.amoro.table.MixedTable;
+import org.apache.amoro.table.UnkeyedTable;
+import org.apache.iceberg.AppendFiles;
+import org.apache.iceberg.DataFile;
+import org.apache.iceberg.DeleteFile;
+import org.apache.iceberg.data.Record;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(Parameterized.class)
+public class TestTableSummaryMetrics extends AMSTableTestBase {
+
+ @Parameterized.Parameters(name = "{0}, {1}")
+ public static Object[] parameters() {
+ return new Object[][] {
+ {new BasicCatalogTestHelper(TableFormat.ICEBERG), new
BasicTableTestHelper(true, false)}
+ };
+ }
+
+ public TestTableSummaryMetrics(
+ CatalogTestHelper catalogTestHelper, TableTestHelper tableTestHelper) {
+ super(catalogTestHelper, tableTestHelper, false);
+ }
+
+ @Before
+ public void prepare() {
+ createDatabase();
+ createTable();
+ }
+
+ @After
+ public void clear() {
+ try {
+ dropTable();
+ dropDatabase();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ private void initTableWithFiles() {
+ UnkeyedTable table =
+ ((MixedTable)
tableService().loadTable(serverTableIdentifier()).originalTable())
+ .asUnkeyedTable();
+ appendData(table);
+ appendPosDelete(table);
+ TableRuntime runtime = tableService().getRuntime(serverTableIdentifier());
+ runtime.refresh(tableService().loadTable(serverTableIdentifier()));
+ }
+
+ private void appendData(UnkeyedTable table) {
+ ArrayList<Record> newRc =
+ Lists.newArrayList(
+ tableTestHelper().generateTestRecord(1, "111", 0,
"2022-01-01T12:00:00"),
+ tableTestHelper().generateTestRecord(2, "222", 0,
"2022-01-01T12:00:00"));
+ List<DataFile> dataFiles =
+ OptimizingTestHelpers.appendBase(
+ table, tableTestHelper().writeBaseStore(table, 0L, newRc, false));
+
+ AppendFiles appendFiles = table.newAppend();
+ dataFiles.forEach(appendFiles::appendFile);
+ appendFiles.commit();
+ }
+
+ private void appendPosDelete(UnkeyedTable table) {
+ ArrayList<Record> newRc =
+ Lists.newArrayList(
+ tableTestHelper().generateTestRecord(3, "333", 0,
"2022-01-01T12:00:00"),
+ tableTestHelper().generateTestRecord(4, "444", 0,
"2022-01-01T12:00:00"));
+ List<DataFile> dataFiles =
+ OptimizingTestHelpers.appendBase(
+ table, tableTestHelper().writeBaseStore(table, 0L, newRc, false));
+ List<DeleteFile> posDeleteFiles = Lists.newArrayList();
+ for (DataFile dataFile : dataFiles) {
+ posDeleteFiles.addAll(
+ MixedDataTestHelpers.writeBaseStorePosDelete(
+ table, 0L, dataFile, Collections.singletonList(0L)));
+ }
+ OptimizingTestHelpers.appendBasePosDelete(table, posDeleteFiles);
+ }
+
+ void refreshPending() {
+ TableRuntimeRefreshExecutor refresher =
+ new TableRuntimeRefreshExecutor(tableService(), 1, Integer.MAX_VALUE);
+ refresher.execute(tableService().getRuntime(serverTableIdentifier()));
+ refresher.dispose();
+ }
+
+ @Test
+ public void testTableSummaryMetrics() {
+ ServerTableIdentifier identifier = serverTableIdentifier();
+ Map<MetricKey, Metric> metrics =
MetricManager.getInstance().getGlobalRegistry().getMetrics();
+ Gauge<Long> totalFiles = getMetric(metrics, identifier,
TABLE_SUMMARY_TOTAL_FILES);
+ Gauge<Long> dataFiles = getMetric(metrics, identifier,
TABLE_SUMMARY_DATA_FILES);
+ Gauge<Long> posDelFiles = getMetric(metrics, identifier,
TABLE_SUMMARY_POSITION_DELETE_FILES);
+ Gauge<Long> eqDelFiles = getMetric(metrics, identifier,
TABLE_SUMMARY_EQUALITY_DELETE_FILES);
+
+ Gauge<Long> totalSize = getMetric(metrics, identifier,
TABLE_SUMMARY_TOTAL_FILES_SIZE);
+ Gauge<Long> dataSize = getMetric(metrics, identifier,
TABLE_SUMMARY_DATA_FILES_SIZE);
+ Gauge<Long> posDelSize =
+ getMetric(metrics, identifier,
TABLE_SUMMARY_POSITION_DELETE_FILES_SIZE);
+ Gauge<Long> eqDelSize =
+ getMetric(metrics, identifier,
TABLE_SUMMARY_EQUALITY_DELETE_FILES_SIZE);
+
+ Gauge<Long> totalRecords = getMetric(metrics, identifier,
TABLE_SUMMARY_TOTAL_RECORDS);
+ Gauge<Long> dataRecords = getMetric(metrics, identifier,
TABLE_SUMMARY_DATA_FILES_RECORDS);
+ Gauge<Long> posDelRecords =
+ getMetric(metrics, identifier,
TABLE_SUMMARY_POSITION_DELETE_FILES_RECORDS);
+ Gauge<Long> eqDelRecords =
+ getMetric(metrics, identifier,
TABLE_SUMMARY_EQUALITY_DELETE_FILES_RECORDS);
+
+ Gauge<Long> snapshots = getMetric(metrics, identifier,
TABLE_SUMMARY_SNAPSHOTS);
+
+ Assertions.assertEquals(0, totalFiles.getValue());
+ Assertions.assertEquals(0, dataFiles.getValue());
+ Assertions.assertEquals(0, posDelFiles.getValue());
+ Assertions.assertEquals(0, eqDelFiles.getValue());
+
+ Assertions.assertEquals(0, totalSize.getValue());
+ Assertions.assertEquals(0, dataSize.getValue());
+ Assertions.assertEquals(0, posDelSize.getValue());
+ Assertions.assertEquals(0, eqDelSize.getValue());
+
+ Assertions.assertEquals(0, totalRecords.getValue());
+ Assertions.assertEquals(0, dataRecords.getValue());
+ Assertions.assertEquals(0, posDelRecords.getValue());
+ Assertions.assertEquals(0, eqDelRecords.getValue());
+
+ // refresh metrics
+ initTableWithFiles();
+ refreshPending();
+
+ Assertions.assertTrue(totalFiles.getValue() > 0);
+ Assertions.assertTrue(dataFiles.getValue() > 0);
+ Assertions.assertTrue(posDelFiles.getValue() > 0);
+
+ Assertions.assertTrue(totalSize.getValue() > 0);
+ Assertions.assertTrue(dataSize.getValue() > 0);
+ Assertions.assertTrue(posDelSize.getValue() > 0);
+
+ Assertions.assertTrue(totalRecords.getValue() > 0);
+ Assertions.assertTrue(dataRecords.getValue() > 0);
+ Assertions.assertTrue(posDelRecords.getValue() > 0);
+
+ Assertions.assertTrue(snapshots.getValue() > 0);
+ }
+
+ private Gauge<Long> getMetric(
+ Map<MetricKey, Metric> metrics, ServerTableIdentifier identifier,
MetricDefine metricDefine) {
+ Gauge<Long> metric =
+ (Gauge<Long>)
+ metrics.get(
+ new MetricKey(
+ metricDefine,
+ ImmutableMap.of(
+ "catalog",
+ identifier.getCatalog(),
+ "database",
+ identifier.getDatabase(),
+ "table",
+ identifier.getTableName())));
+ return metric;
+ }
+}
diff --git a/docs/user-guides/metrics.md b/docs/user-guides/metrics.md
index c84d565d8..cc86bcb0d 100644
--- a/docs/user-guides/metrics.md
+++ b/docs/user-guides/metrics.md
@@ -78,11 +78,11 @@ Amoro has supported built-in metrics to measure status of
table self-optimizing
## Orphan Files Cleaning metrics
-| Metric Name | Type | Tags
| Description
|
-|-------------------------------------------|---------|--------------------------|--------------------------------------------------------------------------------|
-| table_orphan_content_file_cleaning_count | Counter | catalog, database,
table | Count of orphan content files cleaned in the table since ams started
|
-| table_orphan_metadata_file_cleaning_count | Counter | catalog, database,
table | Count of orphan metadata files cleaned in the table since ams started
|
-| table_expected_orphan_content_file_cleaning_count | Counter | catalog,
database, table | Expected Count of orphan content files cleaned in the table
since ams started |
+| Metric Name | Type | Tags
| Description
|
+|----------------------------------------------------|---------|--------------------------|--------------------------------------------------------------------------------|
+| table_orphan_content_file_cleaning_count | Counter | catalog,
database, table | Count of orphan content files cleaned in the table since ams
started |
+| table_orphan_metadata_file_cleaning_count | Counter | catalog,
database, table | Count of orphan metadata files cleaned in the table since ams
started |
+| table_expected_orphan_content_file_cleaning_count | Counter | catalog,
database, table | Expected Count of orphan content files cleaned in the table
since ams started |
| table_expected_orphan_metadata_file_cleaning_count | Counter | catalog,
database, table | Expected Count of orphan metadata files cleaned in the table
since ams started |
@@ -97,3 +97,21 @@ Amoro has supported built-in metrics to measure status of
table self-optimizing
| ams_jvm_threads_count | Gauge |
| The total number of live threads used by the AMS |
| ams_jvm_garbage_collector_count | Gauge
|garbage_collector| The count of the JVM's Garbage Collector, such as G1 Young
|
| ams_jvm_garbage_collector_time | Gauge
|garbage_collector| The time spent by the JVM's Garbage Collector, such as G1
Young |
+
+## table summary metrics
+
+| Metric Name | Type | Tags
| Description |
+|---------------------------------------------|---------|--------------------------|-----------------------------------------------|
+| table_summary_total_files | Gauge | catalog, database,
table | Total number of files in the table |
+| table_summary_data_files | Gauge | catalog, database,
table | Number of data files in the table |
+| table_summary_equality_delete_files | Gauge | catalog, database,
table | Number of equality delete files in the table |
+| table_summary_position_delete_files | Gauge | catalog, database,
table | Number of position delete files in the table |
+| table_summary_total_files_size | Gauge | catalog, database,
table | Total size of files in the table |
+| table_summary_data_files_size | Gauge | catalog, database,
table | Size of data files in the table |
+| table_summary_equality_delete_files_size | Gauge | catalog, database,
table | Size of equality delete files in the table |
+| table_summary_position_delete_files_size | Gauge | catalog, database,
table | Size of position delete files in the table |
+| table_summary_total_records | Gauge | catalog, database,
table | Total records in the table |
+| table_summary_data_files_records | Gauge | catalog, database,
table | Records of data files in the table |
+| table_summary_equality_delete_files_records | Gauge | catalog, database,
table | Records of equality delete files in the table |
+| table_summary_position_delete_files_records | Gauge | catalog, database,
table | Records of position delete files in the table |
+| table_summary_snapshots | Gauge | catalog, database,
table | Number of snapshots in the table |
\ No newline at end of file