Как искать длинные хеши и ID с dict='keywords_32k'

Практическое руководство по поиску длинных хешей, event ID, message ID и email в Manticore Search: лимиты, точное сравнение, wildcard-поиск, токенизация, миграция и ограничения.

Формальный непроцедурный язык программирования

Практическое руководство по поиску длинных хешей, event ID, message ID и email в Manticore Search: лимиты, точное сравнение, wildcard-поиск, токенизация, миграция и ограничения.

После прошлого поста я вдохновился на продолжение, помимо того, что я изначально хотел его доработать, я также увидел, что количество людей увидевших мой пост перевалило за 7,5 тысяч.
Поэтому я сел за доработку согласно предыдущему плану, что я писал в той статье. Я решил идти по первому пути и сделать логирование асинхронным. Дело в том, что так это становится изолированной переменной, ведь банально легче доработать и тестировать, чем заниматься рефакторингом всего кода и разносить его по разным процессам. После доработки я конечно же решил протестировать новую версию и я очень удивился результатам. Изначально throughput действительно вырос, что обрадовало меня.
Я уже думал писать статью, но решил мимолетом запустить 175 воркеров. Это решение создало неожиданную проблему - задача оказалась обработана за 11 секунд до ее создания.

Привет, Хабр!
В этой статье разберём ещё один инструмент ClickHouse, который часто используется при обогащении данных и позволяет значительно ускорить выполнение тяжелых SQL-запросов с джоинами.

Привет, на связи команда BI-разработчиков коммерческого департамента: Алексей Дубинец и Павел Беспалов.
В статье расскажем, как построили пайплайн миграции наших витрин с помощью локальной LLM.
Сразу оговорюсь: это не история про то, как мы дали в Codex или Claude Code, написали скилл и получили магический результат. Покажем инженерную часть задачи: где локальная модель срабатывает не так, какие наивные решения не работают и что пришлось построить вокруг неё, чтобы перевод стал воспроизводимым.

ora2pg переносит схему с Oracle на PostgreSQL, и в целом переносит хорошо. Интересное начинается там, где он чего-то не осилил: он не падает и не ругается, а молча делает не то.
Процедура с AUTHID исчезает из вывода целиком, без ошибки и без строки в логе. TO_DATE с форматом RR молча возвращает 1 год до нашей эры. LONG RAW превращается в text, хотя сам ora2pg документирует bytea. Обработчик исключений после конвертации ловит SQLSTATE, которого PostgreSQL не возбуждает никогда.
Двадцать таких мест, все проверены на реальном ora2pg 25.0 и живом PostgreSQL 16, по каждому написано чем чинить.

Большой текст пугает: часть читателей уходит на середине, часть пролистывает не читая. Поэтому дальше — только факты, действия и последствия: что изменилось в метаданных, как это изменение попало в production и что в итоге получилось — результат, который до сих пор помогает находить источник проблем.

1. Зачем это нужно
Моя боль как автора (а я не только программист и к. т. н, но еще и писатель в жанре фантастики) – это отсутствие на сайте автор.тудей полноценного анализа статистики. Вся статистика ограничивается просмотрами, временем и средним временем прочтений по дням и главам, в виде шахматки:

В статье разбираем реальное тестовое задание на позицию аналитика DWH: четыре коротких SQL-запроса. Все синтаксически корректны, все дают верный результат на контрольных данных. И в каждом спрятана предпосылка, при нарушении которой цифры в витрине становятся неверными — без ошибок, без предупреждений, просто другие числа в отчёте

В первой статье я объяснял кэш через холодильник. Продолжу тем же способом. Сейчас будет про индексы, а потом про то, почему индекс есть, а база его игнорирует.
Статья для тех, кто индексы ставил, но EXPLAIN читал по диагонали.

