Skip to content

Commit f00d8fd

Browse files
committed
feat: support scan metrics of FileStoreScan to align with ScanMetrics
1 parent 11973b2 commit f00d8fd

5 files changed

Lines changed: 101 additions & 17 deletions

File tree

src/paimon/core/operation/file_store_commit_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ Status FileStoreCommitImpl::Commit(const std::shared_ptr<ManifestCommittable>& c
404404
}
405405
}
406406
metrics_->SetCounter(CommitMetrics::LAST_COMMIT_DURATION,
407-
std::chrono::duration_cast<std::chrono::nanoseconds>(
407+
std::chrono::duration_cast<std::chrono::milliseconds>(
408408
std::chrono::high_resolution_clock::now() - started)
409409
.count());
410410
metrics_->SetCounter(CommitMetrics::LAST_COMMIT_ATTEMPTS, attempt);

src/paimon/core/operation/file_store_scan.cpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <cstddef>
2020
#include <future>
2121
#include <list>
22+
#include <numeric>
2223
#include <unordered_map>
2324
#include <unordered_set>
2425

@@ -35,6 +36,7 @@
3536
#include "paimon/core/manifest/manifest_file.h"
3637
#include "paimon/core/manifest/manifest_file_meta.h"
3738
#include "paimon/core/manifest/manifest_list.h"
39+
#include "paimon/core/operation/metrics/scan_metrics.h"
3840
#include "paimon/core/partition/partition_info.h"
3941
#include "paimon/core/stats/simple_stats.h"
4042
#include "paimon/core/utils/field_mapping.h"
@@ -72,10 +74,12 @@ FileStoreScan::RawPlan::GroupFiles FileStoreScan::RawPlan::GroupByPartFiles(
7274

7375
Result<std::vector<PartitionEntry>> FileStoreScan::ReadPartitionEntries() const {
7476
std::optional<Snapshot> snapshot;
75-
std::vector<ManifestFileMeta> manifest_file_metas;
76-
PAIMON_RETURN_NOT_OK(ReadManifests(&snapshot, &manifest_file_metas));
77+
std::vector<ManifestFileMeta> all_manifest_file_metas;
78+
std::vector<ManifestFileMeta> filtered_manifest_file_metas;
79+
PAIMON_RETURN_NOT_OK(
80+
ReadManifests(&snapshot, &all_manifest_file_metas, &filtered_manifest_file_metas));
7781
std::vector<ManifestEntry> manifest_entries;
78-
PAIMON_RETURN_NOT_OK(ReadFileEntries(manifest_file_metas, &manifest_entries));
82+
PAIMON_RETURN_NOT_OK(ReadFileEntries(filtered_manifest_file_metas, &manifest_entries));
7983
std::unordered_map<BinaryRow, PartitionEntry> partitions;
8084
PAIMON_RETURN_NOT_OK(PartitionEntry::Merge(manifest_entries, &partitions));
8185

@@ -90,13 +94,16 @@ Result<std::vector<PartitionEntry>> FileStoreScan::ReadPartitionEntries() const
9094
}
9195

9296
Result<std::shared_ptr<FileStoreScan::RawPlan>> FileStoreScan::CreatePlan() const {
97+
const auto started = std::chrono::high_resolution_clock::now();
9398
std::optional<Snapshot> snapshot;
94-
std::vector<ManifestFileMeta> manifest_file_metas;
95-
PAIMON_RETURN_NOT_OK(ReadManifests(&snapshot, &manifest_file_metas));
96-
manifest_file_metas = PostFilterManifests(std::move(manifest_file_metas));
99+
std::vector<ManifestFileMeta> all_manifest_file_metas;
100+
std::vector<ManifestFileMeta> filtered_manifest_file_metas;
101+
PAIMON_RETURN_NOT_OK(
102+
ReadManifests(&snapshot, &all_manifest_file_metas, &filtered_manifest_file_metas));
103+
filtered_manifest_file_metas = PostFilterManifests(std::move(filtered_manifest_file_metas));
97104

98105
std::vector<ManifestEntry> manifest_entries;
99-
PAIMON_RETURN_NOT_OK(ReadManifestEntries(manifest_file_metas, &manifest_entries));
106+
PAIMON_RETURN_NOT_OK(ReadManifestEntries(filtered_manifest_file_metas, &manifest_entries));
100107
PAIMON_ASSIGN_OR_RAISE(manifest_entries,
101108
PostFilterManifestEntries(std::move(manifest_entries)));
102109

@@ -121,29 +128,46 @@ Result<std::shared_ptr<FileStoreScan::RawPlan>> FileStoreScan::CreatePlan() cons
121128
}
122129
}
123130
}
131+
const int64_t all_data_files = std::accumulate(
132+
all_manifest_file_metas.begin(), all_manifest_file_metas.end(), int64_t{0},
133+
[](const int64_t sum, const ManifestFileMeta& manifest_file_meta) {
134+
return sum + manifest_file_meta.NumAddedFiles() - manifest_file_meta.NumDeletedFiles();
135+
});
136+
metrics_->SetCounter(ScanMetrics::LAST_SCAN_DURATION,
137+
std::chrono::duration_cast<std::chrono::milliseconds>(
138+
std::chrono::high_resolution_clock::now() - started)
139+
.count());
140+
metrics_->SetCounter(ScanMetrics::LAST_SCANNED_SNAPSHOT_ID,
141+
snapshot.has_value() ? snapshot.value().Id() : int64_t{0});
142+
metrics_->SetCounter(ScanMetrics::LAST_SCANNED_MANIFESTS, filtered_manifest_file_metas.size());
143+
metrics_->SetCounter(ScanMetrics::LAST_SCAN_SKIPPED_TABLE_FILES,
144+
all_data_files - manifest_entries.size());
145+
metrics_->SetCounter(ScanMetrics::LAST_SCAN_RESULTED_TABLE_FILES, manifest_entries.size());
124146
return std::make_shared<FileStoreScan::RawPlan>(scan_mode_, snapshot,
125147
std::move(manifest_entries));
126148
}
127149

