Andrei Damian-Fekete
Andrei Damian-Fekete

Reputation: 1980

Spring Boot 1.5 to 2 migration - Flyway migration checksum mismatch

When upgrading to Spring Boot 2 from 1.5 I get the following error, although the SQL scripts haven't changed:

Migration checksum mismatch for migration version 1
-> Applied to database : 1395032327
-> Resolved locally    : -175919814

Spring Boot recommends

To make sure that the schema upgrade goes smoothly, please follow the following instructions:

  • First upgrade your 1.5.x Spring Boot application to Flyway 4 (4.2.0 at the time of writing), see the instructions for Maven and Gradle.

  • Once your schema has been upgraded to Flyway 4, upgrade to Spring Boot 2 and run the migration again to port your application to Flyway 5.

This is not easily possible if you don't control the deployment and you can't deploy the application twice (e.g. users download the latest version of the app).

What is the cause of the problem and what would be the solution?

Upvotes: 5

Views: 7720

Answers (2)

Michal Foksa
Michal Foksa

Reputation: 12024

Probably easiest is to execute flyway.repair() before the real migration:

@Configuration
public class FlywayRepair {

    @Bean
    public FlywayMigrationStrategy repair() {
        return flyway -> {
            // repair each script checksum 
            flyway.repair();
            // before migration is executed 
            flyway.migrate();
        };
    }
}

Downfall is that it also removes failed migrations. From Flyway.repair() Javadoc:

Repairs the Flyway schema history table. This will perform the following actions:

  • Remove any failed migrations on databases without DDL transactions (User objects left behind must still be cleaned up manually)
  • Realign the checksums, descriptions and types of the applied migrations with the ones of the available migrations

Upvotes: 1

Andrei Damian-Fekete
Andrei Damian-Fekete

Reputation: 1980

It seems that the checksum algorithm has changed between versions. In (some) versions of Flyway 4,

all checksums are automatically recalculated and updated with the new algorithm on first run (Flyway #253)

I'm not sure if this means that the checksum is calculated with both versions, and if it matches the old version is updated with the new version, or if it means that it's blindly overwritten with the new one.


Flyway Checksum Algorithm:

  • version 3 - crc32 over bytes:

    bytes = resource.loadAsBytes()
    ...
    crc32.update(bytes);
    
  • version 5 (not a verbatim copy) - crc32 over lines (ignoring CR/LF, and using UTF-8 encoding):

    BufferedReader bufferedReader = new BufferedReader(new StringReader(resource.loadAsString(configuration.getEncoding())));
    [...]
    while ((line = bufferedReader.readLine()) != null) {
        crc32.update(line.getBytes("UTF-8"));
    }
    

Solution

In the answer to Flyway repair with Spring Boot multiple solutions are presented.

Because manual intervention had to be avoided, I've used the FlywayMigrationStrategy and a jdbcTemplate to update at startup the checksums from fixed known values to the new fixed know values required by Flyway 5.

Upvotes: 4

Related Questions