Skip to content

Commit eca7430

Browse files
authored
Update v4 migration docs (#123)
Signed-off-by: nscuro <nscuro@protonmail.com>
1 parent 45273ff commit eca7430

2 files changed

Lines changed: 88 additions & 19 deletions

File tree

docs/guides/administration/migrating-from-v4.md

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,12 @@ v4-migrator verify \
161161

162162
`verify` reads but never writes. On a freshly bootstrapped target with no staging present, expect:
163163

164-
- Schema version `202605111028` reported `OK`.
164+
- Flyway head `202605111028` reported `OK`.
165165
- All row count columns **except for the v5 `PERMISSION` table** zero.
166166
- No probe entries.
167+
- The terminator line `== verify complete ==`.
168+
169+
At this stage the migration has not moved any data, so `verify` shows the seeded baseline with nothing to flag.
167170

168171
### 3. Dry run
169172

@@ -239,23 +242,44 @@ It now reports source / staging / v5 row counts per table and surfaces every pro
239242

240243
```text
241244
[Schema]
242-
OK Schema version = 202605111028
245+
OK Flyway head = 202605111028
243246
244247
[Row counts]
245-
Table Source Staging v5
248+
Table Source Staging v5 Note
246249
LICENSE 5234 5234 5234
247-
TEAM 47 42 42
250+
TEAM 47 42 42 expected: dedup by NAME (-5)
251+
COMPONENT 4823714 4823711 4823711 see [Probes] (-3)
252+
PROJECTS_TAGS 12480 12462 12462 reduction (-18), see migration guide
248253
...
249254
250255
[Probes]
251-
LICENSE 3 malformed UUID(s) dropped
256+
COMPONENT 3 malformed UUID(s) dropped
252257
253258
[Constraints]
254259
18 CHECK constraint(s) hold across 6 loaded table(s)
260+
261+
== verify complete ==
255262
```
256263

257-
Investigate any mismatch where you do not expect dedup or skipping.
258-
The lossy changes section below lists the expected sources of mismatch.
264+
The `Note` column annotates tables whose row count drops from source to v5.
265+
Row counts often decrease during migration because of deduplication, filtering, and retention.
266+
The migrator makes these reductions intentionally. The `Note` (and the `[Probes]` section) tells you which
267+
reason applies, so you can confirm what accounts for each drop rather than leaving it unexplained.
268+
Each note is one of three states:
269+
270+
- `expected: <reason> (-N)`. A known, intentional reduction. The reason maps to a transform in the
271+
[Lossy and non-obvious changes](#lossy-and-non-obvious-changes) section.
272+
- `see [Probes] (-N)`. The `[Probes]` section itemizes the drop (invalid UUIDs, skipped users, case collisions).
273+
- `reduction (-N), see migration guide`. An intentional reduction without a dedicated note.
274+
Consult the [Lossy and non-obvious changes](#lossy-and-non-obvious-changes) section to understand it.
275+
276+
!!! warning "Permission join tables are not a data-loss signal"
277+
278+
`TEAMS_PERMISSIONS` and `USERS_PERMISSIONS` both lose and gain rows as part of the v4-to-v5 permission remap
279+
(see [Portfolio access control bypass](#portfolio-access-control-bypass)), so their row-count delta carries no meaning.
280+
Disregard any `Note` on these two tables.
281+
282+
The final `== verify complete ==` line marks a clean exit. Its absence means `verify` stopped before finishing.
259283

260284
### 7. Drop staging
261285

@@ -451,7 +475,7 @@ INFO -> LICENSE: 5231 rows in 27 ms (193740 rows/s)
451475
```
452476

453477
The load phase additionally emits a heartbeat every 5 seconds while a single table is still running,
454-
so large tables stay visible even when the underlying `INSERT … SELECT` has not yet committed:
478+
so large tables stay visible:
455479

456480
```text
457481
INFO Loading COMPONENT into v5
@@ -460,11 +484,40 @@ INFO .. COMPONENT: still loading after 30s (expected 4823714 rows)
460484
INFO -> COMPONENT: 4823714 rows in 32104 ms (150253 rows/s)
461485
```
462486

463-
The expected count comes from the staging `tgt_*` row count and is an upper bound
464-
(deduped, malformed-UUID-dropped rows may reduce the final number).
487+
The expected count is an upper bound. The final count can be lower because of deduplication and dropped rows.
465488

466489
A 100 GB v4 dataset should complete in a few hours on a workstation-class disk, less on dedicated server hardware.
467490

491+
### Phase completion lines
492+
493+
Each phase prints an explicit completion line on success, after its per-table lines:
494+
495+
```text
496+
INFO Extract phase completed: 64 table(s), 5821044 row(s) in 184302 ms
497+
INFO Transform phase completed: 64 table(s), 5820102 row(s) in 96118 ms
498+
INFO Load phase completed: 64 table(s), 5820097 row(s) in 211740 ms
499+
```
500+
501+
The `run` command, which chains extract, transform, and load, prints one final line:
502+
503+
```text
504+
INFO Migration completed: extract + transform + load finished. Run 'verify' to review row counts and probes.
505+
```
506+
507+
A completed phase prints its completion line. For `run`, the `Migration completed` line confirms success.
508+
**Absence of that line after the per-table output means the phase did not finish.** Check the exit code and the preceding log lines.
509+
510+
After the last table loads, the migrator emits progress lines while it finalizes:
511+
512+
```text
513+
INFO Finalizing load: re-enabling triggers and resetting identity sequences
514+
INFO Analyzing 64 loaded table(s)
515+
INFO Refreshing PORTFOLIOMETRICS_GLOBAL materialized view
516+
INFO Applying v5.7.0 cleanup deletes
517+
```
518+
519+
The `Load phase completed` line follows once finalization finishes.
520+
468521
## Resumability
469522

470523
Each phase persists per-table state in the `migration_state` table inside the staging schema.

docs/tutorials/rehearsing-the-v4-migration.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,13 @@ v4-migrator verify \
163163
Expected output:
164164

165165
```text linenums="1"
166+
== v4-migrator verify ==
167+
166168
[Schema]
167-
OK Schema version = 202605111028
169+
OK Flyway head = 202605111028
168170
169171
[Row counts]
170-
Table Source Staging v5
172+
Table Source Staging v5 Note
171173
(no source configured)
172174
LICENSE - 0 0
173175
TEAM - 0 0
@@ -178,9 +180,11 @@ Expected output:
178180
179181
[Constraints]
180182
13 CHECK constraint(s) hold across 55 loaded table(s)
183+
184+
== verify complete ==
181185
```
182186

183-
If the schema version is anything else or any row count is non-zero, **except in the `PERMISSION` table**,
187+
If the Flyway head differs or any row count is non-zero, **except in the `PERMISSION` table**,
184188
the rest of the rehearsal will not work.
185189

186190
## Dry-running the migration
@@ -248,16 +252,18 @@ We drop `--dry-run` and run the real extract, transform, and load:
248252
```
249253

250254
Runtime depends on the size of our v4 dataset.
251-
The migrator prints per-table progress and a heartbeat every five seconds for long-running tables:
255+
The migrator prints per-table progress and a heartbeat every five seconds for long-running tables, each phase prints a completion line, and `run` ends with a `Migration completed` line that confirms success:
252256

253257
```text linenums="1"
254258
MetricsRetention - Metrics retention set to 30 days (cutoff = 2026-04-15T11:38:10.636499285Z)
255259
ExtractPhase - Extracting LICENSE
256260
ExtractPhase - -> 811 rows in 395 ms
257261
...
262+
ExtractPhase - Extract phase completed: 64 table(s), 5821044 row(s) in 184302 ms
258263
TransformPhase - Transforming LICENSE
259264
TransformPhase - -> 811 rows in 60 ms
260265
...
266+
TransformPhase - Transform phase completed: 64 table(s), 5820102 row(s) in 96118 ms
261267
LoadPhase - Pre-creating metrics partitions for 32 day(s) from 2026-04-15 to 2026-05-16
262268
LoadPhase - Loading LICENSE into v5
263269
LoadProgressReporter - -> LICENSE: 811 rows in 56 ms (14482 rows/s)
@@ -267,6 +273,12 @@ LoadProgressReporter - .. VULNERABLESOFTWARE_VULNERABILITIES: still loading af
267273
LoadProgressReporter - .. VULNERABLESOFTWARE_VULNERABILITIES: still loading after 10s (expected 2740322 rows)
268274
LoadProgressReporter - .. VULNERABLESOFTWARE_VULNERABILITIES: still loading after 15s (expected 2740322 rows)
269275
...
276+
LoadPhase - Finalizing load: re-enabling triggers and resetting identity sequences
277+
LoadPhase - Analyzing 64 loaded table(s)
278+
LoadPhase - Refreshing PORTFOLIOMETRICS_GLOBAL materialized view
279+
LoadPhase - Applying v5.7.0 cleanup deletes
280+
LoadPhase - Load phase completed: 64 table(s), 5820097 row(s) in 211740 ms
281+
RunCommand - Migration completed: extract + transform + load finished. Run 'verify' to review row counts and probes.
270282
```
271283

272284
## Verifying the result
@@ -290,24 +302,28 @@ Expected output:
290302
OK Flyway head = 202605111028
291303
292304
[Row counts]
293-
Table Source Staging v5
305+
Table Source Staging v5 Note
294306
LICENSE 811 811 811
295307
LICENSEGROUP 4 4 4
296308
LICENSEGROUP_LICENSE 131 131 131
309+
TEAM 47 42 42 expected: dedup by NAME (-5)
310+
PROJECTS_TAGS 12480 12462 12462 reduction (-18), see migration guide
297311
...
298312
299313
[Probes]
300314
No probe entries.
301315
302316
[Constraints]
303317
13 CHECK constraint(s) hold across 55 loaded table(s)
318+
319+
== verify complete ==
304320
```
305321

306-
We expect mismatches between source and v5 row counts wherever the migrator
307-
deduplicates, drops, or rewrites rows.
322+
Source and v5 row counts differ wherever the migrator deduplicates, drops, or rewrites rows.
323+
The migrator makes these reductions intentionally. The `Note` column explains each one inline, pointing to the
324+
relevant transform or to the `[Probes]` section, so we can confirm what accounts for every drop.
308325
The migration guide's [lossy and non-obvious changes](../guides/administration/migrating-from-v4.md#lossy-and-non-obvious-changes)
309-
section catalogs every case.
310-
We read it now and confirm that the mismatches we see match the cases the guide describes.
326+
section catalogs every case, and we confirm that the reductions we see match the cases it describes.
311327

312328
## Dropping the staging schema
313329

0 commit comments

Comments
 (0)