Pular para o conteúdo principal
O ClickHouse usa o jemalloc como alocador global. O jemalloc inclui ferramentas de amostragem e profiling de alocação. O ClickHouse e o Keeper permitem controlar a amostragem usando configurações, configurações de consulta, comandos SYSTEM e comandos de quatro letras (4LW) no Keeper. Há várias maneiras de inspecionar os resultados:
  • Coletar amostras em system.trace_log sob o tipo JemallocSample para análise por consulta.
  • Visualizar estatísticas de memória em tempo real e obter perfis de heap por meio da interface web integrada do jemalloc (26.2+).
  • Consultar o perfil de heap atual diretamente via SQL usando system.jemalloc_profile_text (26.2+).
  • Gravar perfis de heap em disco e analisá-los com jeprof.
Este guia se aplica às versões 25.9+. Para versões anteriores, consulte o perfil de alocação para versões anteriores à 25.9.

Amostragem de alocações

Para fazer a amostragem e traçar o perfil das alocações, inicie o ClickHouse/Keeper com a configuração jemalloc_enable_global_profiler habilitada:
<clickhouse>
    <jemalloc_enable_global_profiler>1</jemalloc_enable_global_profiler>
</clickhouse>
jemalloc fará a amostragem das alocações e armazenará as informações internamente. Você também pode ativar a amostragem por consulta usando a configuração jemalloc_enable_profiler.
AvisoComo o ClickHouse é um aplicativo com uso intensivo de alocação de memória, a amostragem do jemalloc pode causar sobrecarga de desempenho.

Armazenando amostras do jemalloc em system.trace_log

Você pode armazenar amostras do jemalloc em system.trace_log como o tipo JemallocSample. Para habilitar isso globalmente, use a configuração jemalloc_collect_global_profile_samples_in_trace_log:
<clickhouse>
    <jemalloc_collect_global_profile_samples_in_trace_log>1</jemalloc_collect_global_profile_samples_in_trace_log>
</clickhouse>
AvisoComo o ClickHouse é uma aplicação que faz uso intensivo de alocações, coletar todas as amostras em system.trace_log pode gerar uma carga elevada.
Você também pode habilitar isso por consulta usando a configuração jemalloc_collect_profile_samples_in_trace_log.

Exemplo: analisando o uso de memória de uma consulta

Primeiro, execute uma consulta com o profiler do jemalloc habilitado e colete as amostras em system.trace_log:
SELECT *
FROM numbers(1000000)
ORDER BY number DESC
SETTINGS max_bytes_ratio_before_external_sort = 0
FORMAT `Null`
SETTINGS jemalloc_enable_profiler = 1, jemalloc_collect_profile_samples_in_trace_log = 1

Query id: 8678d8fe-62c5-48b8-b0cd-26851c62dd75

Ok.

