Skip to content

Commit e531ad0

Browse files
support clean metrics of OrphanFilesCleaner
1 parent 60448b8 commit e531ad0

7 files changed

Lines changed: 120 additions & 12 deletions

File tree

include/paimon/orphan_files_cleaner.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ class PAIMON_EXPORT OrphanFilesCleaner {
184184
/// files.
185185
virtual Result<std::set<std::string>> Clean() = 0;
186186

187+
/// Retrieve metrics related to orphan files cleaning operations.
188+
///
189+
/// @return A shared pointer to a `Metrics` object containing cleaning metrics.
190+
virtual std::shared_ptr<Metrics> GetMetrics() const = 0;
191+
187192
protected:
188193
OrphanFilesCleaner() = default;
189194
};

src/paimon/core/operation/file_store_commit_impl.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include "paimon/core/schema/schema_manager.h"
6363
#include "paimon/core/schema/table_schema.h"
6464
#include "paimon/core/table/sink/commit_message_impl.h"
65+
#include "paimon/core/utils/duration.h"
6566
#include "paimon/core/utils/file_store_path_factory.h"
6667
#include "paimon/core/utils/snapshot_manager.h"
6768
#include "paimon/fs/file_system.h"
@@ -379,7 +380,7 @@ Status FileStoreCommitImpl::Commit(const std::shared_ptr<ManifestCommittable>& c
379380

380381
int32_t attempt = 0;
381382
int32_t generated_snapshot = 0;
382-
const auto started = std::chrono::high_resolution_clock::now();
383+
Duration duration;
383384
if (!ignore_empty_commit_ || !append_table_files.empty() || !append_table_index_files.empty()) {
384385
PAIMON_ASSIGN_OR_RAISE(int32_t cnt,
385386
TryCommit(append_table_files, append_table_index_files,
@@ -403,10 +404,7 @@ Status FileStoreCommitImpl::Commit(const std::shared_ptr<ManifestCommittable>& c
403404
compaction_input_file_size += entry.File()->file_size;
404405
}
405406
}
406-
metrics_->SetCounter(CommitMetrics::LAST_COMMIT_DURATION,
407-
std::chrono::duration_cast<std::chrono::milliseconds>(
408-
std::chrono::high_resolution_clock::now() - started)
409-
.count());
407+
metrics_->SetCounter(CommitMetrics::LAST_COMMIT_DURATION, duration.Get());
410408
metrics_->SetCounter(CommitMetrics::LAST_COMMIT_ATTEMPTS, attempt);
411409
metrics_->SetCounter(CommitMetrics::LAST_TABLE_FILES_ADDED, table_files_added);
412410
metrics_->SetCounter(CommitMetrics::LAST_TABLE_FILES_DELETED, table_files_deleted);

src/paimon/core/operation/file_store_scan.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "paimon/core/operation/metrics/scan_metrics.h"
4040
#include "paimon/core/partition/partition_info.h"
4141
#include "paimon/core/stats/simple_stats.h"
42+
#include "paimon/core/utils/duration.h"
4243
#include "paimon/core/utils/field_mapping.h"
4344
#include "paimon/core/utils/snapshot_manager.h"
4445
#include "paimon/predicate/literal.h"
@@ -94,7 +95,7 @@ Result<std::vector<PartitionEntry>> FileStoreScan::ReadPartitionEntries() const
9495
}
9596

9697
Result<std::shared_ptr<FileStoreScan::RawPlan>> FileStoreScan::CreatePlan() const {
97-
const auto started = std::chrono::high_resolution_clock::now();
98+
Duration duration;
9899
std::optional<Snapshot> snapshot;
99100
std::vector<ManifestFileMeta> all_manifest_file_metas;
100101
std::vector<ManifestFileMeta> filtered_manifest_file_metas;
@@ -133,10 +134,7 @@ Result<std::shared_ptr<FileStoreScan::RawPlan>> FileStoreScan::CreatePlan() cons
133134
[](const int64_t sum, const ManifestFileMeta& manifest_file_meta) {
134135
return sum + manifest_file_meta.NumAddedFiles() - manifest_file_meta.NumDeletedFiles();
135136
});
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());
137+
metrics_->SetCounter(ScanMetrics::LAST_SCAN_DURATION, duration.Get());
140138
metrics_->SetCounter(ScanMetrics::LAST_SCANNED_SNAPSHOT_ID,
141139
snapshot.has_value() ? snapshot.value().Id() : int64_t{0});
142140
metrics_->SetCounter(ScanMetrics::LAST_SCANNED_MANIFESTS, filtered_manifest_file_metas.size());
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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 clean operation.
22+
class CleanMetrics {
23+
public:
24+
static constexpr char CLEAN_DURATION[] = "cleanDuration";
25+
static constexpr char CLEAN_LIST_DIRECTORIES_DURATION[] = "listDirectoriesDuration";
26+
static constexpr char CLEAN_LIST_DIRECTORIES[] = "listDirectories";
27+
static constexpr char CLEAN_LIST_FILE_STATUS_DURATION[] = "listFileStatusDuration";
28+
static constexpr char CLEAN_LIST_FILE_STATUS_TASKS[] = "listFileStatusTasks";
29+
static constexpr char CLEAN_LIST_USED_FILES_DURATION[] = "listUsedFilesDuration";
30+
static constexpr char CLEAN_USED_FILES[] = "usedFiles";
31+
static constexpr char CLEAN_SCAN_ORPHAN_FILES_DURATION[] = "scanOrphanFilesDuration";
32+
static constexpr char CLEAN_ORPHAN_FILES[] = "orphanFiles";
33+
};
34+
35+
} // namespace paimon

