> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Страница с описанием профилирования выделения памяти в ClickHouse

# Профилирование выделения памяти для версий до 25.9

ClickHouse использует [jemalloc](https://github.com/jemalloc/jemalloc) в качестве глобального аллокатора. В jemalloc есть инструменты для сэмплирования выделений памяти и профилирования.
Чтобы упростить профилирование выделения памяти, доступны команды `SYSTEM`, а также четырёхбуквенные команды (4LW) в Keeper.

<div id="sampling-allocations-and-flushing-heap-profiles">
  ## Сэмплирование выделений памяти и сброс профилей кучи
</div>

Если вы хотите включить сэмплирование и профилирование выделений памяти в `jemalloc`, необходимо запустить ClickHouse/Keeper с включенным профилированием, используя переменную окружения `MALLOC_CONF`:

```sh theme={null}
MALLOC_CONF=background_thread:true,prof:true,prof_active:true
```

`jemalloc` будет выборочно сэмплировать выделения памяти и хранить эту информацию внутри.

Вы можете указать `jemalloc` сбросить текущий профиль, выполнив:

<Tabs>
  <Tab title="ClickHouse">
    ```sql theme={null}
    SYSTEM JEMALLOC FLUSH PROFILE
    ```
  </Tab>

  <Tab title="Keeper">
    ```sh theme={null}
    echo jmfp | nc localhost 9181
    ```
  </Tab>
</Tabs>

По умолчанию файл профиля кучи будет создан в `/tmp/jemalloc_clickhouse._pid_._seqnum_.heap`, где `_pid_` — PID процесса ClickHouse, а `_seqnum_` — глобальный порядковый номер текущего профиля кучи.
Для Keeper по умолчанию используется файл `/tmp/jemalloc_keeper._pid_._seqnum_.heap`; для него действуют те же правила.

Другое расположение можно задать, добавив к переменной окружения `MALLOC_CONF` параметр `prof_prefix`.
Например, если вы хотите создавать профили в папке `/data`, где префикс имени файла будет `my_current_profile`, вы можете запустить ClickHouse/Keeper со следующей переменной окружения:

```sh theme={null}
MALLOC_CONF=background_thread:true,prof:true,prof_prefix:/data/my_current_profile
```

К имени сгенерированного файла будут добавлены префикс PID и порядковый номер.

<div id="analyzing-heap-profiles">
  ## Анализ профилей кучи
</div>

После создания профили кучи необходимо проанализировать.
Для этого можно использовать инструмент `jemalloc` под названием [jeprof](https://github.com/jemalloc/jemalloc/blob/dev/bin/jeprof.in). Установить его можно несколькими способами:

* С помощью системного менеджера пакетов
* Клонировать [репозиторий jemalloc](https://github.com/jemalloc/jemalloc) и запустить `autogen.sh` из корневого каталога. В результате в каталоге `bin` появится скрипт `jeprof`

<Note>
  `jeprof` использует `addr2line` для генерации трассировок стека, что может быть довольно медленно.
  В этом случае рекомендуется установить [альтернативную реализацию](https://github.com/gimli-rs/addr2line) этого инструмента.

  ```bash theme={null}
  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
  ```
</Note>

С помощью `jeprof` из профиля кучи можно получить данные во многих разных форматах.
Чтобы узнать о способе использования и доступных параметрах, рекомендуется выполнить `jeprof --help`.

В общем случае команда `jeprof` выглядит так:

```sh theme={null}
jeprof path/to/binary path/to/heap/profile --output_format [ > output_file]
```

Если вы хотите сравнить, какие выделения памяти произошли между двумя профилями, можно задать аргумент `base`:

```sh theme={null}
jeprof path/to/binary --base path/to/first/heap/profile path/to/second/heap/profile --output_format [ > output_file]
```

<div id="examples">
  ### Примеры
</div>

* если вы хотите создать текстовый файл, где каждая процедура записана в отдельной строке:

```sh theme={null}
jeprof path/to/binary path/to/heap/profile --text > result.txt
```

* если вы хотите сгенерировать PDF-файл с графом вызовов:

```sh theme={null}
jeprof path/to/binary path/to/heap/profile --pdf > result.pdf
```

<div id="generating-flame-graph">
  ### Создание флеймграфа
</div>

`jeprof` позволяет генерировать свёрнутые стеки для построения флеймграфов.

Для этого нужно использовать аргумент `--collapsed`:

```sh theme={null}
jeprof path/to/binary path/to/heap/profile --collapsed > result.collapsed
```

После этого можно использовать множество различных инструментов для визуализации свёрнутых стеков.

Самый популярный из них — [FlameGraph](https://github.com/brendangregg/FlameGraph), в состав которого входит скрипт `flamegraph.pl`:

```sh theme={null}
cat result.collapsed | /path/to/FlameGraph/flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg
```

Ещё один интересный инструмент — [speedscope](https://www.speedscope.app/), который позволяет анализировать собранные стеки в более интерактивном режиме.

<div id="controlling-allocation-profiler-during-runtime">
  ## Управление профилировщиком выделения памяти во время выполнения
</div>

Если ClickHouse/Keeper запущен с включенным профилировщиком, во время выполнения доступны дополнительные команды для включения и отключения профилирования выделения памяти.
С их помощью проще профилировать только определенные интервалы.

Чтобы отключить профилировщик:

<Tabs>
  <Tab title="ClickHouse">
    ```sql theme={null}
    SYSTEM JEMALLOC DISABLE PROFILE
    ```
  </Tab>

  <Tab title="Keeper">
    ```sh theme={null}
    echo jmdp | nc localhost 9181
    ```
  </Tab>
</Tabs>

Чтобы включить профилировщик:

<Tabs>
  <Tab title="ClickHouse">
    ```sql theme={null}
    SYSTEM JEMALLOC ENABLE PROFILE
    ```
  </Tab>

  <Tab title="Keeper">
    ```sh theme={null}
    echo jmep | nc localhost 9181
    ```
  </Tab>
</Tabs>

Начальным состоянием профилировщика также можно управлять с помощью параметра `prof_active`, который по умолчанию включен.
Например, если вы не хотите выполнять выборку выделений памяти во время запуска, а только после него, можно включить профилировщик позже. Вы можете запустить ClickHouse/Keeper со следующей переменной окружения:

```sh theme={null}
MALLOC_CONF=background_thread:true,prof:true,prof_active:false
```

Профилировщик можно включить позже.

<div id="additional-options-for-profiler">
  ## Дополнительные параметры для профилировщика
</div>

У `jemalloc` есть множество параметров, относящихся к профилировщику. Ими можно управлять, изменяя переменную окружения `MALLOC_CONF`.
Например, интервал между выборками выделения памяти можно задать с помощью `lg_prof_sample`.
Если вы хотите выгружать профиль кучи каждые N байт, включите это с помощью `lg_prof_interval`.

Чтобы получить полный список параметров, рекомендуется обратиться к [странице справки](https://jemalloc.net/jemalloc.3.html) `jemalloc`.

<div id="other-resources">
  ## Другие ресурсы
</div>

ClickHouse/Keeper предоставляют метрики, связанные с `jemalloc`, различными способами.

<Warning>
  **Предупреждение**

  Важно помнить, что эти метрики не синхронизированы друг с другом, и их значения могут расходиться.
</Warning>

<div id="system-table-asynchronous_metrics">
  ### Системная таблица `asynchronous_metrics`
</div>

```sql theme={null}
SELECT *
FROM system.asynchronous_metrics
WHERE metric LIKE '%jemalloc%'
FORMAT Vertical
```

[Справочник](/ru/reference/system-tables/asynchronous_metrics)

<div id="system-table-jemalloc_bins">
  ### Системная таблица `jemalloc_bins`
</div>

Содержит информацию о выделении памяти через аллокатор jemalloc в различных классах размеров (bins), собранную по всем аренам.

[Справочник](/ru/reference/system-tables/jemalloc_bins)

<div id="prometheus">
  ### Prometheus
</div>

Все метрики, связанные с `jemalloc`, из `asynchronous_metrics` также экспортируются через конечную точку Prometheus как в ClickHouse, так и в Keeper.

[Справочник](/ru/reference/settings/server-settings/settings#prometheus)

<div id="jmst-4lw-command-in-keeper">
  ### Команда 4LW `jmst` в Keeper
</div>

Keeper поддерживает команду 4LW `jmst`, которая возвращает [базовую статистику аллокатора памяти](https://github.com/jemalloc/jemalloc/wiki/Use-Case%3A-Basic-Allocator-Statistics):

```sh theme={null}
echo jmst | nc localhost 9181
```