0 rows in set. Elapsed: 0.009 sec. Processed 1.00 million rows, 8.00 MB (108.58 million rows/s., 868.61 MB/s.)
Peak memory usage: 12.65 MiB.
Se o ClickHouse foi iniciado com jemalloc_enable_global_profiler, você não precisa habilitar jemalloc_enable_profiler. O mesmo vale para jemalloc_collect_global_profile_samples_in_trace_log e jemalloc_collect_profile_samples_in_trace_log.
Faça o flush de system.trace_log:
SYSTEM FLUSH LOGS trace_log
Em seguida, consulte-o para obter o uso cumulativo de memória ao longo do tempo:
WITH per_bucket AS
(
    SELECT
        event_time_microseconds AS bucket_time,
        sum(size) AS bucket_sum
    FROM system.trace_log
    WHERE trace_type = 'JemallocSample'
      AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
    GROUP BY bucket_time
)
SELECT
    bucket_time,
    sum(bucket_sum) OVER (
        ORDER BY bucket_time ASC
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS cumulative_size,
    formatReadableSize(cumulative_size) AS cumulative_size_readable
FROM per_bucket
ORDER BY bucket_time
Encontre o momento em que o uso de memória foi mais alto:
SELECT
    argMax(bucket_time, cumulative_size),
    max(cumulative_size)
FROM
(
    WITH per_bucket AS
    (
        SELECT
            event_time_microseconds AS bucket_time,
            sum(size) AS bucket_sum
        FROM system.trace_log
        WHERE trace_type = 'JemallocSample'
          AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
        GROUP BY bucket_time
    )
    SELECT
        bucket_time,
        sum(bucket_sum) OVER (
            ORDER BY bucket_time ASC
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS cumulative_size,
        formatReadableSize(cumulative_size) AS cumulative_size_readable
    FROM per_bucket
    ORDER BY bucket_time
)
Usando esse resultado, veja quais pilhas de alocação estavam mais ativas no momento de pico:
SELECT
    concat(
        '\n',
        arrayStringConcat(
            arrayMap(
                (x, y) -> concat(x, ': ', y),
                arrayMap(x -> addressToLine(x), allocation_trace),
                arrayMap(x -> demangle(addressToSymbol(x)), allocation_trace)
            ),
            '\n'
        )
    ) AS symbolized_trace,
    sum(s) AS per_trace_sum
FROM
(
    SELECT
        ptr,
        sum(size) AS s,
        argMax(trace, event_time_microseconds) AS allocation_trace
    FROM system.trace_log
    WHERE trace_type = 'JemallocSample'
      AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
      AND event_time_microseconds <= '2025-09-04 11:56:21.737139'
    GROUP BY ptr
    HAVING s > 0
)
GROUP BY ALL
ORDER BY per_trace_sum ASC

Interface web do jemalloc

Esta seção se aplica às versões 26.2+.
O ClickHouse fornece uma interface web integrada para visualizar estatísticas de memória do jemalloc no endpoint HTTP /jemalloc. Ela exibe métricas de memória em tempo real com gráficos, incluindo memória alocada, ativa, residente e mapeada, além de estatísticas por arena e por bin. Você também pode buscar perfis de heap globais e por consulta diretamente pela interface web.
http://localhost:8123/jemalloc
A interface web do servidor inclui todas as abas: Summary, Allocations, Arenas, Operations, Global Profiler, Query Profiler e Raw Output.

Obtendo perfis de heap por SQL

Esta seção se aplica às versões 26.2+.
A tabela de sistema system.jemalloc_profile_text permite obter e visualizar o perfil de heap atual do jemalloc diretamente por SQL, sem precisar de ferramentas externas nem de gravá-lo em disco antes. A tabela tem uma única coluna:
ColunaTipoDescrição
lineStringLinha do perfil de heap do jemalloc simbolizado.
Você pode consultar a tabela diretamente — não é necessário gravar um perfil de heap antes:
SELECT * FROM system.jemalloc_profile_text

Formato de saída

O formato de saída é controlado pela configuração jemalloc_profile_text_output_format, que oferece suporte a três valores:
  • raw — perfil de heap bruto, gerado pelo jemalloc.
  • symbolized — formato compatível com o jeprof, com símbolos de função incorporados. Como os símbolos já estão incorporados, o jeprof pode analisar a saída sem precisar do binário do ClickHouse.
  • collapsed (padrão) — pilhas colapsadas compatíveis com FlameGraph, uma pilha por linha com a contagem de bytes.
Por exemplo, para obter o perfil bruto:
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'raw'
Para obter uma saída simbolizada:
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'symbolized'

Configurações adicionais

  • jemalloc_profile_text_symbolize_with_inline (Bool, padrão: true) — Define se frames inline devem ser incluídos na simbolização. Desabilitar isso acelera significativamente a simbolização, mas reduz a precisão, pois chamadas de função inline não aparecerão nas stacks. Afeta apenas os formatos symbolized e collapsed.
  • jemalloc_profile_text_collapsed_use_count (Bool, padrão: false) — Ao usar o formato collapsed, agrega por contagem de alocações em vez de bytes.

Exemplo: gerando um flame graph com SQL

Como o formato de saída padrão é collapsed, você pode passar a saída diretamente para o FlameGraph:
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text" | flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg
Para gerar um flame graph com base na contagem de alocações, em vez de bytes:
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text SETTINGS jemalloc_profile_text_collapsed_use_count = 1" | flamegraph.pl --color=mem --title="Allocation Count Flame Graph" --width 2400 > result.svg

Gravando perfis de heap no disco

Se você precisar salvar perfis de heap como arquivos para análise offline com jeprof, poderá gravá-los no disco. Por padrão, o arquivo de perfil de heap será gerado em /tmp/jemalloc_clickhouse._pid_._seqnum_.heap, em que _pid_ é o PID do ClickHouse e _seqnum_ é o número de sequência global do perfil de heap atual. No Keeper, o arquivo padrão é /tmp/jemalloc_keeper._pid_._seqnum_.heap e segue as mesmas regras. Para gravar o perfil atual:
SYSTEM JEMALLOC FLUSH PROFILE
Ele retornará o local do perfil gravado.
É possível definir outro local adicionando a opção prof_prefix à variável de ambiente MALLOC_CONF. Por exemplo, se você quiser gerar perfis na pasta /data, em que o prefixo do nome do arquivo será my_current_profile, poderá executar o ClickHouse/Keeper com a seguinte variável de ambiente:
MALLOC_CONF=prof_prefix:/data/my_current_profile
O PID e o número de sequência serão acrescentados ao prefixo do arquivo gerado.

Analisando arquivos de perfil de heap com jeprof

Após gravar os perfis de heap em disco, eles podem ser analisados usando a ferramenta do jemalloc chamada jeprof. Ela pode ser instalada de várias formas:
  • Usando o gerenciador de pacotes do sistema
  • Clonando o repositório do jemalloc e executando autogen.sh a partir da pasta raiz. Isso disponibilizará o script jeprof na pasta bin
Há vários formatos de saída disponíveis. Execute jeprof --help para ver a lista completa de opções.

Perfis de heap simbolizados

A partir da versão 26.1+, o ClickHouse gera automaticamente perfis de heap simbolizados quando você executa SYSTEM JEMALLOC FLUSH PROFILE. O perfil simbolizado (com a extensão .symbolized) contém símbolos de função incorporados e pode ser analisado com o jeprof sem exigir o binário do ClickHouse. Por exemplo, quando você executa:
SYSTEM JEMALLOC FLUSH PROFILE
O ClickHouse retornará o caminho para o profile simbolizado (por exemplo, /tmp/jemalloc_clickhouse.12345.0.heap.symbolized). Em seguida, você poderá analisá-lo diretamente com jeprof:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --output_format [ > output_file]
Nenhum binário necessário: Ao usar perfis simbolizados (arquivos .symbolized), você não precisa fornecer o caminho do binário do ClickHouse ao jeprof. Isso facilita muito a análise de perfis em máquinas diferentes ou depois que o binário tiver sido atualizado.
Se você tiver um perfil de heap mais antigo, sem símbolos, e ainda tiver acesso ao binário do ClickHouse, poderá usar a abordagem tradicional:
jeprof path/to/clickhouse path/to/heap/profile --output_format [ > output_file]
Para perfis não simbolizados, jeprof usa addr2line para gerar stacktraces, o que pode ser bem lento. Se esse for o caso, recomenda-se instalar uma implementação alternativa da ferramenta.
git clone https://github.com/gimli-rs/addr2line.git --depth=1 --branch=0.23.0
cd addr2line
cargo build --features bin --release
cp ./target/release/addr2line path/to/current/addr2line
Como alternativa, llvm-addr2line funciona igualmente bem (mas observe que llvm-objdump não é compatível com jeprof)Depois, use-o assim: jeprof --tools addr2line:/usr/bin/llvm-addr2line,nm:/usr/bin/llvm-nm,objdump:/usr/bin/objdump,c++filt:/usr/bin/llvm-cxxfilt
Ao comparar dois perfis, você pode usar o argumento --base:
jeprof --base /path/to/first.heap.symbolized /path/to/second.heap.symbolized --output_format [ > output_file]

Exemplos

Usando perfis simbolizados (recomendado):
  • Gere um arquivo de texto com cada procedimento em uma linha:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --text > result.txt
  • Gere um arquivo PDF com o grafo de chamadas:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --pdf > result.pdf
Usando perfis não simbolizados (requer o binário):
  • Gere um arquivo de texto com cada procedimento em uma linha:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --text > result.txt
  • Gere um arquivo PDF com um grafo de chamadas:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --pdf > result.pdf

Gerando um flame graph

jeprof permite gerar pilhas colapsadas para criar flame graphs. Você precisa usar o argumento --collapsed:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --collapsed > result.collapsed
Ou com um perfil sem símbolos:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --collapsed > result.collapsed
Depois disso, você pode usar várias ferramentas para visualizar pilhas colapsadas. A mais popular é o FlameGraph, que contém um script chamado flamegraph.pl:
cat result.collapsed | /path/to/FlameGraph/flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg
Outra ferramenta interessante é o speedscope, que permite analisar as stacks coletadas de forma mais interativa.

Opções adicionais para o profiler

O jemalloc oferece muitas opções relacionadas ao profiler. Elas podem ser controladas modificando a variável de ambiente MALLOC_CONF. Por exemplo, o intervalo entre as amostras de alocação pode ser controlado com lg_prof_sample. Se você quiser gerar o heap profile a cada N bytes, pode ativá-lo usando lg_prof_interval. Recomenda-se consultar a página de referência do jemalloc para obter uma lista completa das opções.

Outros recursos

ClickHouse/Keeper expõem métricas relacionadas ao jemalloc de várias formas.
AvisoÉ importante ter em mente que nenhuma dessas métricas é sincronizada com as outras, e os valores podem divergir.

Tabela de sistema asynchronous_metrics

SELECT *
FROM system.asynchronous_metrics
WHERE metric LIKE '%jemalloc%'
FORMAT Vertical
Referência

Tabela de sistema jemalloc_bins

Contém informações sobre alocações de memória feitas pelo alocador jemalloc em diferentes classes de tamanho (bins), agregadas a partir de todas as arenas. Referência

Tabela do sistema jemalloc_stats (26.2+)

Retorna toda a saída de malloc_stats_print() como uma única string. Equivalente ao comando SYSTEM JEMALLOC STATS.
SELECT * FROM system.jemalloc_stats

Prometheus

Todas as métricas relacionadas ao jemalloc de asynchronous_metrics também são expostas por meio do endpoint do Prometheus, tanto no ClickHouse quanto no Keeper. Referência

Comando 4LW jmst no Keeper

O Keeper é compatível com o comando 4LW jmst, que retorna estatísticas básicas do alocador:
echo jmst | nc localhost 9181
Última modificação em 10 de junho de 2026