Skip to content

Commit e75cf4b

Browse files
chore: update documentation
1 parent 203a908 commit e75cf4b

2 files changed

Lines changed: 48 additions & 51 deletions

File tree

omod/src/main/resources/_etl/derived/follow_up/README.md

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ That arrangement had three problems:
2222

2323
This folder solves all three: the table is named `mamba_fact_follow_up` (peer of
2424
`mamba_fact_client` and `mamba_fact_location_*`), the rebuild is a clean
25-
DROP+rebuild on every ETL run, and the layout is replicated mechanically for
26-
the other 8 forms.
25+
blue-green (staging + atomic rename) rebuild on every ETL run, and the layout
26+
is replicated mechanically for the other 8 forms.
2727

2828
## Layout
2929

@@ -32,7 +32,6 @@ follow_up/
3232
├── README.md this file
3333
├── sp_makefile lists sp_data_processing_derived_follow_up.sql
3434
├── sp_data_processing_derived_follow_up.sql entry-point called by sp_mamba_data_processing_etl
35-
├── sp_compress_follow_up_flat_tables.sql post-create compression for the 10 source flat tables
3635
└── facts/
3736
└── follow_up/
3837
├── sp_makefile lists the 3 SP files below
@@ -46,77 +45,75 @@ since the materialization is always full-rebuild, there is no separate
4645
`_update.sql` for delta refresh. (The original `_update.sql` was reverted —
4746
see "Full rebuild on every run" below.)
4847

49-
## Full rebuild on every run
48+
## Full rebuild on every run (blue-green)
5049

5150
The entry-point `sp_data_processing_derived_follow_up` performs a full rebuild
52-
of `mamba_fact_follow_up` on every ETL run:
53-
54-
1. `DROP TABLE IF EXISTS mamba_fact_follow_up` — always, regardless of mode
55-
2. `CALL sp_fact_follow_up()` — creates the table (with `ROW_FORMAT=COMPRESSED
56-
KEY_BLOCK_SIZE=8`) and populates it via `TRUNCATE` + 10-way LEFT JOIN INSERT
57-
3. `CALL sp_compress_follow_up_flat_tables()` — re-applies compression to the
58-
10 source flat tables and the new materialization (idempotent metadata-only
59-
change on already-compressed tables)
51+
of `mamba_fact_follow_up` on every ETL run, using a blue-green (staging +
52+
atomic swap) strategy so the live table stays available with old data for
53+
the whole rebuild:
54+
55+
1. `DROP TABLE IF EXISTS mamba_fact_follow_up_staging` — clean up any leftover
56+
staging table from a previously aborted run.
57+
2. `CALL sp_fact_follow_up()` — creates `mamba_fact_follow_up_staging` (with
58+
`ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8`) and populates it via `TRUNCATE`
59+
+ 10-way LEFT JOIN INSERT. The live `mamba_fact_follow_up` is untouched
60+
and fully queryable throughout this step.
61+
3. `DROP TABLE IF EXISTS mamba_fact_follow_up_old` — guard against a
62+
pre-existing `_old` table left by a previously crashed run.
63+
4. Atomic `RENAME TABLE mamba_fact_follow_up TO mamba_fact_follow_up_old,
64+
mamba_fact_follow_up_staging TO mamba_fact_follow_up` — readers see either
65+
the fully old or fully new table, never a partial rebuild. The archived
66+
`_old` table is dropped immediately after.
6067

6168
**Why full rebuild instead of incremental:**
6269

6370
- ETL is user-triggered (after data changes), not a high-frequency timer.
6471
- The user expects a known-correct state after each run, with no drift and
6572
no dependence on a `_mamba_etl_schedule` watermark.
66-
- The performance cost is acceptable: a 10-way JOIN over 5M rows + 10
67-
idempotent `ALTER TABLE` statements takes ~5–10 seconds on a typical
68-
8 GB / HDD box. Within the headroom of a 5-minute ETL schedule.
69-
- Compression keeps the disk footprint small and the I/O bounded.
73+
- The performance cost is acceptable: a 10-way JOIN over 5M rows takes
74+
~5–10 seconds on a typical 8 GB / HDD box. Within the headroom of a
75+
5-minute ETL schedule.
76+
- Blue-green keeps the live table queryable throughout, instead of dropping
77+
it up front and leaving a "table not found" gap for the duration of the
78+
rebuild.
7079

7180
**Behavior change from the previous incremental design:**
7281

