Skip to content

feat: add point dimension tables and backfill jobs - #3375

Open
Freika wants to merge 2 commits into
devfrom
feat/points-dimensions
Open

feat: add point dimension tables and backfill jobs#3375
Freika wants to merge 2 commits into
devfrom
feat/points-dimensions

Conversation

@Freika

@Freika Freika commented Aug 17, 2026

Copy link
Copy Markdown
Owner

What

First slice of the points normalization (Release C of the storage plan; follows #3359/#3360/#3368). Adds the two dimension tables and the backfills — no read-path or ingest changes yet.

  • point_sources — deduplicates the nine device/importer combo columns (tracker_id, topic, ssid, bssid, connection, trigger, battery_status, inrids, in_regions). Measured on a 1.6M-point dataset these collapse to ~200 distinct rows.
  • point_motions — deduplicates motion_data payloads (~18× dedup measured).
  • Both dedup via a digest unique index (md5(jsonb::text), computed in SQL so every writer produces identical digests; jsonb output is canonical). A plain unique index on the jsonb is impossible — payloads can exceed the 2.7 kB btree row limit.
  • points gains nullable source_id / motion_id (int, metadata-only migration, instant). No FK constraints yet — they come with the rewrite.
  • Backfills (data_migrations queue, auto-enqueued on upgrade, SKIP_POINT_DIMENSION_BACKFILL=1 to opt out): id-range batches of 50k with a 5s pause, self-re-enqueueing, resumable from any cursor, idempotent — seeding upserts by digest, stamping touches only NULL FKs. A second job resolves country_id from country_name (42% of rows are NULL) plus the legacy country column, never overwriting an existing value.
  • Drops idx_points_user_visit_null_timestamp (visit detection falls back to the consolidated unique index; verified with EXPLAIN).

Scoping

Ingest still writes only the legacy columns — the dual-write creators/importers and the read-path joins come in follow-up PRs before any legacy column is dropped. The backfill is re-runnable at any time to catch up rows created after its pass. Nothing user-visible changes.

Testing

  • 12 examples, 0 failures across both backfill jobs: combo dedup, digest sharing, gap-free stamping, idempotent re-runs, batch chaining, country resolution incl. legacy fallback and no-overwrite.
  • RuboCop clean; migrations run cleanly forward on a schema-loaded database.

Freika added 2 commits August 17, 2026 20:22
Introduce point_sources and point_motions reference tables that
deduplicate the device/importer combo columns and motion payloads
repeated on every point. Both dedup through an md5 digest computed in
SQL from canonical jsonb text, since motion payloads can exceed the
btree row limit for a plain unique index.

Backfill jobs walk points in id-range batches, seed the dimensions,
stamp source_id/motion_id, and resolve country_id from country_name and
the legacy country column. Both are resumable, idempotent, and enqueued
automatically on upgrade with an env escape hatch. Also drops the
visit-null partial index now that detection falls back to the
consolidated unique index.
Bound the ALTER TABLE lock wait with retries and hand off to a dedicated
job when the lock cannot be won, so boot never crash-loops on a busy
points table. Make the enqueue migration the single decision point for
starting the backfill chain, gate Cloud to manual scheduling, and own
the retry lifecycle in the backfill jobs with bounded lock and statement
timeouts. Stamp both dimensions in one UPDATE per batch instead of two,
guard dimension inserts against burning sequence values on repeats, and
chain the country backfill after the dimension walk finishes.
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 26e252ff-44bf-428c-b51c-4fff76d3e041

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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