Skip to content

Commit b059278

Browse files
authored
Merge pull request ClickHouse#78412 from ClickHouse/transposed_metric_log
Allow to use transposed metric log
2 parents 27f1df7 + ec89dd4 commit b059278

File tree

20 files changed

+1298
-7
lines changed

20 files changed

+1298
-7
lines changed

docs/en/operations/system-tables/metric_log.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ CurrentMetric_LocalThreadActive: 0
5454
CurrentMetric_DistributedFilesToInsert: 0
5555
```
5656

57+
**Schema**
58+
This table can be configured with different schema types using the XML tag `<schema_type>`. The default schema type is `wide`, where each metric or profile event is stored as a separate column. This schema is the most performant and efficient for single-column reads.
59+
60+
The `transposed` schema stores data in a format similar to `system.asynchronous_metric_log`, where metrics and events are stored as rows. This schema is useful for low-resource setups because it reduces resource consumption during merges.
61+
62+
There is also a compatibility schema, `transposed_with_wide_view`, which stores actual data in a table with the transposed schema (`system.transposed_metric_log`) and creates a view on top of it using the wide schema. This view queries the transposed table, making it useful for migrating from the `wide` schema to the `transposed` schema.
63+
5764
**See also**
5865

5966
- [metric_log setting](../../operations/server-configuration-parameters/settings.md#metric_log) — Enabling and disabling the setting.

src/Common/SystemLogBase.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <Interpreters/CrashLog.h>
33
#include <Interpreters/ErrorLog.h>
44
#include <Interpreters/MetricLog.h>
5+
#include <Interpreters/TransposedMetricLog.h>
56
#include <Interpreters/LatencyLog.h>
67
#include <Interpreters/OpenTelemetrySpanLog.h>
78
#include <Interpreters/PartLog.h>

src/Common/SystemLogBase.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class ISystemLog
8383

8484
virtual void savingThreadFunction() = 0;
8585

86+
virtual bool mustBePreparedAtStartup() const { return false; }
87+
8688
protected:
8789
std::mutex thread_mutex;
8890
std::unique_ptr<ThreadFromGlobalPool> saving_thread;

src/Interpreters/Context.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4761,6 +4761,16 @@ std::shared_ptr<MetricLog> Context::getMetricLog() const
47614761
return shared->system_logs->metric_log;
47624762
}
47634763

4764+
std::shared_ptr<TransposedMetricLog> Context::getTransposedMetricLog() const
4765+
{
4766+
SharedLockGuard lock(shared->mutex);
4767+
4768+
if (!shared->system_logs)
4769+
return {};
4770+
4771+
return shared->system_logs->transposed_metric_log;
4772+
}
4773+
47644774

47654775
std::shared_ptr<LatencyLog> Context::getLatencyLog() const
47664776
{

src/Interpreters/Context.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class PartLog;
116116
class TextLog;
117117
class TraceLog;
118118
class MetricLog;
119+
class TransposedMetricLog;
119120
class LatencyLog;
120121
class AsynchronousMetricLog;
121122
class OpenTelemetrySpanLog;
@@ -1256,6 +1257,7 @@ class Context: public ContextData, public std::enable_shared_from_this<Context>
12561257
std::shared_ptr<TraceLog> getTraceLog() const;
12571258
std::shared_ptr<TextLog> getTextLog() const;
12581259
std::shared_ptr<MetricLog> getMetricLog() const;
1260+
std::shared_ptr<TransposedMetricLog> getTransposedMetricLog() const;
12591261
std::shared_ptr<LatencyLog> getLatencyLog() const;
12601262
std::shared_ptr<AsynchronousMetricLog> getAsynchronousMetricLog() const;
12611263
std::shared_ptr<OpenTelemetrySpanLog> getOpenTelemetrySpanLog() const;

src/Interpreters/PeriodicLog.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <Common/SystemLogBase.h>
33
#include <Interpreters/ErrorLog.h>
44
#include <Interpreters/MetricLog.h>
5+
#include <Interpreters/TransposedMetricLog.h>
56
#include <Interpreters/PeriodicLog.h>
67
#include <Interpreters/QueryMetricLog.h>
78
#include <Interpreters/LatencyLog.h>

src/Interpreters/PeriodicLog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define SYSTEM_PERIODIC_LOG_ELEMENTS(M) \
1010
M(ErrorLogElement) \
1111
M(MetricLogElement) \
12+
M(TransposedMetricLogElement) \
1213
M(LatencyLogElement) \
1314

1415

src/Interpreters/SystemLog.cpp

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <Interpreters/InterpreterInsertQuery.h>
2222
#include <Interpreters/InterpreterRenameQuery.h>
2323
#include <Interpreters/MetricLog.h>
24+
#include <Interpreters/TransposedMetricLog.h>
2425
#include <Interpreters/LatencyLog.h>
2526
#include <Interpreters/OpenTelemetrySpanLog.h>
2627
#include <Interpreters/PartLog.h>
@@ -158,7 +159,11 @@ std::shared_ptr<TSystemLog> createSystemLog(
158159
SystemLogSettings log_settings;
159160

160161
log_settings.queue_settings.database = config.getString(config_prefix + ".database", default_database_name);
161-
log_settings.queue_settings.table = config.getString(config_prefix + ".table", default_table_name);
162+
163+
if (default_table_name != "transposed_metric_log")
164+
log_settings.queue_settings.table = config.getString(config_prefix + ".table", default_table_name);
165+
else
166+
log_settings.queue_settings.table = default_table_name;
162167

163168
if (log_settings.queue_settings.database != default_database_name)
164169
{
@@ -213,9 +218,26 @@ std::shared_ptr<TSystemLog> createSystemLog(
213218
if (!ttl.empty())
214219
log_settings.engine += " TTL " + ttl;
215220

216-
/// ORDER BY expr is necessary.
217-
String order_by = config.getString(config_prefix + ".order_by", TSystemLog::getDefaultOrderBy());
218-
log_settings.engine += " ORDER BY (" + order_by + ")";
221+
if (std::is_same_v<TSystemLog, TransposedMetricLog>)
222+
{
223+
auto schema = config.getString(config_prefix + ".schema_type", "wide");
224+
/// NOTE, fixed schema, it's not allowed to change order by for efficiency reasons
225+
if (schema == "transposed_with_wide_view")
226+
{
227+
log_settings.engine += std::string{" ORDER BY ("} + TSystemLog::getDefaultOrderBy() + ")";
228+
}
229+
else
230+
{
231+
String order_by = config.getString(config_prefix + ".order_by", TSystemLog::getDefaultOrderBy());
232+
log_settings.engine += " ORDER BY (" + order_by + ")";
233+
}
234+
}
235+
else
236+
{
237+
/// ORDER BY expr is necessary.
238+
String order_by = config.getString(config_prefix + ".order_by", TSystemLog::getDefaultOrderBy());
239+
log_settings.engine += " ORDER BY (" + order_by + ")";
240+
}
219241

220242
/// SETTINGS expr is not necessary.
221243
/// https://clickhouse.com/docs/engines/table-engines/mergetree-family/mergetree#settings
@@ -279,7 +301,34 @@ std::shared_ptr<TSystemLog> createSystemLog(
279301

280302
log_settings.queue_settings.turn_off_logger = TSystemLog::shouldTurnOffLogger();
281303

304+
if constexpr (std::is_same_v<TSystemLog, MetricLog>)
305+
{
306+
auto schema = config.getString(config_prefix + ".schema_type", "wide");
307+
if (schema == "wide")
308+
return std::make_shared<TSystemLog>(context, log_settings);
309+
310+
return {};
311+
}
312+
else if (std::is_same_v<TSystemLog, TransposedMetricLog>)
313+
{
314+
auto schema = config.getString(config_prefix + ".schema_type", "wide");
315+
if (schema == "transposed_with_wide_view")
316+
{
317+
log_settings.view_name_for_transposed_metric_log = config.getString(config_prefix + ".table", "metric_log");
318+
return std::make_shared<TSystemLog>(context, log_settings);
319+
}
320+
else if (schema == "transposed")
321+
{
322+
return std::make_shared<TSystemLog>(context, log_settings);
323+
}
324+
else if (schema != "wide")
325+
{
326+
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Unknown schema type {} for metric_log table, only 'wide', 'transposed' and 'transposed_with_wide_view' are allowed", schema);
327+
}
328+
}
329+
282330
return std::make_shared<TSystemLog>(context, log_settings);
331+
283332
}
284333

285334

@@ -306,15 +355,28 @@ SystemLogs::SystemLogs(ContextPtr global_context, const Poco::Util::AbstractConf
306355

307356
LIST_OF_ALL_SYSTEM_LOGS(CREATE_PUBLIC_MEMBERS)
308357
#undef CREATE_PUBLIC_MEMBERS
358+
309359
/// NOLINTEND(bugprone-macro-parentheses)
310360

361+
if (metric_log == nullptr && config.has("metric_log") && config.getString("metric_log.schema_type", "wide") == "transposed")
362+
{
363+
transposed_metric_log = createSystemLog<TransposedMetricLog>(
364+
global_context, "system", "metric_log", config, "metric_log", TransposedMetricLog::DESCRIPTION);
365+
}
366+
else if (metric_log == nullptr && config.has("metric_log") && config.getString("metric_log.schema_type", "wide") == "transposed_with_wide_view")
367+
{
368+
transposed_metric_log = createSystemLog<TransposedMetricLog>(
369+
global_context, "system", "transposed_metric_log", config, "metric_log", TransposedMetricLog::DESCRIPTION);
370+
}
371+
372+
311373
bool should_prepare = global_context->getServerSettings()[ServerSetting::prepare_system_log_tables_on_startup];
312374
try
313375
{
314376
for (auto & log : getAllLogs())
315377
{
316378
log->startup();
317-
if (should_prepare)
379+
if (should_prepare || log->mustBePreparedAtStartup())
318380
log->prepareTable();
319381
}
320382
}
@@ -332,6 +394,13 @@ SystemLogs::SystemLogs(ContextPtr global_context, const Poco::Util::AbstractConf
332394
metric_log->startCollect("MetricLog", collect_interval_milliseconds);
333395
}
334396

397+
if (transposed_metric_log)
398+
{
399+
size_t collect_interval_milliseconds = config.getUInt64("metric_log.collect_interval_milliseconds",
400+
DEFAULT_METRIC_LOG_COLLECT_INTERVAL_MILLISECONDS);
401+
transposed_metric_log->startCollect("TMetricLog", collect_interval_milliseconds);
402+
}
403+
335404
if (latency_log)
336405
{
337406
size_t collect_interval_milliseconds = config.getUInt64("latency_log.collect_interval_milliseconds",

src/Interpreters/SystemLog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
M(CrashLog, crash_log, "Contains information about stack traces for fatal errors. The table does not exist in the database by default, it is created only when fatal errors occur.") \
1515
M(TextLog, text_log, "Contains logging entries which are normally written to a log file or to stdout.") \
1616
M(MetricLog, metric_log, "Contains history of metrics values from tables system.metrics and system.events, periodically flushed to disk.") \
17+
M(TransposedMetricLog, transposed_metric_log,"Contains history of metrics values from tables system.metrics and system.events. Periodically flushed to disk. Transposed form of system.metric_log.") \
1718
M(LatencyLog, latency_log, "Contains history of all latency buckets, periodically flushed to disk.") \
1819
M(ErrorLog, error_log, "Contains history of error values from table system.errors, periodically flushed to disk.") \
1920
M(FilesystemCacheLog, filesystem_cache_log, "Contains a history of all events occurred with filesystem cache for objects on a remote filesystem.") \
@@ -99,6 +100,7 @@ struct SystemLogSettings
99100

100101
String engine;
101102
bool symbolize_traces = false;
103+
std::string view_name_for_transposed_metric_log;
102104
};
103105

104106
template <typename LogElement>

0 commit comments

Comments
 (0)