Skip to content

Commit 139bd4f

Browse files
Merge pull request ClickHouse#88537 from ClickHouse/backport/25.8/87903
Backport ClickHouse#87903 to 25.8: Add more information for Iceberg SELECT queries profiling
2 parents 3db67e4 + 9e77704 commit 139bd4f

File tree

10 files changed

+240
-83
lines changed

10 files changed

+240
-83
lines changed

src/Common/ProfileEvents.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@
8787
M(IcebergMetadataFilesCacheHits, "Number of times iceberg metadata files have been found in the cache.", ValueType::Number) \
8888
M(IcebergMetadataFilesCacheMisses, "Number of times iceberg metadata files have not been found in the iceberg metadata cache and had to be read from (remote) disk.", ValueType::Number) \
8989
M(IcebergMetadataFilesCacheWeightLost, "Approximate number of bytes evicted from the iceberg metadata cache.", ValueType::Number) \
90+
M(IcebergMetadataReadWaitTimeMicroseconds, "Total time data readers spend waiting for iceberg metadata files to be read and parsed, summed across all reader threads.", ValueType::Microseconds) \
91+
M(IcebergIteratorInitializationMicroseconds, "Total time spent on synchronous initialization of iceberg data iterators.", ValueType::Microseconds) \
92+
M(IcebergMetadataUpdateMicroseconds, "Total time spent on synchronous initialization of iceberg data iterators.", ValueType::Microseconds) \
93+
M(IcebergMetadataReturnedObjectInfos, "Total number of returned object infos from iceberg iterator.", ValueType::Number) \
9094
M(VectorSimilarityIndexCacheHits, "Number of times an index granule has been found in the vector index cache.", ValueType::Number) \
9195
M(VectorSimilarityIndexCacheMisses, "Number of times an index granule has not been found in the vector index cache and had to be read from disk.", ValueType::Number) \
9296
M(VectorSimilarityIndexCacheWeightLost, "Approximate number of bytes evicted from the vector index cache.", ValueType::Number) \

src/Interpreters/IcebergMetadataLog.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ namespace
4444

4545
const DataTypePtr rowType = makeNullable(std::make_shared<DataTypeUInt64>());
4646

47+
auto iceberg_pruning_status_datatype = std::make_shared<DataTypeEnum8>(DataTypeEnum8::Values{
48+
{"NotPruned", static_cast<Int8>(Iceberg::PruningReturnStatus::NOT_PRUNED)},
49+
{"PartitionPruned", static_cast<Int8>(Iceberg::PruningReturnStatus::PARTITION_PRUNED)},
50+
{"MinMaxIndexPruned", static_cast<Int8>(Iceberg::PruningReturnStatus::MIN_MAX_INDEX_PRUNED)}});
51+
52+
const DataTypePtr iceberg_pruning_status_datatype_nullable = makeNullable(iceberg_pruning_status_datatype);
4753
}
4854

4955
ColumnsDescription IcebergMetadataLogElement::getColumnsDescription()
@@ -64,7 +70,8 @@ ColumnsDescription IcebergMetadataLogElement::getColumnsDescription()
6470
{"table_path", std::make_shared<DataTypeString>(), "Table path."},
6571
{"file_path", std::make_shared<DataTypeString>(), "File path."},
6672
{"content", std::make_shared<DataTypeString>(), "Content in a JSON format (json file content, avro metadata or avro entry)."},
67-
{"row_in_file", rowType, "Row in file."}};
73+
{"row_in_file", rowType, "Row in file."},
74+
{"pruning_status", iceberg_pruning_status_datatype_nullable, "Status of partition pruning or min-max index pruning for the file."}};
6875
}
6976

7077
void IcebergMetadataLogElement::appendToBlock(MutableColumns & columns) const
@@ -79,6 +86,7 @@ void IcebergMetadataLogElement::appendToBlock(MutableColumns & columns) const
7986
columns[column_index++]->insert(file_path);
8087
columns[column_index++]->insert(metadata_content);
8188
columns[column_index++]->insert(row_in_file ? *row_in_file : rowType->getDefault());
89+
columns[column_index++]->insert(pruning_status ? *pruning_status : iceberg_pruning_status_datatype_nullable->getDefault());
8290
}
8391

8492
void insertRowToLogTable(
@@ -87,7 +95,8 @@ void insertRowToLogTable(
8795
IcebergMetadataLogLevel row_log_level,
8896
const String & table_path,
8997
const String & file_path,
90-
std::optional<UInt64> row_in_file)
98+
std::optional<UInt64> row_in_file,
99+
std::optional<Iceberg::PruningReturnStatus> pruning_status)
91100
{
92101
IcebergMetadataLogLevel set_log_level = local_context->getSettingsRef()[Setting::iceberg_metadata_log_level].value;
93102
if (set_log_level < row_log_level)
@@ -104,6 +113,7 @@ void insertRowToLogTable(
104113
.table_path = table_path,
105114
.file_path = file_path,
106115
.metadata_content = row,
107-
.row_in_file = row_in_file});
116+
.row_in_file = row_in_file,
117+
.pruning_status = pruning_status});
108118
}
109119
}

