Зачем: - Дать слою расчётную сущность, которой в потоке нет: стенд режет визиты сам, а VisitID генератора остаётся эталоном самопроверки. - Отделить прожитый день от живого — иначе визит, начатый в 23:50, замёрз бы обрезанным навсегда: пересобирать замёрзший день слой не станет. Что: - Добавлены dds.session_rep/_dist, двойник-донор dds.session_stage_rep/_dist и публичный договор dds.session_v. - Нарезка стоит на двух окнах: первое ставит шов там, где пауза длиннее тридцати минут, второе считает нарастающий итог швов — номер визита. Границу суток держит разбиение окна, отдельной проверки ей не нужно. - Порядок в окнах полный, по метке времени и event_id: сортировок две, и при равных метках они разошлись бы, разорвав сессию надвое. - Объём прогона считается от первой дыры в слое по последний прожитый день; прожитый день выводится из позиции мира и первого дня событий. Собирать нечего — группа задач пропускается, а не зеленеет впустую. - В dds_transform появилась группа session рядом с заказом; зависимости по данным между ними нет. - Потолок max_active_tasks: размноженная замена без него выносит планировщика за отведённые ему 640 МиБ. - parallel_distributed_insert_select у сессий не назначается вслух — ключ шардирования у источника и цели один по контракту ко-локации. - Записано, что позиция отвечает за «прожит», а не за «доехал»: сторож хвоста потока приезжает отдельным тикетом. Проверка: - make lint - make smoke (21 проверка), make check-clickhouse (10), make check-services - Стартовый мир, пересобранный с нуля: 79367 сессий за восемь дней; расхождение с uniqExact(VisitID) по паре «кука × день» — ноль; все 401185 событий ровно в одной сессии; session_id уникальны. - Ни одной паузы длиннее тридцати минут внутри сессии и ни одной пары соседних визитов куки, разделённой меньшим промежутком. - Повтор после DROP PARTITION ALL: те же session_id и то же содержимое строк. - Снесённая руками партиция 2026-06-04: следующий прогон взял хвост от неё, дни до дыры не тронуты. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
12 lines
967 B
SQL
12 lines
967 B
SQL
-- DDS: подмена одного дня сессий собранной партицией двойника.
|
|
--
|
|
-- Механика и доводы целиком — sql/dds/order_replace.sql: замена идёт по
|
|
-- локальным таблицам, шард за шардом, атомарность пошардовая, день
|
|
-- подставляет Jinja, потому что параметров ALTER … PARTITION не берёт.
|
|
--
|
|
-- Разница одна, и она про отказ. Несобранный день заказа вернуло бы в работу
|
|
-- следующее окно; сессиям возвращать нечем, и упавшая замена оставляет дыру
|
|
-- до тех пор, пока её не найдёт счёт хвоста (sql/dds/session_scope.sql).
|
|
ALTER TABLE dds.session_rep ON CLUSTER clickstream_cluster
|
|
REPLACE PARTITION '{{ params.day }}' FROM dds.session_stage_rep;
|