11-- +goose Up
2- -- Search v2 keeps the dedicated event-time search boundary, but stores only bounded,
3- -- normalized searchable text and fields needed by the list. The materialized view is
4- -- intentionally forward-only. Any historical backfill must be run as a separate,
5- -- throttled operation.
2+ -- Search v2 stores bounded normalized text outside the task_events_v2 insert path.
3+ -- The source index supports closed projector windows on newly written parts.
4+ ALTER TABLE trigger_dev .task_events_v2
5+ ADD INDEX IF NOT EXISTS idx_inserted_at_projector inserted_at TYPE minmax GRANULARITY 1 ;
6+
67CREATE TABLE IF NOT EXISTS trigger_dev .task_events_search_v2
78(
89 environment_id String,
@@ -22,63 +23,29 @@ CREATE TABLE IF NOT EXISTS trigger_dev.task_events_search_v2
2223 status LowCardinality(String) CODEC(ZSTD(1 )),
2324 duration UInt64 CODEC(ZSTD(1 )),
2425 parent_span_id String CODEC(ZSTD(1 )),
26+ projection_fingerprint UInt128 DEFAULT reinterpretAsUInt128(
27+ sipHash128(trace_id, span_id, run_id, start_time)
28+ ),
2529
2630 INDEX idx_run_id run_id TYPE bloom_filter(0 .001 ) GRANULARITY 1 ,
2731 INDEX idx_search_text search_text
2832 TYPE text (tokenizer = ' ngrams' , preprocessor = lowerUTF8(search_text))
2933)
30- ENGINE = MergeTree
34+ ENGINE = ReplacingMergeTree
3135PARTITION BY toDate(triggered_timestamp)
32- ORDER BY (organization_id, environment_id, triggered_timestamp, trace_id, span_id)
33- TTL toDateTime(triggered_timestamp) + INTERVAL 90 DAY
34- SETTINGS ttl_only_drop_parts = 1 ;
35-
36- CREATE MATERIALIZED VIEW IF NOT EXISTS trigger_dev .task_events_search_mv_v2
37- TO trigger_dev .task_events_search_v2 AS
38- SELECT
39- environment_id,
36+ ORDER BY (
4037 organization_id,
41- project_id,
42- least(
43- fromUnixTimestamp64Nano(toUnixTimestamp64Nano(start_time) + toInt64(duration)),
44- now64(9 ) + INTERVAL 5 MINUTE
45- ) AS triggered_timestamp,
38+ environment_id,
39+ triggered_timestamp,
4640 trace_id,
4741 span_id,
48- run_id,
49- task_identifier,
50- start_time,
51- inserted_at,
52- message,
53- substring (JSONExtractString(attributes_text, ' error' , ' message' ), 1 , 2048 ) AS error_message,
54- replaceRegexpAll(
55- lowerUTF8(
56- substring (
57- concat(
58- substring (message, 1 , 2048 ),
59- ' ' ,
60- replaceAll(substring (attributes_text, 1 , 6144 ), ' \\ /' , ' /' )
61- ),
62- 1 ,
63- 8192
64- )
65- ),
66- ' [^\\ p{L}\\ p{N}_./:@+-]+' ,
67- ' '
68- ) AS search_text,
69- kind,
70- status,
71- duration,
72- parent_span_id
73- FROM trigger_dev .task_events_v2
74- WHERE
75- trace_id != ' '
76- AND kind != ' DEBUG_EVENT'
77- AND status != ' PARTIAL'
78- AND NOT (kind = ' SPAN_EVENT' AND attributes_text = ' {}' )
79- AND kind != ' ANCESTOR_OVERRIDE'
80- AND message != ' trigger.dev/start' ;
42+ projection_fingerprint
43+ )
44+ TTL toDateTime(triggered_timestamp) + INTERVAL 90 DAY
45+ SETTINGS ttl_only_drop_parts = 1 ;
8146
8247-- +goose Down
83- DROP VIEW IF EXISTS trigger_dev .task_events_search_mv_v2 ;
8448DROP TABLE IF EXISTS trigger_dev .task_events_search_v2 ;
49+
50+ ALTER TABLE trigger_dev .task_events_v2
51+ DROP INDEX IF EXISTS idx_inserted_at_projector;
0 commit comments