У банков и ритейлеров, с которыми я работала, почти всегда одна и та же боль: данные о клиенте размазаны по CRM, core-banking и платёжным системам, и никто не может ответить на простой вопрос — а что мы вообще знаем об этом клиенте прямо сейчас. Чтобы попрактиковаться в решении этой задачи и показать подход публично, я собрала pet-проект: end-to-end пайплайн, который строит единую витрину Customer 360 из синтетических данных.
Сразу оговорюсь: все данные генерируются локально скриптом и полностью синтетические. Кода или данных работодателя в проекте нет — это самостоятельная реализация архитектуры, которую я использую в повседневной работе DWH/data-аналитика.
В первой части был инструмент, который снимает схему Firebird и раскладывает её деревом файлов: один объект — один файл. Он отлично отвечает на вопрос «как эта процедура выглядит сейчас» и совершенно беспомощен в вопросе «кто её поменял в среду вечером». Дамп — это фотография, а нам нужен ещё и вахтенный журнал.
Вторая часть — про журнал. Про то, какие факты об изменении схемы имеет смысл хранить прямо в базе, чем за это платишь и где закопаны грабли, на которые я наступил, чтобы вы могли их обойти.
Когда я только пришел на должность помощника DBA, я заметил, что все production базы фиксируют изменения странным образом, а именно каждый день в 00:00 вызывался скрипт, который выгружает схему БД Firebird, в виде файла script.sql, созданный встроенной утилитой isql. Далее делил весь файл на объекты (файлы), по группам (директориям) принадлежности, объясняю: есть кусок скрипта создания таблицы, он помещается в директорию 01_TABLES в виде отдельного файла названного в честь названия объекта который он содержит, и так далее. Чем же это плохо? А суть в том что разработчиков много, правки анонимны, история тяжело воспроизводимая. В такой каше сразу не разберешься.
В 2020-м мне понадобилось версионировать схему ClickHouse в CI/CD, а готового инструмента под Go с поддержкой ClickHouse не нашлось ни одного. Пришлось написать свой — db-migrator. Со временем он оброс поддержкой Postgres, MySQL, а недавно и Iceberg, и разошёлся среди коллег по отрасли. В статье расскажу, чем миграции в ClickHouse отличаются от привычного Postgres/MySQL и какие инженерные развилки из-за этого пришлось пройти: ON CLUSTER для обычного реплицированного кластера, режим Replicated-базы, аккуратная таблица истории миграций на шардированном кластере и маскирование секретов в логах.
Инструмент: https://github.com/raoptimus/db-migrator.go

Цена запроса не зависела от того, что ищешь: фильтр стоял над GROUP BY. Теперь отсечение идёт до агрегата, на трёх движках, без единой правки в коде приложения. До 100 раз на диапазоне по дате и в 5,3 раза на полной выборке в MS SQL Server.
Есть класс проблем производительности, который не видно на маленьких данных и невозможно не заметить на больших. Наш выглядел так: запрос искал один редкий номер заказа среди сотни тысяч объектов ровно столько же, сколько поиск, не находящий ничего. Избирательность условия не влияла на время. Совсем.
Причина оказалась в форме сгенерированного SQL. Значения props живут построчно, и запрос сначала сворачивает их в широкую строку через GROUP BY, а уже потом применяет фильтр. Условие стояло над агрегатом, то есть фильтровало результат свёртки, а не колонку. Индексу там зацепиться не за что: к моменту проверки движок уже прочитал и свернул все значения всех объектов схемы. Триграммный индекс по строкам лежал без дела.
В 3.7.1 появился шаг, который ...

И так, что мы имеем и для чего же собственно эта статья? Когда человеку ставят задачу в духе «Придумай пароль» — он берет и генерирует самостоятельно некую псевдослучайную последовательность, что в будущем именуется паролем (или с помощью генераторов паролей, которые встроены во все популярные браузеры, или с помощью установленных утилит). Казалось бы, можно и так понять, что самые часто используемые слова в духе «мама», «папа», «пароль» и другие — вполне объяснимы. Это то, что нас в большинстве своем объединяет, а потому может намного чаще встречаться в паролях. Не все люди хотят заморачиваться и отказываться от простых и понятных аналогиях. На примере старшего поколения моей семьи (бабуле) могу хоть сколько раз подтвердить, что ее излюбленный пароль был именем дочери и годом ее рождения.
А ведь в таких псевдо случайных генерациях можно встретить «проблему раскладки» (то, что проанализировано было в русском сегменте только в 2025 году следующими лицами: Леа Мюллер, Аушриус Юозапавичюс, Владимир Охримчук, Стефан Зюттерлин в работе «Поиск в словаре с использованием преобразованных русских слов на клавиатуре QWERTY», P. S. я мог допустить ошибки в переводе информации, за что прошу прощения). Если кратко, то это создает некую «маску», зная которую можно облегчить взлом. Подобные словари встречаются в открытом доступе, и еще чаще встречаются в недоброжелательном сообществе за разные суммы денег.

