Skip to content

Schema migrations - #522

Draft
aagbsn wants to merge 3 commits into
schema_sql_current_statefrom
schema_migrations
Draft

aagbsn wants to merge 3 commits into
schema_sql_current_statefrom
schema_migrations

Conversation

@aagbsn

@aagbsn aagbsn commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Adds a base schema (current state), a migrations directory for changes to prod, and a script that ensures they stay in sync. schema.sql will be used for ooni/backend's CI fixtures, so that there is a single source of truth for database tables. Related is #520, for backing up (soon, also restoring from) clickhouse backups. For handling of some tables, e.g. the EmbeddedRocksDB types, this is convoluted, so migrating them to replicated types is desirable.

schema.sql stays the schema as it is now. A change to an existing cluster
goes in a numbered file in migrations/, applied once, in order, on one node.
000_baseline.sql is schema.sql as of this PR and is never edited; the
README says how to run, document and record a migration. schema.sql's
header points to it.
test/check.sh starts a one-node oonidata_cluster with Keeper at production's
version (24.8.6.70), loads schema.sql into one database and every migration,
in order, into another, and compares each table's definition and Keeper path
with the database name and UUIDs blanked. It takes about 10 seconds. CI runs
it when schema.sql, the migrations, the test or the workflow change.

It fails when a migration is missing, and when schema.sql changes without
one: both checked by hand before this commit.
The view kept its rows in a hidden table, .inner_id.<uuid>, sorted by
(probe_cc, probe_asn, input). It's a SummingMergeTree, so merges add up the
weeks of each key and keep one arbitrary week. Its reader, ooniprobe's
test-list/urls (common/prio.py), sums the current and previous week, so it
misses every count whose merged row says an older week, which in production
is most of them. Tested on 24.8: 2 rows from last week and 5 from this one
merge into one row of 7 that says last week.

The view now writes TO counters_asn_test_list_data, sorted by (probe_cc,
probe_asn, input, week), with a plain {database} Keeper path. It keeps its
name and column types, so the reader's query doesn't change. The table is
backed up and restored by name, like any other table, by the
clickhouse_backup role's "*" job; the view's backup holds only its
definition. Restore the table before the view: a view restored without its
table makes every insert into fastpath fail.

Migration 001 does it in production. The old rows are wrong, so it doesn't
copy them: it counts the two weeks the reader uses again from fastpath, from
the rows inserted before the new view existed (fastpath's update_time), and
the new view counts the rest. That also counts uploads that came more than
8 days late, which the view leaves out. It isn't a mutation. Queries on the
view fail between the DROP and the RENAME, for about a second; from then on
test-list/urls gets the corrected counts.

Tested on a two-node 24.8.6.70 cluster set up like production (the view on
one node, its rows already merged): the weeks come out right, a late upload
is counted once, later inserts are counted once on both nodes, and
test/check.sh passes.
@aagbsn
aagbsn marked this pull request as draft October 23, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant