Заказы разложены по своему ключу шардирования, и шаг разбора дефект больше не воспроизводит. Закрывает #137.
Механизм
Семантика parallel_distributed_insert_select сверена по Context7 и по system.settings живой ноды 26.3.17 (совпали): 0 — выключено, 1 — SELECT на каждом шарде, 2 — SELECT и INSERT на каждом шарде; заводское — 2. В обе вставки sql/ods/order_parse.sql добавлен явный 0 с доводом комментарием: вставку исполняет инициатор и раскладывает строки по ключу цели.
Данные
Сырьё было полно (одна порция, все 1662 заказа), поэтому адресная очистка: TRUNCATE ods.order_rep и ods.order_errors_rep ON CLUSTER, затем повторный разбор той же порции тем же шагом.
до
после
после следующего слепка
межшардовые дубли
1189
0
0
uniqExact(order_id)
1662
1662
1917
count() по order_dist
2851
1662
3356
Вершина версий сверена не «до/после», а с эталоном из сырья: деловые поля ods.order_v совпали с argMax по updated_at построчно, 0 расхождений. Следующий модельный день прожит дагом world_next_day, слепок принят уже с новой настройкой — дублей 0. make smoke 21/0, make check-clickhouse 10/10.
Попутная находка (закрыта документацией в этом же PR)
У заказа, не менявшегося несколько дней, вершина версий приезжает в нескольких слепках побайтово одинаковыми строками, и какая переживёт схлопывание — не обещано: snapshot_date выжившей строки — один из дней наблюдения, не обязательно последний (у 86 заказов стартового мира выжил серединный). Данные целы: во всех 3034 парах с равным updated_at деловые поля совпали побайтово, монотонность updated_at по слепкам без нарушений. Семантика записана в orders/ingestion.md и комментарии DDL; допущение «уточнение поднимает updated_at» названо допущением. Механические защиты (составная версия, сортировка вставки, удаление колонки) отклонены как несоразмерные — довод в той же правке.
Заказы разложены по своему ключу шардирования, и шаг разбора дефект больше не воспроизводит. Закрывает #137.
## Механизм
Семантика `parallel_distributed_insert_select` сверена по Context7 и по `system.settings` живой ноды 26.3.17 (совпали): `0` — выключено, `1` — `SELECT` на каждом шарде, `2` — `SELECT` и `INSERT` на каждом шарде; заводское — `2`. В обе вставки `sql/ods/order_parse.sql` добавлен явный `0` с доводом комментарием: вставку исполняет инициатор и раскладывает строки по ключу цели.
## Данные
Сырьё было полно (одна порция, все 1662 заказа), поэтому адресная очистка: `TRUNCATE ods.order_rep` и `ods.order_errors_rep ON CLUSTER`, затем повторный разбор той же порции тем же шагом.
| | до | после | после следующего слепка |
|---|---|---|---|
| межшардовые дубли | 1189 | 0 | 0 |
| uniqExact(order_id) | 1662 | 1662 | 1917 |
| count() по order_dist | 2851 | 1662 | 3356 |
Вершина версий сверена не «до/после», а с эталоном из сырья: деловые поля `ods.order_v` совпали с `argMax` по `updated_at` построчно, 0 расхождений. Следующий модельный день прожит дагом `world_next_day`, слепок принят уже с новой настройкой — дублей 0. `make smoke` 21/0, `make check-clickhouse` 10/10.
## Попутная находка (закрыта документацией в этом же PR)
У заказа, не менявшегося несколько дней, вершина версий приезжает в нескольких слепках побайтово одинаковыми строками, и какая переживёт схлопывание — не обещано: `snapshot_date` выжившей строки — один из дней наблюдения, не обязательно последний (у 86 заказов стартового мира выжил серединный). Данные целы: во всех 3034 парах с равным `updated_at` деловые поля совпали побайтово, монотонность `updated_at` по слепкам без нарушений. Семантика записана в `orders/ingestion.md` и комментарии DDL; допущение «уточнение поднимает updated_at» названо допущением. Механические защиты (составная версия, сортировка вставки, удаление колонки) отклонены как несоразмерные — довод в той же правке.
- Зачем:
- заводское parallel_distributed_insert_select = 2 исполняло вставку из
Distributed в Distributed локально на каждом шарде, минуя ключ цели:
1189 из 1662 заказов задвоились на обоих шардах, а ReplacingMergeTree
через границу шарда дубли не схлопывает.
- Что:
- в обе вставки sql/ods/order_parse.sql добавлено явное
parallel_distributed_insert_select = 0 с доводом комментарием.
- в docs/architecture/storage.md описан капкан «INSERT из Distributed в
Distributed при несовпадающих ключах» и записана проверка (#137).
- Проверка:
- межшардовые дубли по ods.order_rep дают 0 (было 1189), каждый шард
держит только свои ключи; uniqExact(order_id) не изменился.
- после прожитого дага world_next_day новый слепок принят, дублей
по-прежнему 0.
- make smoke, make check-clickhouse.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- проверка #137 показала: у заказа, не менявшегося несколько дней, версию
выбирает только updated_at, и какая из одинаковых строк переживёт
схлопывание — не обещано; snapshot_date выжившей строки означал не то,
что обещала документация (у 86 заказов стартового мира выжил серединный
день наблюдения).
- Что:
- в docs/architecture/orders/ingestion.md записано: snapshot_date, _load_id
и _load_ts выжившей строки — координаты одного из наблюдений версии, не
обязательно последнего; допущение «уточнение поднимает updated_at»
названо допущением с границей применимости.
- та же оговорка — в комментарии DDL ods.order_rep.
- Проверка:
- замеры на живом стенде: во всех 3034 парах строк с равным updated_at
деловые поля совпали побайтово; монотонность updated_at по слепкам —
без нарушений; ods.order_v сошёлся с эталоном argMax из сырья построчно.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Зачем:
- правки #137 дважды рассказывали одно и то же: механика капкана жила и в
storage.md, и у вставок, а цифры замеров — и в прозе, и в леджере;
у читателя это спрашивает больше внимания, чем даёт.
- Что:
- комментарии у вставок order_parse.sql сжаты до довода с указателем на
storage.md; из капкана в storage.md цифры ушли в «Что проверено»;
в ingestion.md замеры перенесены из прозы в свой раздел «Что проверено».
- Проверка:
- рендер order_parse.sql по-прежнему делится ровно на два запроса
(из комментария убрана точка с запятой, по которой оператор делит файл).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ddmitry
merged commit 544e500dc8 into main2026-08-22 11:38:57 +03:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Заказы разложены по своему ключу шардирования, и шаг разбора дефект больше не воспроизводит. Закрывает #137.
Механизм
Семантика
parallel_distributed_insert_selectсверена по Context7 и поsystem.settingsживой ноды 26.3.17 (совпали):0— выключено,1—SELECTна каждом шарде,2—SELECTиINSERTна каждом шарде; заводское —2. В обе вставкиsql/ods/order_parse.sqlдобавлен явный0с доводом комментарием: вставку исполняет инициатор и раскладывает строки по ключу цели.Данные
Сырьё было полно (одна порция, все 1662 заказа), поэтому адресная очистка:
TRUNCATE ods.order_repиods.order_errors_rep ON CLUSTER, затем повторный разбор той же порции тем же шагом.Вершина версий сверена не «до/после», а с эталоном из сырья: деловые поля
ods.order_vсовпали сargMaxпоupdated_atпострочно, 0 расхождений. Следующий модельный день прожит дагомworld_next_day, слепок принят уже с новой настройкой — дублей 0.make smoke21/0,make check-clickhouse10/10.Попутная находка (закрыта документацией в этом же PR)
У заказа, не менявшегося несколько дней, вершина версий приезжает в нескольких слепках побайтово одинаковыми строками, и какая переживёт схлопывание — не обещано:
snapshot_dateвыжившей строки — один из дней наблюдения, не обязательно последний (у 86 заказов стартового мира выжил серединный). Данные целы: во всех 3034 парах с равнымupdated_atделовые поля совпали побайтово, монотонностьupdated_atпо слепкам без нарушений. Семантика записана вorders/ingestion.mdи комментарии DDL; допущение «уточнение поднимает updated_at» названо допущением. Механические защиты (составная версия, сортировка вставки, удаление колонки) отклонены как несоразмерные — довод в той же правке.- Зачем: - заводское parallel_distributed_insert_select = 2 исполняло вставку из Distributed в Distributed локально на каждом шарде, минуя ключ цели: 1189 из 1662 заказов задвоились на обоих шардах, а ReplacingMergeTree через границу шарда дубли не схлопывает. - Что: - в обе вставки sql/ods/order_parse.sql добавлено явное parallel_distributed_insert_select = 0 с доводом комментарием. - в docs/architecture/storage.md описан капкан «INSERT из Distributed в Distributed при несовпадающих ключах» и записана проверка (#137). - Проверка: - межшардовые дубли по ods.order_rep дают 0 (было 1189), каждый шард держит только свои ключи; uniqExact(order_id) не изменился. - после прожитого дага world_next_day новый слепок принят, дублей по-прежнему 0. - make smoke, make check-clickhouse. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>