Skip to content

Commit 8fe3014

Browse files
Fix: backfill historical gaps in SERVER_CHANGE_LOG during migrate (#27703)
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 #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 #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). Co-authored-by: Mohit Yadav <105265192+mohityadav766@users.noreply.github.com>
1 parent 3d88c99 commit 8fe3014

2 files changed

Lines changed: 73 additions & 30 deletions

File tree

openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,6 @@ private static int[] parseVersion(String version) {
263263
return numbers;
264264
}
265265

266-
static boolean sameOrHigherMajorMinor(String version, String maxVersion) {
267-
int[] v = parseVersion(version);
268-
int[] max = parseVersion(maxVersion);
269-
if (v[0] != max[0]) return v[0] > max[0];
270-
return v[1] >= max[1];
271-
}
272-
273266
// Package-private for testing
274267
List<MigrationFile> resolveApplyMigrations(List<MigrationFile> availableMigrations) {
275268
LOG.debug("Filtering Server Migrations");
@@ -321,8 +314,7 @@ private List<MigrationFile> processNativeMigrations(
321314
for (MigrationFile migration : nativeMigrations) {
322315
if (migration.version.equals(maxVer)) {
323316
result.add(migration.copyWithReprocessing(true));
324-
} else if (!executedMigrations.contains(migration.version)
325-
&& sameOrHigherMajorMinor(migration.version, maxVer)) {
317+
} else if (!executedMigrations.contains(migration.version)) {
326318
result.add(migration.copyWithReprocessing(false));
327319
}
328320
}

openmetadata-service/src/test/java/org/openmetadata/service/migration/api/MigrationWorkflowTest.java

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ void runMigrationWorkflowsExecutesDataMigrationForReprocessing() throws Exceptio
410410
}
411411

412412
@Test
413-
void getMigrationsToApplyOlderMinorBackfillsExcludedWhenOnHigherMinor() throws Exception {
413+
void getMigrationsToApplyBackportedLowerMinorVersionsAreIncluded() throws Exception {
414414
List<String> executedMigrations = List.of("1.11.10", "1.12.0", "1.12.1");
415415
List<MigrationFile> availableMigrations =
416416
List.of(
@@ -429,9 +429,31 @@ void getMigrationsToApplyOlderMinorBackfillsExcludedWhenOnHigherMinor() throws E
429429
workflow.getMigrationsToApply(executedMigrations, availableMigrations);
430430

431431
List<String> versions = result.stream().map(m -> m.version).toList();
432-
assertEquals(List.of("1.12.1", "1.12.2"), versions);
433-
assertTrue(result.get(0).isReprocessing());
434-
assertFalse(result.get(1).isReprocessing());
432+
assertEquals(List.of("1.11.11", "1.11.12", "1.12.1", "1.12.2"), versions);
433+
assertFalse(
434+
result.stream()
435+
.filter(m -> m.version.equals("1.11.11"))
436+
.findFirst()
437+
.orElseThrow()
438+
.isReprocessing());
439+
assertFalse(
440+
result.stream()
441+
.filter(m -> m.version.equals("1.11.12"))
442+
.findFirst()
443+
.orElseThrow()
444+
.isReprocessing());
445+
assertTrue(
446+
result.stream()
447+
.filter(m -> m.version.equals("1.12.1"))
448+
.findFirst()
449+
.orElseThrow()
450+
.isReprocessing());
451+
assertFalse(
452+
result.stream()
453+
.filter(m -> m.version.equals("1.12.2"))
454+
.findFirst()
455+
.orElseThrow()
456+
.isReprocessing());
435457
}
436458

437459
@Test
@@ -458,7 +480,7 @@ void getMigrationsToApplyCollateVersionsAreIncluded() throws Exception {
458480
List<String> extensionVersions =
459481
result.stream().filter(m -> m.isExtension).map(m -> m.version).toList();
460482

461-
assertEquals(List.of("1.12.1", "1.12.2"), nativeVersions);
483+
assertEquals(List.of("1.11.11", "1.12.1", "1.12.2"), nativeVersions);
462484
assertEquals(List.of("1.12.1-collate"), extensionVersions);
463485
assertTrue(result.stream().anyMatch(m -> m.version.equals("1.12.1") && m.isReprocessing()));
464486
assertTrue(
@@ -606,7 +628,7 @@ void getMigrationsToApplyAllMigrationsAlreadyExecuted() throws Exception {
606628
}
607629

608630
@Test
609-
void getMigrationsToApplyMultipleBackportedMinorVersionsExcluded() throws Exception {
631+
void getMigrationsToApplyMultipleBackportedMinorVersionsAreIncluded() throws Exception {
610632
List<String> executedMigrations = List.of("1.10.5", "1.11.0", "1.12.0", "1.12.1");
611633
List<MigrationFile> availableMigrations =
612634
List.of(
@@ -627,8 +649,50 @@ void getMigrationsToApplyMultipleBackportedMinorVersionsExcluded() throws Except
627649
workflow.getMigrationsToApply(executedMigrations, availableMigrations);
628650

629651
List<String> versions = result.stream().map(m -> m.version).toList();
630-
assertEquals(List.of("1.12.1", "1.12.2"), versions);
631-
assertTrue(result.get(0).isReprocessing());
652+
assertEquals(List.of("1.10.6", "1.11.1", "1.11.1-collate", "1.12.1", "1.12.2"), versions);
653+
assertTrue(
654+
result.stream()
655+
.filter(m -> m.version.equals("1.12.1"))
656+
.findFirst()
657+
.orElseThrow()
658+
.isReprocessing());
659+
}
660+
661+
@Test
662+
void getMigrationsToApplyHistoricalGapBelowMaxIsBackfilled() throws Exception {
663+
List<String> executedMigrations =
664+
List.of("1.5.0", "1.5.11", "1.9.0", "1.9.1", "1.10.0", "1.10.5");
665+
List<MigrationFile> availableMigrations =
666+
List.of(
667+
createMigrationFile("1.5.0", false),
668+
createMigrationFile("1.5.11", false),
669+
createMigrationFile("1.5.15", false),
670+
createMigrationFile("1.9.0", false),
671+
createMigrationFile("1.9.1", false),
672+
createMigrationFile("1.10.0", false),
673+
createMigrationFile("1.10.5", false));
674+
675+
MigrationWorkflow workflow =
676+
new MigrationWorkflow(
677+
jdbi, tempDir.toString(), ConnectionType.MYSQL, null, null, config, false);
678+
679+
List<MigrationFile> result =
680+
workflow.getMigrationsToApply(executedMigrations, availableMigrations);
681+
682+
List<String> versions = result.stream().map(m -> m.version).toList();
683+
assertEquals(List.of("1.5.15", "1.10.5"), versions);
684+
assertFalse(
685+
result.stream()
686+
.filter(m -> m.version.equals("1.5.15"))
687+
.findFirst()
688+
.orElseThrow()
689+
.isReprocessing());
690+
assertTrue(
691+
result.stream()
692+
.filter(m -> m.version.equals("1.10.5"))
693+
.findFirst()
694+
.orElseThrow()
695+
.isReprocessing());
632696
}
633697

634698
@Test
@@ -696,19 +760,6 @@ void resolveApplyMigrationsAllExecutedNoDuplicates() throws Exception {
696760
assertTrue(result.get(0).isReprocessing());
697761
}
698762

699-
@Test
700-
void sameOrHigherMajorMinorComparisons() {
701-
assertTrue(MigrationWorkflow.sameOrHigherMajorMinor("1.12.0", "1.12.1"));
702-
assertTrue(MigrationWorkflow.sameOrHigherMajorMinor("1.12.5", "1.12.1"));
703-
assertTrue(MigrationWorkflow.sameOrHigherMajorMinor("1.13.0", "1.12.1"));
704-
assertTrue(MigrationWorkflow.sameOrHigherMajorMinor("2.0.0", "1.12.1"));
705-
assertFalse(MigrationWorkflow.sameOrHigherMajorMinor("1.11.15", "1.12.1"));
706-
assertFalse(MigrationWorkflow.sameOrHigherMajorMinor("1.10.6", "1.12.1"));
707-
assertFalse(MigrationWorkflow.sameOrHigherMajorMinor("0.13.0", "1.12.1"));
708-
assertTrue(MigrationWorkflow.sameOrHigherMajorMinor("1.12.1-collate", "1.12.1"));
709-
assertFalse(MigrationWorkflow.sameOrHigherMajorMinor("1.11.1-collate", "1.12.1"));
710-
}
711-
712763
private void mockContext(
713764
MigrationWorkflowContext contextMock, org.mockito.MockedConstruction.Context context) {
714765
HashMap<String, MigrationContext> contexts = new HashMap<>();

0 commit comments

Comments
 (0)