184 похожих чатов

Всём доброе утро, день, вечер ) коллеги подскажите что можно

сделать: есть относительно небольшая таблица 100+ млн строк, 30-40 столбцов. В ней нужно удалять раз в сутки старые записи, ttl не подходит поскольку то что нужно удалить - вычисляемое множество. Иногда выдаёт memory limit error - видно в логах мутаций. Что можно сделать, мб уменьшить кол-во обработчиков фоновых процессов?

28 ответов

28 просмотров

Если вычисляемое множество, то и выборка мутации подозреваю тоже по нему работает рассчитывая на лету. Соответственно по памяти падает потому что запрос слишком сложный/долгий. И ответ из этого, материализуейте вычисляемое множество в реальную колонку, и удаляйте по ней хоть в ttl

Роман-Болдырев Автор вопроса
L de Funes
Если вычисляемое множество, то и выборка мутации п...

По ttl всё равно не получится. Может я не точно выразился, попробую перефразировать: из таблицы выбираются те id, что уже неактуальны и это не критерий времени, далее удаляются всё эти id. Запрос там достаточно простой, без джойнов. Потому могу предположить что просто выборка не влезает в память, хм, может выборку тупо лимитом ограничить

Роман Болдырев
По ttl всё равно не получится. Может я не точно вы...

покажите запрос. сколько мутаций одновременно запускается?

Роман-Болдырев Автор вопроса
Denny [Altinity]
покажите запрос. сколько мутаций одновременно запу...

Alter table... Delete where id in (select id from... Where...) ; Падало на 1 мутации с количеством parts_to_do 300+

Я бы на дверь показал, а когда пришел разбираться тот, кто на работу взял, СБ вызвал.

Первое, что приходит в голову, это делать delete in partition - находишь партиции, которые будут изменены, и по ним по отдельности делаешь удаление Ещё можешь найти партиции, которые будешь менять, создать временную таблицу (полноценную копию оригинала), через insert вставить в неё строки из изменяемых партиций с фильтром и потом через replace partition вставить в оригинальную таблицу

Роман-Болдырев Автор вопроса

раз в день удалять надо именно через мутации (желательно IN PARTITION но автоматический прунинг тоже есть давно уже). мутации по памяти вообще не должны падать. у вас какие-то сложные условия в where?

【D】【J】
раз в день удалять надо именно через мутации (жела...

мутации могут падать, если их не через словарь делают а через сложный запрос

Роман-Болдырев Автор вопроса
【D】【J】
раз в день удалять надо именно через мутации (жела...

В условии отобрать все id которых нет в словаре, словарь содержит актуальные записи. Словарь 30+ млн строк и 2 столбца. В памяти занимает 4 Гб.

Dmitry [Altinity] Titov
мутации могут падать, если их не через словарь дел...

ну, поэтому и спросил про "что там в WHERE" коллега удаляет, не обновляет... но мало ли что там в WHERE

Роман Болдырев
Alter table... Delete where id in (select id from....

Вообще, это не самое правильное использование кликхауса, удаление данных мутациями, это последнее что надо делать. Это не MySQL, и для ваших данных возможно правильнее использовать его, а для аналитики уже переливать из MySQL в кликхаус (есть даже движок подходящий) Прочитайте про разницу между OLAP и OLTP. С таким подходом и количеством обрабатываемых партиций, проблема будет расти как снежный ком с ростом количества данных. У вас после удаления данных все эти партиции должны будут перестроиться и смержиться под новые индексы, и так каждый раз, пока вы не столкнетесь с тем что будет недостаточно и места для выполнения операции. Я бы пересмотрел архитектуру и способ хранения данных. Или как другую костыльную альтернативу использовал VersionedCollapsingMergeTree или ReplacingMergeTree для "обнуления" нужных вам строк, а не удаления

Роман Болдырев
По ttl всё равно не получится. Может я не точно вы...

если дело не в том, что критически нужно высвобождать место, а просто "отключать" ненужные id, для меня выглядит логичнее сделать это через колонку is_active или is_deleted (на ваш вкус) и поверх таблицы просто прикрутить вью, которая по этой колонке фильтрует. потом на старых cold партициях где-нибудь в 3 утра запускать физическое удаление таких строк.

Роман-Болдырев Автор вопроса
ivan
если дело не в том, что критически нужно высвобожд...

Не логичней, ведь тогда придётся делать апдейт этой колонки, когда id станет неактуальным - что тоже будет тяжело для КХ.

Роман Болдырев
Не логичней, ведь тогда придётся делать апдейт это...

бесспорно, но вроде как апдейты по логике должны быть гораздо легче "физически" для системы, чем удаления

Роман-Болдырев Автор вопроса
【D】【J】
WHERE dictHas() ?

Where dictGet(dictionary, dict. Attribute, table.Key) = table. Attribute что-то вроде латерального запроса к справочнику в памяти

ivan
бесспорно, но вроде как апдейты по логике должны б...

как минимум если колонок в таблице больше, чем одна)

Роман-Болдырев Автор вопроса
ivan
бесспорно, но вроде как апдейты по логике должны б...

Почему? И там и там насколько я понял читая статью на Хабре происходит клонирование куска, вычищение лишнего из куска или обновление в нём данных и потом замена новым куском - старого?

Роман Болдырев
Почему? И там и там насколько я понял читая стать...

так как система колоночная, то (как я понимаю), чтобы сделать апдейт нужно обработать один "файл-колонку", а для удаления — столько же, сколько столбцов в таблице

Роман Болдырев
Where dictGet(dictionary, dict. Attribute, table.K...

у вас перебор, так нельзя вы удаляете по двум полям? если так делайте словарь с композитным ключем на два поля...

Роман-Болдырев Автор вопроса
【D】【J】
у вас перебор, так нельзя вы удаляете по двум поля...

Почему нельзя? Работает же, и причём быстро достаточно...

Роман Болдырев
Почему нельзя? Работает же, и причём быстро достат...

хотя да, так тоже будет быстро... но память есть не должен совсем. может память кто-то другой съедает? у вас словарь не автообновляемый?

Роман Болдырев
Почему нельзя? Работает же, и причём быстро достат...

Вы либо обновляете минимальный файл с uint8 изменяя 0 или 1. Либо удаляет и пересобираете парт в партиции по всем столбцам, вроде вывод очевиден

Роман-Болдырев Автор вопроса
【D】【J】
хотя да, так тоже будет быстро... но память есть н...

Авто обновляемый, может кто то другой - этот вариант я тоже прорабатываю

Роман-Болдырев Автор вопроса

Всем спасибо за помощь в вопросе, в итоге переспал) с вашими идеями ночь и придумал свой вариант. - удаляю материализованный столбец если он есть is_actual - 9 секунд. (alter table ... drop column if exists) - Создаю материализованный столбец в основной таблице is_actual в котором из словаря сразу рассчитываю его актуальность. 1-3 секунды (alter table ... add column if not exists ...) - далее делаю alter table ... delete where is_actual = 0 and date_modify < today() — чтобы не зацепить те данные что в процессе укладки (допущение, но не планируется запускать такую чистку сразу в начале дня, часа в 3 ночи - там уже все будет уложено точно. date_modify - дата вставки строки в таблицу - дефолт на стороне КХ) - жду 15-30 секунд - мутация успешно завершена. - профит.

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта