跳到主要内容
跳到主要内容

反射函数

您可以使用本章描述的函数来反射 ELFDWARF 以进行查询分析。

备注

这些函数运行缓慢,可能会带来安全隐患。

为了使反射函数正常工作:

  • 安装 clickhouse-common-static-dbg 包。

  • allow_introspection_functions 设置为 1。

    出于安全原因,反射函数默认情况下是禁用的。

ClickHouse 将分析器报告保存到 trace_log 系统表中。请确保该表和分析器已正确配置。

demangle

引入于:v20.1

将符号转换为 C++ 函数名称。 该符号通常由函数 addressToSymbol 返回。

语法

demangle(symbol)

参数

  • symbol — 来自对象文件的符号。 String

返回值

返回 C++ 函数的名称,如果符号无效,则返回空字符串。 String

示例

trace_log 系统表中选择第一个字符串

SELECT * FROM system.trace_log LIMIT 1 \G;
-- The `trace` field contains the stack trace at the moment of sampling.
Row 1:
──────
event_date:    2019-11-20
event_time:    2019-11-20 16:57:59
revision:      54429
timer_type:    Real
thread_number: 48
query_id:      724028bf-f550-45aa-910d-2af6212b94ac
trace:         [94138803686098,94138815010911,94138815096522,94138815101224,94138815102091,94138814222988,94138806823642,94138814457211,94138806823642,94138814457211,94138806823642,94138806795179,94138806796144,94138753770094,94138753771646,94138753760572,94138852407232,140399185266395,140399178045583]

获取单个地址的函数名称

SET allow_introspection_functions=1;
SELECT demangle(addressToSymbol(94138803686098)) \G;
Row 1:
──────
demangle(addressToSymbol(94138803686098)): DB::IAggregateFunctionHelper<DB::AggregateFunctionSum<unsigned long, unsigned long, DB::AggregateFunctionSumData<unsigned long> > >::addBatchSinglePlace(unsigned long, char*, DB::IColumn const**, DB::Arena*) const

将函数应用于整个堆栈跟踪

SET allow_introspection_functions=1;

-- The arrayMap function allows to process each individual element of the trace array by the demangle function.
-- The result of this processing is shown in the trace_functions column of output.

SELECT
    arrayStringConcat(arrayMap(x -> demangle(addressToSymbol(x)), trace), '\n') AS trace_functions
FROM system.trace_log
LIMIT 1
\G
Row 1:
──────
trace_functions: DB::IAggregateFunctionHelper<DB::AggregateFunctionSum<unsigned long, unsigned long, DB::AggregateFunctionSumData<unsigned long> > >::addBatchSinglePlace(unsigned long, char*, DB::IColumn const**, DB::Arena*) const
DB::Aggregator::executeWithoutKeyImpl(char*&, unsigned long, DB::Aggregator::AggregateFunctionInstruction*, DB::Arena*) const
DB::Aggregator::executeOnBlock(std::vector<COW<DB::IColumn>::immutable_ptr<DB::IColumn>, std::allocator<COW<DB::IColumn>::immutable_ptr<DB::IColumn> > >, unsigned long, DB::AggregatedDataVariants&, std::vector<DB::IColumn const*, std::allocator<DB::IColumn const*> >&, std::vector<std::vector<DB::IColumn const*, std::allocator<DB::IColumn const*> >, std::allocator<std::vector<DB::IColumn const*, std::allocator<DB::IColumn const*> > > >&, bool&)
DB::Aggregator::executeOnBlock(DB::Block const&, DB::AggregatedDataVariants&, std::vector<DB::IColumn const*, std::allocator<DB::IColumn const*> >&, std::vector<std::vector<DB::IColumn const*, std::allocator<DB::IColumn const*> >, std::allocator<std::vector<DB::IColumn const*, std::allocator<DB::IColumn const*> > > >&, bool&)
DB::Aggregator::execute(std::shared_ptr<DB::IBlockInputStream> const&, DB::AggregatedDataVariants&)
DB::AggregatingBlockInputStream::readImpl()
DB::IBlockInputStream::read()
DB::ExpressionBlockInputStream::readImpl()
DB::IBlockInputStream::read()
DB::ExpressionBlockInputStream::readImpl()
DB::IBlockInputStream::read()
DB::AsynchronousBlockInputStream::calculate()
std::_Function_handler<void (), DB::AsynchronousBlockInputStream::next()::{lambda()#1}>::_M_invoke(std::_Any_data const&)
ThreadPoolImpl<ThreadFromGlobalPool>::worker(std::_List_iterator<ThreadFromGlobalPool>)
ThreadFromGlobalPool::ThreadFromGlobalPool<ThreadPoolImpl<ThreadFromGlobalPool>::scheduleImpl<void>(std::function<void ()>, int, std::optional<unsigned long>)::{lambda()#3}>(ThreadPoolImpl<ThreadFromGlobalPool>::scheduleImpl<void>(std::function<void ()>, int, std::optional<unsigned long>)::{lambda()#3}&&)::{lambda()#1}::operator()() const
ThreadPoolImpl<std::thread>::worker(std::_List_iterator<std::thread>)
execute_native_thread_routine
start_thread
clone

isMergeTreePartCoveredBy

引入于:v25.6

该函数检查第一个参数的部分是否被第二个参数的部分覆盖。

语法

isMergeTreePartCoveredBy(nested_part, covering_part)

参数

  • nested_part — 预期的嵌套部分名称。 String
  • covering_part — 预期的覆盖部分名称。 String

返回值

如果覆盖返回 1,否则返回 0UInt8

示例

基本示例

WITH 'all_12_25_7_4' AS lhs, 'all_7_100_10_20' AS rhs
SELECT isMergeTreePartCoveredBy(rhs, lhs), isMergeTreePartCoveredBy(lhs, rhs);
┌─isMergeTreePartCoveredBy(rhs, lhs)─┬─isMergeTreePartCoveredBy(lhs, rhs)─┐
│                                  0 │                                  1 │
└────────────────────────────────────┴────────────────────────────────────┘

logTrace

引入于:v20.12

为每个 Block 向服务器日志发出跟踪日志消息。

语法

logTrace(message)

参数

  • message — 发出到服务器日志的消息。 const String

返回值

始终返回 0UInt8

示例

基本示例

SELECT logTrace('logTrace message');
┌─logTrace('logTrace message')─┐
│                            0 │
└──────────────────────────────┘

mergeTreePartInfo

引入于:v25.6

该函数帮助从 MergeTree 部分名称中提取有用值。

语法

mergeTreePartInfo(part_name)

参数

  • part_name — 要解包的部分名称。 String

返回值

返回一个元组,其子列包括:partition_idmin_blockmax_blocklevelmutationTuple

示例

基本示例

WITH mergeTreePartInfo('all_12_25_7_4') AS info
SELECT info.partition_id, info.min_block, info.max_block, info.level, info.mutation;
┌─info.partition_id─┬─info.min_block─┬─info.max_block─┬─info.level─┬─info.mutation─┐
│ all               │             12 │             25 │          7 │             4 │
└───────────────────┴────────────────┴────────────────┴────────────┴───────────────┘

tid

引入于:v20.12

返回当前 Block 正在处理的线程的 ID。

语法

tid()

参数

  • 无。 返回值

返回当前线程 ID。 UInt64

示例

使用示例

SELECT tid();
┌─tid()─┐
│  3878 │
└───────┘