src/paimon/core/operation/orphan_files_cleaner_impl.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@
2525

2626
#include "fmt/format.h"
2727
#include "paimon/common/executor/future.h"
28+
#include "paimon/common/metrics/metrics_impl.h"
2829
#include "paimon/common/utils/path_util.h"
2930
#include "paimon/common/utils/scope_guard.h"
3031
#include "paimon/common/utils/string_utils.h"
3132
#include "paimon/core/manifest/manifest_entry.h"
3233
#include "paimon/core/manifest/manifest_file.h"
3334
#include "paimon/core/manifest/manifest_file_meta.h"
3435
#include "paimon/core/manifest/manifest_list.h"
36+
#include "paimon/core/operation/metrics/clean_metrics.h"
3537
#include "paimon/core/snapshot.h"
38+
#include "paimon/core/utils/duration.h"
3639
#include "paimon/core/utils/file_store_path_factory.h"
3740
#include "paimon/core/utils/snapshot_manager.h"
3841
#include "paimon/status.h"
@@ -61,7 +64,8 @@ OrphanFilesCleanerImpl::OrphanFilesCleanerImpl(
6164
manifest_file_(manifest_file),
6265
manifest_list_(manifest_list),
6366
older_than_ms_(older_than_ms),
64-
should_be_retained_(should_be_retained) {}
67+
should_be_retained_(should_be_retained),
68+
metrics_(std::make_shared<MetricsImpl>()) {}
6569

6670
bool OrphanFilesCleanerImpl::SupportToClean(const std::string& file_name) {
6771
static std::vector<std::pair<std::string, std::string>> supported_pattern = {
@@ -91,16 +95,18 @@ Result<std::set<std::string>> OrphanFilesCleanerImpl::Clean() {
9195
"OrphanFilesCleaner do not support cleaning table with branch");
9296
}
9397
PAIMON_ASSIGN_OR_RAISE(std::set<std::string> all_dirs, ListPaimonFileDirs());
98+
PAIMON_ASSIGN_OR_RAISE(std::set<std::string> used_file_names, GetUsedFiles());
99+
Duration duration;
94100
std::vector<std::future<std::vector<std::unique_ptr<FileStatus>>>> file_statuses_futures;
95101
for (const auto& dir : all_dirs) {
96102
file_statuses_futures.push_back(
97103
Via(executor_.get(), [this, dir] { return TryBestListingDirs(dir); }));
98104
}
99-
PAIMON_ASSIGN_OR_RAISE(std::set<std::string> used_file_names, GetUsedFiles());
100105

101106
std::set<std::string> need_to_deletes;
102107
std::vector<std::future<void>> futures;
103108
ScopeGuard guard([&futures]() { Wait(futures); });
109+
uint64_t file_statuses_duration = duration.Reset();
104110
for (const auto& file_statuses : CollectAll(file_statuses_futures)) {
105111
for (const auto& file_status : file_statuses) {
106112
if (file_status->IsDir()) {
@@ -129,10 +135,17 @@ Result<std::set<std::string>> OrphanFilesCleanerImpl::Clean() {
129135
}
130136
}
131137
}
138+
metrics_->SetCounter(CleanMetrics::CLEAN_SCAN_ORPHAN_FILES_DURATION, duration.Get());
139+
metrics_->SetCounter(CleanMetrics::CLEAN_LIST_FILE_STATUS_DURATION, file_statuses_duration);
140+
metrics_->SetCounter(CleanMetrics::CLEAN_LIST_FILE_STATUS_TASKS,
141+
static_cast<uint64_t>(file_statuses_futures.size()));
142+
metrics_->SetCounter(CleanMetrics::CLEAN_ORPHAN_FILES,
143+
static_cast<uint64_t>(need_to_deletes.size()));
132144
return need_to_deletes;
133145
}
134146

135147
Result<std::set<std::string>> OrphanFilesCleanerImpl::ListPaimonFileDirs() const {
148+
Duration duration;
136149
std::set<std::string> paimon_file_dirs;
137150
paimon_file_dirs.insert(snapshot_manager_->SnapshotDirectory());
138151
paimon_file_dirs.insert(FileStorePathFactory::ManifestPath(root_path_));
@@ -156,6 +169,9 @@ Result<std::set<std::string>> OrphanFilesCleanerImpl::ListPaimonFileDirs() const
156169
// ListFileDirs(external_path, partition_keys_.size());
157170
// paimon_file_dirs.insert(external_file_dirs.begin(), external_file_dirs.end());
158171
// }
172+
metrics_->SetCounter(CleanMetrics::CLEAN_LIST_DIRECTORIES_DURATION, duration.Get());
173+
metrics_->SetCounter(CleanMetrics::CLEAN_LIST_DIRECTORIES,
174+
static_cast<uint64_t>(paimon_file_dirs.size()));
159175
return paimon_file_dirs;
160176
}
161177

@@ -225,6 +241,7 @@ Result<std::set<std::string>> OrphanFilesCleanerImpl::GetUsedFiles() const {
225241
// TODO(jinli.zjw): consider changelog(add tests), stats
226242
used_files.insert(SnapshotManager::EARLIEST);
227243
used_files.insert(SnapshotManager::LATEST);
244+
Duration duration;
228245
PAIMON_ASSIGN_OR_RAISE(std::vector<Snapshot> snapshots, snapshot_manager_->GetAllSnapshots());
229246
for (const auto& snapshot : snapshots) {
230247
used_files.insert(SnapshotManager::SNAPSHOT_PREFIX + std::to_string(snapshot.Id()));
@@ -257,6 +274,8 @@ Result<std::set<std::string>> OrphanFilesCleanerImpl::GetUsedFiles() const {
257274
}
258275
}
259276
}
277+
metrics_->SetCounter(CleanMetrics::CLEAN_LIST_USED_FILES_DURATION, duration.Get());
278+
metrics_->SetCounter(CleanMetrics::CLEAN_USED_FILES, static_cast<uint64_t>(used_files.size()));
260279
return used_files;
261280
}
262281

src/paimon/core/operation/orphan_files_cleaner_impl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "paimon/core/snapshot.h"
2929
#include "paimon/fs/file_system.h"
3030
#include "paimon/memory/memory_pool.h"
31+
#include "paimon/metrics.h"
3132
#include "paimon/orphan_files_cleaner.h"
3233
#include "paimon/result.h"
3334

@@ -62,6 +63,10 @@ class OrphanFilesCleanerImpl : public OrphanFilesCleaner {
6263

6364
Result<std::set<std::string>> Clean() override;
6465

66+
std::shared_ptr<Metrics> GetMetrics() const override {
67+
return metrics_;
68+
}
69+
6570
private:
6671
Result<std::set<std::string>> ListPaimonFileDirs() const;
6772
std::vector<std::unique_ptr<FileStatus>> TryBestListingDirs(const std::string& path) const;
@@ -86,5 +91,7 @@ class OrphanFilesCleanerImpl : public OrphanFilesCleaner {
8691
std::shared_ptr<ManifestList> manifest_list_;
8792
int64_t older_than_ms_;
8893
std::function<bool(const std::string&)> should_be_retained_;
94+
95+
std::shared_ptr<Metrics> metrics_;
8996
};
9097
} // namespace paimon

src/paimon/core/utils/duration.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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+
#include <chrono>
20+
21+
namespace paimon {
22+
23+
// Calculate operation duration.
24+
class Duration {
25+
public:
26+
Duration() {
27+
Reset();
28+
}
29+
30+
uint64_t Get() {
31+
return std::chrono::duration_cast<std::chrono::milliseconds>(
32+
std::chrono::high_resolution_clock::now() - start_)
33+
.count();
34+
}
35+
36+
uint64_t Reset() {
37+
uint64_t dura = Get();
38+
start_ = std::chrono::high_resolution_clock::now();
39+
return dura;
40+
}
41+
42+
private:
43+
std::chrono::high_resolution_clock::time_point start_;
44+
};
45+
46+
} // namespace paimon

0 commit comments

Comments
 (0)