Fix: plan unexecuted migrations regardless of major.minor order#27703
Fix: plan unexecuted migrations regardless of major.minor order#27703sonika-shah wants to merge 5 commits intoopen-metadata:mainfrom
Conversation
processNativeMigrations used sameOrHigherMajorMinor to gate unexecuted migrations by the current max's major.minor. That gate silently drops any version recorded on disk but missing from the ledger whose major.minor is lower than the current max — for example a historical gap at 1.5.15 when the dump was last migrated through 1.9.x, or a backported 1.11.11 landing after 1.12.1 was already cut. The containment check against SERVER_CHANGE_LOG is sufficient on its own: any version already executed is skipped, any version not executed is planned. Maintaining the reprocessing-on-maxVer path preserves the continuous-release behavior introduced in open-metadata#26571 (new SQL appended to the current version's schemaChanges.sql is picked up via checksum filter in SERVER_MIGRATION_SQL_LOGS). This also brings processNativeMigrations in line with processExtensionMigrations, which already uses the same containment-only filter. See also open-metadata#26592 which applied the equivalent simplification on the 1.12.x release line. Tests: - Updated three tests that encoded the old exclusion behavior to assert backports and historical gaps now get planned. - Added a historical-gap scenario (1.5.15 below executed max 1.10.5). - Removed sameOrHigherMajorMinorComparisons (method is gone).
There was a problem hiding this comment.
Pull request overview
Updates the server migration planner so that any native migration present on disk but missing from SERVER_CHANGE_LOG is planned, even if its major.minor is lower than the currently executed max. This prevents “missing migrations” from being silently skipped forever in upgrade paths with ledger gaps or backported patch releases.
Changes:
- Remove the
sameOrHigherMajorMinorfilter fromprocessNativeMigrations, relying solely on execution-history containment while preserving “reprocess max version” behavior. - Update/rename affected unit tests to assert inclusion of backported lower-minor migrations.
- Add a unit test covering the “historical gap below executed max” scenario; remove the now-obsolete
sameOrHigherMajorMinorcomparison test.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java | Removes major.minor gating so unexecuted native migrations below the executed max are still planned; keeps max-version reprocessing intact. |
| openmetadata-service/src/test/java/org/openmetadata/service/migration/api/MigrationWorkflowTest.java | Updates expectations for backported/lower-minor inclusion, adds historical-gap regression test, and deletes the helper-method test that no longer applies. |
🟡 Playwright Results — all passed (12 flaky)✅ 3963 passed · ❌ 0 failed · 🟡 12 flaky · ⏭️ 86 skipped
🟡 12 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
There was a problem hiding this comment.
Pull request overview
Fixes migration planning so that any unexecuted native migration present on disk is planned, even if its major.minor is lower than the current max executed version—eliminating a long-standing gap/backport skip scenario and aligning behavior with extension migration planning.
Changes:
- Remove
sameOrHigherMajorMinorgating from native migration selection (containment-only filter + reprocess max preserved). - Update existing unit tests to reflect the new inclusion behavior for backported/lower-minor migrations.
- Add a new unit test covering a “historical gap below max executed” scenario.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java | Removes major/minor order filtering so unexecuted native migrations are always planned; keeps reprocessing of max executed native version. |
| openmetadata-service/src/test/java/org/openmetadata/service/migration/api/MigrationWorkflowTest.java | Updates assertions for backport behavior, adds a historical-gap regression test, and removes the obsolete helper-method test. |
Code Review ✅ ApprovedMigration execution logic now correctly handles unexecuted migrations regardless of major or minor version ordering. No issues found. OptionsDisplay: compact → Showing less information. Comment with these commands to change:
Was this helpful? React with 👍 / 👎 | Gitar |
There was a problem hiding this comment.
Pull request overview
This PR fixes native migration planning so that any migration present on disk but missing from SERVER_CHANGE_LOG will be planned, even if its major.minor is lower than the currently max-executed major.minor. This aligns native migration behavior with extension migration planning and prevents historical gaps/backported patch migrations from being skipped indefinitely.
Changes:
- Removed the
sameOrHigherMajorMinorfilter from native migration planning so unexecuted versions are selected purely by execution history. - Updated existing unit tests to reflect the new inclusion behavior for backported lower-minor versions.
- Added a new unit test covering a “historical gap below max” scenario (e.g., missing
1.5.15while max executed is1.10.5).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java | Removes the major.minor gating in processNativeMigrations, relying on executed-version containment while preserving max-version reprocessing. |
| openmetadata-service/src/test/java/org/openmetadata/service/migration/api/MigrationWorkflowTest.java | Updates assertions for backport behavior, adds a historical-gap test case, and removes the deleted helper’s test. |
|



Summary
processNativeMigrationscurrently drops any unexecuted migration whosemajor.minoris lower than the current max'smajor.minor(sameOrHigherMajorMinorcheck). In upgrade paths where the ledger has a gap below the current max, those missing versions are silently skipped forever, andMigrationValidationClientreports them asMissing migrations that were not executed [...].This PR removes the
sameOrHigherMajorMinorgate. The ledger check (!executedMigrations.contains(version)) is sufficient — any version recorded inSERVER_CHANGE_LOGis still skipped, any version not recorded is planned. Reprocessing on the max version is preserved, so the continuous-release behavior (new SQL appended to the current version'sschemaChanges.sql, gated by statement-level checksums inSERVER_MIGRATION_SQL_LOGS) is unaffected.After the fix,
processNativeMigrationsmatchesprocessExtensionMigrations, which already uses a containment-only filter.Why
Two real-world scenarios hit this gate today:
Historical gap. A dump whose ledger contains
1.5.0 … 1.5.11, 1.9.0 …but is missing1.5.15. Withmax = 1.9.x,sameOrHigherMajorMinor("1.5.15", "1.9.x")returns false, so1.5.15is never planned on subsequent upgrades — even when the folder is present on disk and the migration hasn't been run.Backport below current max. When
1.11.11/1.11.12are released after1.12.1has been cut, a cluster upgrading from1.12.1→1.12.2seesmax = 1.12.1and drops the backported1.11.xmigrations. This is the original incident behind Minor migration fix #26592 on the 1.12.x line.Both cases already work on the 1.12.x release branches (which carry #26592's containment-only filter). This PR brings
mainto parity.What changes
MigrationWorkflow.javasameOrHigherMajorMinorhelper and its usage insideprocessNativeMigrations.MigrationWorkflowTest.java1.5.15below executed max1.10.5).sameOrHigherMajorMinorComparisonstest (method is gone).Guard rails that stay intact
SERVER_CHANGE_LOGcontainment check — any already-executed version is skipped.SERVER_MIGRATION_SQL_LOGSchecksum check inside the SQL runner — already-applied statements skip even during reprocess.Test plan
mvn test -Dtest=MigrationWorkflowTest— 25/25 pass1.5.15row inSERVER_CHANGE_LOG, run./bootstrap/openmetadata-ops.sh migrate, verify health check passes and1.5.15is recorded.1.12.1, upgrade to build containing1.11.11folder on disk, verify it's planned and executed.Related
Summary by Gitar
ServiceLoaderto supportMigrationProcessExtensionProviderfor pluggable extension migration logic.resolveMigrationProcessto handle delegation between native migrations and extension providers, ensuring Java data migrations are not incorrectly re-run for extension versions.loadMigrationsFallsBackToNoOpWhenNoExtensionProviderHandlesVersionto ensure extension versions correctly default toMigrationProcessImplwhen no provider is found.This will update automatically on new commits.