7382
- The `sp_fact_follow_up_update.sql` (delta refresh) was deleted. It is
7483
no longer called from any SP.
7584
- The wrapper `sp_fact_follow_up.sql` lost its `etl_incremental_mode`
76-
parameter and the IF/ELSE branch. It always calls `_create` then `_insert`.
77-
- The entry-point `sp_data_processing_derived_follow_up.sql` always does
78-
`DROP TABLE IF EXISTS mamba_fact_follow_up` (no mode gating).
85+
parameter and the IF/ELSE branch. It always calls `_create` then `_insert`,
86+
building into `mamba_fact_follow_up_staging`.
87+
- The entry-point `sp_data_processing_derived_follow_up.sql` no longer drops
88+
the live table up front — it drops leftover staging/`_old` tables, builds
89+
staging, then does the atomic rename swap described above.
7990
- The `etl_incremental_mode` parameter is kept in the entry-point's
8091
signature for backward compatibility with the call site in
8192
`sp_mamba_data_processing_etl`, but is intentionally ignored.
8293

8394
## Compression
8495

85-
Both `mamba_fact_follow_up` and the 10 source flat tables are configured with
86-
`ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8`. This applies to deployments on both
87-
small (8 GB / HDD) and large (powerful) machines — the trade is cheap CPU for
88-
less I/O, which is the right trade on either profile.
89-
90-
### How compression is applied
91-
92-
- **`mamba_fact_follow_up`**: created with `ROW_FORMAT=COMPRESSED
93-
KEY_BLOCK_SIZE=8` in `sp_fact_follow_up_create.sql`. Idempotent via
94-
`CREATE TABLE IF NOT EXISTS`.
95-
- **The 10 source flat tables**: the core (separate repo) creates them as
96-
default `ROW_FORMAT=DYNAMIC` via `sp_mamba_flat_encounter_table_create`.
97-
We can't change that from this repo, so we re-apply compression via
98-
`sp_compress_follow_up_flat_tables.sql`, called from the entry-point
99-
after the materialization runs. The 10 `ALTER TABLE` statements are
100-
idempotent: on an already-compressed table MySQL 8 performs a
101-
metadata-only change (no rewrite); on an uncompressed table it rewrites
102-
the table once.
96+
`mamba_fact_follow_up` (built as `mamba_fact_follow_up_staging`, then renamed
97+
into place) is created with `ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8` in
98+
`sp_fact_follow_up_create.sql`, idempotent via `CREATE TABLE IF NOT EXISTS`.
99+
The trade is cheap CPU for less I/O on both small (8 GB / HDD) and large
100+
deployments.
101+
102+
The 10 source flat tables (`mamba_flat_encounter_follow_up`, `_1``_9`) are
103+
**not** compressed by this repo. They're created by the core
104+
(`sp_mamba_flat_encounter_table_create`, separate repo) with the default
105+
`ROW_FORMAT=DYNAMIC`, and we can't change that from here. An earlier version
106+
of this folder re-applied compression to those 10 tables via
107+
`sp_compress_follow_up_flat_tables.sql`, called from the entry-point after
108+
the materialization ran — that SP has been removed; only the materialized
109+
fact table itself is compressed now.
103110

104111
### Why `KEY_BLOCK_SIZE=8` and not 4 or 16
105112

106113
- `KEY_BLOCK_SIZE=4`: ~70% compression, ~20% CPU, more risk of compression failures on busy pages
107114
- `KEY_BLOCK_SIZE=8`: ~55% compression, ~10% CPU — sweet spot for HDD
108115
- `KEY_BLOCK_SIZE=16`: ~30% compression, ~5% CPU — marginal win over DYNAMIC
109116

110-
### What about existing deployments
111-
112-
This folder assumes a fresh deploy: the next ETL run that hits the
113-
full-rebuild path will produce compressed tables. For an existing
114-
deployment with >5 GB of uncompressed data already on disk, run a
115-
one-time `ALTER TABLE mamba_flat_encounter_follow_up[_1.._9]
116-
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8` on each of the 10 flat tables
117-
during a maintenance window. The compression cost is ~minutes per
118-
GB on HDD.
119-
120117
## Known limitations (out of scope)
121118

122119
- **Drift correction** — the full-rebuild model makes this moot. Every

omod/src/main/resources/_etl/derived/follow_up/facts/follow_up/sp_fact_follow_up.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
-- Wrapper for the follow-up materialization.
22
-- Always performs a full rebuild: _create (idempotent CREATE TABLE)
3-
-- followed by _insert (TRUNCATE + 10-way LEFT JOIN INSERT).
4-
-- The table is dropped by sp_data_processing_derived_follow_up
5-
-- before this wrapper is called, so the wrapper is responsible only
6-
-- for the create-then-populate sequence.
3+
-- followed by _insert (TRUNCATE + 10-way LEFT JOIN INSERT), both against
4+
-- mamba_fact_follow_up_staging. The live mamba_fact_follow_up table is
5+
-- left untouched by this wrapper; sp_data_processing_derived_follow_up
6+
-- swaps staging into place with an atomic RENAME after this call returns.
77
DELIMITER //
88

99
DROP PROCEDURE IF EXISTS sp_fact_follow_up;

0 commit comments

Comments
 (0)