128150
Status FileStoreScan::ReadManifests(std::optional<Snapshot>* snapshot_ptr,
129-
std::vector<ManifestFileMeta>* manifests_ptr) const {
151+
std::vector<ManifestFileMeta>* all_manifests_ptr,
152+
std::vector<ManifestFileMeta>* filter_manifests_ptr) const {
130153
auto& snapshot = *snapshot_ptr;
131-
auto& manifests = *manifests_ptr;
154+
auto& all_manifests = *all_manifests_ptr;
155+
auto& filtered_manifests = *filter_manifests_ptr;
132156
if (specified_snapshot_ != std::nullopt) {
133157
snapshot = specified_snapshot_;
134158
} else {
135159
PAIMON_ASSIGN_OR_RAISE(snapshot, snapshot_manager_->LatestSnapshot());
136160
}
137161
if (snapshot == std::nullopt) {
138-
manifests = std::vector<ManifestFileMeta>();
162+
all_manifests = std::vector<ManifestFileMeta>();
163+
filtered_manifests = std::vector<ManifestFileMeta>();
139164
return Status::OK();
140165
}
141-
std::vector<ManifestFileMeta> unfiltered_manifest_metas;
142-
PAIMON_RETURN_NOT_OK(ReadManifestsWithSnapshot(snapshot.value(), &unfiltered_manifest_metas));
143-
for (const auto& meta : unfiltered_manifest_metas) {
166+
PAIMON_RETURN_NOT_OK(ReadManifestsWithSnapshot(snapshot.value(), &all_manifests));
167+
for (const auto& meta : all_manifests) {
144168
PAIMON_ASSIGN_OR_RAISE(bool filter_meta_result, FilterManifestFileMeta(meta));
145169
if (filter_meta_result) {
146-
manifests.push_back(meta);
170+
filtered_manifests.push_back(meta);
147171
}
148172
}
149173
return Status::OK();

src/paimon/core/operation/file_store_scan.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <vector>
2929

3030
#include "paimon/common/data/binary_row.h"
31+
#include "paimon/common/metrics/metrics_impl.h"
3132
#include "paimon/common/predicate/compound_predicate_impl.h"
3233
#include "paimon/common/predicate/leaf_predicate_impl.h"
3334
#include "paimon/common/predicate/literal_converter.h"
@@ -86,7 +87,8 @@ class FileStoreScan {
8687
snapshot_manager_(snapshot_manager),
8788
manifest_list_(manifest_list),
8889
manifest_file_(manifest_file),
89-
executor_(executor) {
90+
executor_(executor),
91+
metrics_(std::make_shared<MetricsImpl>()) {
9092
assert(executor_);
9193
}
9294

@@ -135,6 +137,10 @@ class FileStoreScan {
135137
return partition_filter_;
136138
}
137139

140+
std::shared_ptr<Metrics> GetScanMetrics() const {
141+
return metrics_;
142+
}
143+
138144
static Result<std::shared_ptr<PredicateFilter>> CreatePartitionPredicate(
139145
const std::vector<std::string>& partition_keys, const std::string& partition_default_name,
140146
const std::shared_ptr<arrow::Schema>& arrow_schema,
@@ -210,7 +216,8 @@ class FileStoreScan {
210216

211217
private:
212218
Status ReadManifests(std::optional<Snapshot>* snapshot_ptr,
213-
std::vector<ManifestFileMeta>* manifests_ptr) const;
219+
std::vector<ManifestFileMeta>* all_manifests_ptr,
220+
std::vector<ManifestFileMeta>* filtered_manifests_ptr) const;
214221

215222
Status ReadManifestsWithSnapshot(const Snapshot& snapshot,
216223
std::vector<ManifestFileMeta>* manifests) const;
@@ -255,5 +262,6 @@ class FileStoreScan {
255262
std::optional<int32_t> bucket_filter_;
256263
std::function<bool(int32_t)> level_filter_;
257264
std::optional<Snapshot> specified_snapshot_;
265+
std::shared_ptr<Metrics> metrics_;
258266
};
259267
} // namespace paimon

src/paimon/core/operation/key_value_file_store_scan_test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "paimon/core/manifest/file_source.h"
3232
#include "paimon/core/manifest/manifest_file.h"
3333
#include "paimon/core/manifest/manifest_list.h"
34+
#include "paimon/core/operation/metrics/scan_metrics.h"
3435
#include "paimon/core/schema/schema_manager.h"
3536
#include "paimon/core/schema/table_schema.h"
3637
#include "paimon/core/snapshot.h"
@@ -143,7 +144,27 @@ TEST_F(KeyValueFileStoreScanTest, TestMaxSequenceNumber) {
143144
CreateFileStoreScan(table_path, scan_filter,
144145
/*table_schema_id=*/0, /*snapshot_id=*/2));
145146

147+
const auto started = std::chrono::high_resolution_clock::now();
146148
ASSERT_OK_AND_ASSIGN(std::shared_ptr<FileStoreScan::RawPlan> raw_plan, scan->CreatePlan());
149+
std::shared_ptr<Metrics> metrics = scan->GetScanMetrics();
150+
ASSERT_TRUE(metrics);
151+
ASSERT_OK_AND_ASSIGN(uint64_t last_scan_duration,
152+
metrics->GetCounter(ScanMetrics::LAST_SCAN_DURATION));
153+
ASSERT_LE(last_scan_duration, std::chrono::duration_cast<std::chrono::milliseconds>(
154+
std::chrono::high_resolution_clock::now() - started)
155+
.count());
156+
ASSERT_OK_AND_ASSIGN(uint64_t last_scanned_snapshot_id,
157+
metrics->GetCounter(ScanMetrics::LAST_SCANNED_SNAPSHOT_ID));
158+
ASSERT_EQ(last_scanned_snapshot_id, 2u);
159+
ASSERT_OK_AND_ASSIGN(uint64_t last_scanned_manifests,
160+
metrics->GetCounter(ScanMetrics::LAST_SCANNED_MANIFESTS));
161+
ASSERT_EQ(last_scanned_manifests, 2u);
162+
ASSERT_OK_AND_ASSIGN(uint64_t last_scan_skipped_table_files,
163+
metrics->GetCounter(ScanMetrics::LAST_SCAN_SKIPPED_TABLE_FILES));
164+
ASSERT_EQ(last_scan_skipped_table_files, 1u);
165+
ASSERT_OK_AND_ASSIGN(uint64_t last_scan_resulted_table_files,
166+
metrics->GetCounter(ScanMetrics::LAST_SCAN_RESULTED_TABLE_FILES));
167+
ASSERT_EQ(last_scan_resulted_table_files, 1u);
147168
int64_t max_sequence_num = GetMaxSequenceNumberOfRawPlan(raw_plan);
148169
ASSERT_EQ(max_sequence_num, 1);
149170
// test multiple scan
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2026-present Alibaba Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
namespace paimon {
20+
21+
/// Metrics to measure scan operation.
22+
class ScanMetrics {
23+
public:
24+
static constexpr char LAST_SCAN_DURATION[] = "lastScanDuration";
25+
static constexpr char LAST_SCANNED_SNAPSHOT_ID[] = "lastScannedSnapshotId";
26+
static constexpr char LAST_SCANNED_MANIFESTS[] = "lastScannedManifests";
27+
static constexpr char LAST_SCAN_SKIPPED_TABLE_FILES[] = "lastScanSkippedTableFiles";
28+
static constexpr char LAST_SCAN_RESULTED_TABLE_FILES[] = "lastScanResultedTableFiles";
29+
};
30+
31+
} // namespace paimon

0 commit comments

Comments
 (0)