fix(ods): заказы разложены по своему ключу шардирования

- Зачем:
  - заводское 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>
This commit is contained in:
ddadminandClaude Opus 5 committed 2026-08-22 04:02:52 -04:00
1 parent ea39982bdd
commit 8c76a7a0d8
2 files changed
+39 -2

No files matched your search

+16 -2
View File
@@ -92,7 +92,16 @@ SELECT
_load_ts
FROM stg.orders_raw_dist
WHERE _load_id = {load_id:String} AND row_is_valid
SETTINGS distributed_foreground_insert = 1;
-- Заводское значение parallel_distributed_insert_select — 2: вставку вида
-- INSERT ... SELECT из Distributed в Distributed на одном кластере ClickHouse
-- исполняет локально на каждом шарде, и строки минуют ключ шардирования цели.
-- Ключи здесь разные — сырьё разложено по хешу строки, заказы по
-- cityHash64(order_id), — так версии одного заказа и расползлись по обоим
-- шардам, где ReplacingMergeTree их уже не схлопывает. Ноль возвращает вставку
-- инициатору: он читает срез со всех шардов и пишет через ods.order_dist,
-- то есть по её ключу.
SETTINGS distributed_foreground_insert = 1,
parallel_distributed_insert_select = 0;
-- Брак: тот же срез и буквальное отрицание того же предиката.
--
@@ -118,4 +127,9 @@ SELECT
_load_ts
FROM stg.orders_raw_dist
WHERE _load_id = {load_id:String} AND NOT row_is_valid
SETTINGS distributed_foreground_insert = 1;
-- Тот же ноль, хотя здесь заводское значение раскладку не ломало: ключ у
-- ods.order_errors_dist — cityHash64(raw), тот же, что у сырья, и локальная
-- запись попадала бы в свой шард сама. Совпадение ключей не гарантия:
-- поменяется ключ любой из двух таблиц — и строки разъедутся молча.
SETTINGS distributed_foreground_insert = 1,
parallel_distributed_insert_select = 0;