src/Interpreters/IcebergMetadataLog.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <Interpreters/SystemLog.h>
44
#include <Storages/ColumnsDescription.h>
5+
#include <Storages/ObjectStorage/DataLakes/Iceberg/ManifestFilesPruning.h>
56

67
namespace DB
78
{
@@ -15,6 +16,7 @@ struct IcebergMetadataLogElement
1516
String file_path;
1617
String metadata_content;
1718
std::optional<UInt64> row_in_file;
19+
std::optional<Iceberg::PruningReturnStatus> pruning_status;
1820

1921
static std::string name() { return "IcebergMetadataLog"; }
2022

@@ -29,7 +31,8 @@ void insertRowToLogTable(
2931
IcebergMetadataLogLevel row_log_level,
3032
const String & table_path,
3133
const String & file_path,
32-
std::optional<UInt64> row_in_file);
34+
std::optional<UInt64> row_in_file,
35+
std::optional<Iceberg::PruningReturnStatus> pruning_status);
3336

3437
class IcebergMetadataLog : public SystemLog<IcebergMetadataLogElement>
3538
{

src/Storages/ObjectStorage/DataLakes/Iceberg/IcebergIterator.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#include "config.h"
32
#if USE_AVRO
43

@@ -45,13 +44,21 @@
4544

4645
#include <Storages/ObjectStorage/DataLakes/Iceberg/StatelessMetadataFileGetter.h>
4746

47+
#include <Common/ProfileEvents.h>
4848
#include <Common/SharedLockGuard.h>
4949
#include <Common/logger_useful.h>
5050

51+
#include <Interpreters/IcebergMetadataLog.h>
52+
#include <base/wide_integer_to_string.h>
53+
#include <Common/ElapsedTimeProfileEventIncrement.h>
54+
55+
5156
namespace ProfileEvents
5257
{
5358
extern const Event IcebergPartitionPrunedFiles;
5459
extern const Event IcebergMinMaxIndexPrunedFiles;
60+
extern const Event IcebergMetadataReadWaitTimeMicroseconds;
61+
extern const Event IcebergMetadataReturnedObjectInfos;
5562
};
5663

5764

@@ -158,6 +165,14 @@ std::optional<ManifestFileEntry> SingleThreadIcebergKeysIterator::next()
158165
local_context);
159166
}
160167
auto pruning_status = current_pruner ? current_pruner->canBePruned(manifest_file_entry) : PruningReturnStatus::NOT_PRUNED;
168+
insertRowToLogTable(
169+
local_context,
170+
"",
171+
DB::IcebergMetadataLogLevel::ManifestFileEntry,
172+
configuration.lock()->getRawPath().path,
173+
current_manifest_file_content->getPathToManifestFile(),
174+
manifest_file_entry.row_number,
175+
pruning_status);
161176
switch (pruning_status)
162177
{
163178
case PruningReturnStatus::NOT_PRUNED:
@@ -321,6 +336,7 @@ IcebergIterator::IcebergIterator(
321336

322337
ObjectInfoPtr IcebergIterator::next(size_t)
323338
{
339+
ProfileEventTimeIncrement<Microseconds> watch(ProfileEvents::IcebergMetadataReadWaitTimeMicroseconds);
324340
Iceberg::ManifestFileEntry manifest_file_entry;
325341
if (blocking_queue.pop(manifest_file_entry))
326342
{
@@ -333,6 +349,7 @@ ObjectInfoPtr IcebergIterator::next(size_t)
333349
{
334350
object_info->addEqualityDeleteObject(equality_delete);
335351
}
352+
ProfileEvents::increment(ProfileEvents::IcebergMetadataReturnedObjectInfos);
336353
return object_info;
337354
}
338355
{

src/Storages/ObjectStorage/DataLakes/Iceberg/IcebergMetadata.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@
6868

6969
namespace ProfileEvents
7070
{
71-
extern const Event IcebergTrivialCountOptimizationApplied;
71+
extern const Event IcebergIteratorInitializationMicroseconds;
72+
extern const Event IcebergMetadataUpdateMicroseconds;
73+
extern const Event IcebergTrivialCountOptimizationApplied;
7274
}
7375

7476
namespace DB
@@ -249,6 +251,7 @@ bool IcebergMetadata::update(const ContextPtr & local_context)
249251
DB::IcebergMetadataLogLevel::Metadata,
250252
configuration_ptr->getRawPath().path,
251253
metadata_file_path,
254+
std::nullopt,
252255
std::nullopt);
253256

254257
if (previous_snapshot_id != relevant_snapshot_id)
@@ -587,6 +590,7 @@ DataLakeMetadataPtr IcebergMetadata::create(
587590
DB::IcebergMetadataLogLevel::Metadata,
588591
configuration_ptr->getRawPath().path,
589592
metadata_file_path,
593+
std::nullopt,
590594
std::nullopt);
591595
return std::make_unique<IcebergMetadata>(object_storage, configuration_ptr, local_context, metadata_version, format_version, object, cache_ptr, compression_method);
592596
}
@@ -782,6 +786,8 @@ ObjectIterator IcebergMetadata::iterate(
782786
{
783787
SharedLockGuard lock(mutex);
784788

789+
ProfileEventTimeIncrement<Microseconds> watch(ProfileEvents::IcebergIteratorInitializationMicroseconds);
790+
785791
auto table_snapshot
786792
= std::make_shared<IcebergTableStateSnapshot>(last_metadata_version, relevant_snapshot_schema_id, relevant_snapshot_id);
787793
return std::make_shared<IcebergIterator>(

src/Storages/ObjectStorage/DataLakes/Iceberg/ManifestFile.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ ManifestFileContent::ManifestFileContent(
160160
DB::IcebergMetadataLogLevel::ManifestFileMetadata,
161161
common_path,
162162
path_to_manifest_file,
163+
std::nullopt,
163164
std::nullopt);
164165

165166
for (const auto & column_name : {f_status, f_data_file})
@@ -235,7 +236,8 @@ ManifestFileContent::ManifestFileContent(
235236
DB::IcebergMetadataLogLevel::ManifestFileEntry,
236237
common_path,
237238
path_to_manifest_file,
238-
i);
239+
i,
240+
std::nullopt);
239241
FileContentType content_type = FileContentType::DATA;
240242
if (format_version_ > 1)
241243
content_type = FileContentType(manifest_file_deserializer.getValueFromRowByName(i, c_data_file_content, TypeIndex::Int32).safeGet<UInt64>());
@@ -418,6 +420,7 @@ ManifestFileContent::ManifestFileContent(
418420
this->data_files_without_deleted.emplace_back(
419421
file_path_key,
420422
file_path,
423+
i,
421424
status,
422425
added_sequence_number,
423426
snapshot_id,
@@ -444,6 +447,7 @@ ManifestFileContent::ManifestFileContent(
444447
this->position_deletes_files_without_deleted.emplace_back(
445448
file_path_key,
446449
file_path,
450+
i,
447451
status,
448452
added_sequence_number,
449453
snapshot_id,
@@ -472,6 +476,7 @@ ManifestFileContent::ManifestFileContent(
472476
this->equality_deletes_files.emplace_back(
473477
file_path_key,
474478
file_path,
479+
i,
475480
status,
476481
added_sequence_number,
477482
snapshot_id,

src/Storages/ObjectStorage/DataLakes/Iceberg/ManifestFile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct ManifestFileEntry
6161
String file_path_key;
6262
// It's a processed file path to be used by Object Storage
6363
String file_path;
64+
Int64 row_number;
6465

6566
ManifestEntryStatus status;
6667
Int64 added_sequence_number;

src/Storages/ObjectStorage/DataLakes/Iceberg/ManifestFilesPruning.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22
#include "config.h"
33

4-
#if USE_AVRO
54

65
#include <Core/NamesAndTypes.h>
76
#include <Parsers/IAST_fwd.h>
@@ -21,6 +20,13 @@ enum class PruningReturnStatus
2120
MIN_MAX_INDEX_PRUNED
2221
};
2322

23+
}
24+
25+
#if USE_AVRO
26+
27+
namespace DB::Iceberg
28+
{
29+
2430
struct ManifestFileEntry;
2531
class ManifestFileContent;
2632

src/Storages/ObjectStorage/DataLakes/Iceberg/StatelessMetadataFileGetter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ ManifestFileCacheKeys getManifestList(
153153
DB::IcebergMetadataLogLevel::ManifestListMetadata,
154154
configuration_ptr->getRawPath().path,
155155
filename,
156+
std::nullopt,
156157
std::nullopt);
157158

158159
for (size_t i = 0; i < manifest_list_deserializer.rows(); ++i)
@@ -187,7 +188,8 @@ ManifestFileCacheKeys getManifestList(
187188
DB::IcebergMetadataLogLevel::ManifestListEntry,
188189
configuration_ptr->getRawPath().path,
189190
filename,
190-
i);
191+
i,
192+
std::nullopt);
191193
}
192194
/// We only return the list of {file name, seq number} for cache.
193195
/// Because ManifestList holds a list of ManifestFilePtr which consume much memory space.
@@ -248,7 +250,6 @@ std::pair<Poco::JSON::Object::Ptr, Int32> parseTableSchemaV1Method(const Poco::J
248250
auto current_schema_id = schema->getValue<int>(f_schema_id);
249251
return {schema, current_schema_id};
250252
}
251-
252253
}
253254
}
254255

0 commit comments

Comments
 (0)