Задача звучала как задача из учебника: перенести кредитный домен банка с Oracle на PostgreSQL. 70+ таблиц, чуть больше терабайта данных, 500–3000 RPS на чтение и 50–300 на запись в пике. Одно ограничение: система обслуживает клиентов и не может остановиться. Ни на ночь, ни на выходные, ни «на 15 минут на переключение».
Эта статья — не туториал «как мигрировать за 10 шагов». Таких на Хабре десятки, и половина из них сводится к «запустите ora2pg». Здесь — список мест, где у нас всё ломалось, в порядке от «это все знают, но всё равно наступают» до «об этом мы узнали за неделю до переключения».
Если вы планируете такую миграцию, читайте как чеклист. Если уже прошли — сверьте, сколько совпало.
Дисклеймер: проект под NDA, поэтому названия, точные объёмы и часть деталей изменены. Порядок величин и сами проблемы — настоящие.

Когда впервые пишешь собственную интеграцию с amoCRM через REST API, сами запросы к сделкам, контактам или компаниям обычно оказываются не самой сложной частью.
Основной вопрос возникает раньше:
как один раз авторизовать интеграцию, а затем поддерживать доступ к amoCRM без постоянного ручного получения ключей?
1-2 года назад я реализовывал такую интеграцию на PHP. Токены хранили в MySQL, а работу с OAuth разбили на несколько отдельных файлов.
Сейчас решил восстановить общую архитектуру этой реализации.
Если убрать детали, OAuth-интеграция выглядит довольно просто:
Authorization Code → Access Token + Refresh Token → сохранение в БД → запросы к REST API → обновление токенов → повторное сохранение в БД.
Код авторизации берется в AmoCRM:
Привет!
Заметка о правильности названий ETL процессов. Расставим точки над i.
Всегда было же нормально, коротко и звучно ETL. Теперь все чаще мелькает ELT, ETLT, EtLT.
Традиционный паттерн ETL, применяет бизнес-логику во время преобразования, до загрузки в хранилище. Выбрал данные, преобразовал, положил в хранилище. ELT меняет эту последовательность, сначала загружая сырые данные в хранилище, а преобразование выполняет уже внутри. ELT подход сокращает нагрузку на систему источник, позволяет итеративно совершенствовать логику преобразования. Имеем два противоположных метода.
Но мы то с вами знаем, что на проектах, в жизни оба метода применяются одновременно. Более того, они могут одновременно применяться в одном потоке. Выбрал данные, преобразовал, положил в хранилище на первый уровень, преобразовал и положил на второй уровень.
Например, в потоке выполняется экстракция из базы данных, непосредственно при выборке происходят предварительные преобразования (отсечение миллисекунд у столбца времени), далее загрузка в цель - выполнился процесс ETL. Вторым этапом идут бизнес преобразования - процесс T, а вместе ETLT.
Таким образом и получается, что в большинстве случаев используется процесс ETLT, но исторически так сложилось называть все подобные процесcы просто и звучно ETL.
В аббревиатуре первая трансформация обозначается маленькой первой буквой t, и это не случайно. На данном шаге выполняются только предварительные преобразования данных: очистка, приведение типов. А вот уже вторая - это полноценная трансформация: бизнес преобразования, обогащения, расчеты и тд. Еще я встречал проставление индексов к буквам трансформаций ET1LT2.
Так же есть такое понятие как ETL++, но об этом в другой раз :-)

У Jira есть REST API, есть JQL, есть маркетплейс с дашбордами. Но как только метрики становятся чуть сложнее, чем «сколько задач закрыто за спринт», всё это упирается в потолок:
Мы в отделе поспорили, как подключать LLM к базе на 253 таблицы: MCP-инструменты или схема в промте. Собрали бенчмарк на 29 реальных вопросах аналитиков и померили три подхода по execution accuracy, деньгам и латентности. Победил вариант, за который не топил никто, а больше всех ошибался составитель бенчмарка: трижды, и один раз его поправила испытуемая модель. Внутри: таблицы с цифрами, четыре дефекта харнесса, которые выдавали правдоподобные числа вместо падений, и почему семантика, живущая в коде, — потолок любого подхода.