На одном сервере ClickHouse одновременно выполняются тяжёлый пакетный отчёт и короткие запросы рабочих панелей. Пока памяти достаточно, отчёт использует свободный запас и никому не мешает. Затем приходит ещё одна интерактивная выборка, просит новую порцию памяти, а ClickHouse завершает совсем другой запрос. Со стороны это похоже на ошибку: память понадобилась одному запросу, а жертвой стал другой. Но так и задумана внутренняя политика memory overcommit.
Она пытается сохранить управляемость смешанной нагрузки, выбрав работу, которая относительно сильнее других вышла за назначенную ей основу сравнения. Это не бесплатная RAM и не исправление плохого SQL. Если полезная одновременная работа физически не помещается на сервере, ClickHouse способен лишь решить, какой запрос потерять первым. Цена решения — сорванный отчёт, повторный запуск и потраченное до завершения время.
Это не overcommit виртуальных машин
В виртуальной инфраструктуре overcommit означает, что гостям суммарно обещали больше памяти, чем физически установлено на хосте. Гипервизор рассчитывает на несовпадение потребностей ВМ и при давлении возвращает страницы. ClickHouse решает другую задачу внутри одного сервера базы. Memory overcommit в ClickHouse — экспериментальная политика более гибких лимитов запросов. Она не меняет объём DRAM и не обещает процессу больше физической памяти. Механизм начинает действовать, когда достигается применимый предел и нужно освободить память для продолжения работы.
ClickHouse ведёт учёт расхода запросов через внутренние трекеры памяти. Они сравнивают текущую нагрузку с правилами пользователя или всего сервера и выбирают наиболее переподписанный запрос. Под «переподписанным» здесь понимается не виртуальная машина, а запрос, который сильнее превысил свою относительную гарантированную основу.
Жёсткий потолок плохо описывает смешанную нагрузку
Предел одного запроса задаёт максимальный объём, который запрос может использовать на одном сервере. Отдельный предел пользователя охватывает совокупность его запросов. Серверная граница защищает общий процесс ClickHouse и оставляет место операционной системе и другой работе. Один жёсткий потолок создаёт противоположные ошибки. Если поставить его низко, полезный отчёт завершится даже на свободном сервере, где память никому больше не нужна. Если разрешить тяжёлым запросам расти без достаточного общего контроля, несколько одновременных отчётов способны исчерпать сервер.
Смешанная нагрузка требует условной свободы. Пакетный отчёт может временно использовать свободную память, пока интерактивные панели работают легко. При реальном дефиците система должна вернуть запас, не дожидаясь аварийного завершения всего процесса со стороны ОС. Memory overcommit пытается выразить именно этот договор: превышение возможно, когда ресурс свободен, но не становится безусловным правом. Запрос получает шанс завершиться быстрее в спокойный период и принимает риск быть выбранным при конкуренции.
Жертва и инициатор дефицита могут не совпасть
Когда запросу нужна новая аллокация памяти и достигнут предел, ClickHouse обращается к соответствующему overcommit tracker. Трекер ищет наиболее переподписанный запрос в своей области и пытается освободить память его завершением. Поэтому последняя просьба о памяти лишь запускает проверку, но не обязательно определяет жертву. Запрос, который пытается получить память, может немного ждать. За это время выбранная работа должна освободить свои структуры, и тогда ожидающий запрос продолжит выполнение. Если за отведённое время память не появилась, он получает исключение MEMORY_LIMIT_EXCEEDED и завершается.
Получаются два разных события. Один запрос выбран для принудительного завершения как наиболее переподписанный. Другой не смог дождаться освобождения памяти. В журнале ошибок они могут оказаться рядом, но причины их завершения различаются. Это объясняет кажущуюся несправедливость. Тяжёлый отчёт мог начать работу раньше и долго потреблять память, а короткий запрос лишь обнаружил, что общий предел достигнут. Политика старается освободить больше ресурса там, где превышение относительно гарантии выше, а не наказать последнего пришедшего. Ожидание тоже не бесплатно. Пока система освобождает память, интерактивный запрос задерживается, а завершённый отчёт теряет уже выполненную работу. Поэтому успешная защита измеряется не отсутствием падения процесса, а приемлемым временем ответа, числом повторов и объёмом завершённой полезной работы.
User и global tracker защищают разные границы
User overcommit tracker выбирает запрос среди работ одного пользователя, когда достигнут пользовательский лимит. Это позволяет не переносить превышение одного клиента или класса нагрузки на всех остальных. Global tracker рассматривает запросы на сервере шире, когда достигнута общая граница. Denominator — значение, которое задаёт запросу относительную гарантированную основу для сравнения. Чем сильнее текущее потребление вышло за эту основу относительно других запросов в том же трекере, тем вероятнее выбор. Для управленческого понимания формула не нужна: это вес права на память, а не резервирование физических байтов.
Нулевой denominator исключает запрос из выбора конкретным overcommit tracker. Но это не делает его бессмертным. Он всё ещё может достичь собственного или другого лимита, получить MEMORY_LIMIT_EXCEEDED, быть завершён административно либо пострадать от OOM операционной системы. Пользовательский и глобальный denominator также нельзя механически смешивать. Каждый участвует в своей области сравнения. Неверно настроенный приоритет способен защитить пакетную работу от трекера и фактически переложить риск на интерактивные запросы или общий сервер.
Overcommit не заменяет работу с запросом
Тяжёлые группировки и сортировки держат промежуточные данные, а широкое чтение и высокая параллельность увеличивают объём одновременной работы. Если отчёт обрабатывает лишние строки или запускается многократно, выбор жертвы не уменьшает его реальную стоимость. Он лишь ограничивает ущерб при дефиците. У ClickHouse есть отдельные пределы для запроса, пользователя и сервера. Они задают жёсткие границы ответственности. Overcommit полезен поверх них, когда нужно разрешить временно использовать свободный запас и сохранить правило, кто уступает при конкуренции.
Для поддерживаемых группировок и сортировок промежуточные данные можно переводить во внешние алгоритмы с записью на диск. Это снижает пик RAM, но добавляет I/O и задержку. Нельзя обещать, что любая операция умеет выгрузиться или что накопитель выдержит несколько таких работ одновременно. Другие решения меняют сам спрос: сокращают объём читаемых данных, уменьшают параллелизм запроса, разводят тяжёлые отчёты по времени или ограничивают конкуренцию. Это не список универсальных настроек. Выбор зависит от того, какая работа важна и какую задержку допускает её класс.
За выбором жертвы остаётся физический предел
Если серверу действительно не хватает памяти для обязательной одновременной нагрузки, внутренний трекер не решает проблему ёмкости. Он освобождает память завершением одной работы, чтобы остальные получили шанс. Когда жертвой регулярно становится полезный процесс, это уже не гибкость, а недостаточный ресурс или неверная архитектура нагрузки. Прозрачный страничный уровень класса gigaRAM и memory overcommit ClickHouse работают на разных уровнях. ClickHouse решает, какой запрос продолжит работу при дефиците, а страничный слой размещает подходящие менее активные страницы между DRAM и NVMe. Он не отменяет лимиты ClickHouse и сам по себе не устраняет MEMORY_LIMIT_EXCEEDED.
Дополнительная физическая память оправдана, если конкуренцию нельзя убрать без нарушения сроков, поддерживаемая выгрузка на диск не подходит, а полезная смесь запросов воспроизводимо не помещается. Но сначала отделяют дорогой запрос, чрезмерную одновременность и неверные приоритеты от настоящего недостатка ёмкости. Управленческий смысл механизма прост: свободную память можно использовать смелее, если заранее определено, какая работа уступит при дефиците. Это управляемая потеря, а не ускорение и не новая RAM. Качество решения видно по завершённым отчётам и интерактивным ответам, а не по самому факту работы overcommit tracker.
Источники. ClickHouse Docs — Memory overcommit определяет экспериментальный механизм, ожидание, выбор запроса и user/global tracker.
Session Settings описывает пределы запроса и пользователя.
Restrictions on query complexity подтверждает внешние алгоритмы для поддерживаемых группировок и сортировок.
ClickHouse — 13 mistakes and how to avoid them используется для сценария смешанной нагрузки и того, что жертва может отличаться от инициатора дефицита.
Meta Engineering — TMO применяется только к общей механике страничного переноса.
Страница продукта — только для позиционирования класса решения.
