Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 793
Andrei Damian-Fekete Avatar asked Jul 03 '18 11:07

Andrei Damian-Fekete


People also ask

What checksum does Flyway use?

Flyway uses the CRC32 algorithm for checksum generation.

How do you skip Flyway migration?

The hotfix migration can be deployed with Flyway with skipExecutingMigrations=true . The schema history table will be updated with the new migration, but the script itself won't be executed again. skipExecutingMigrations can be used with with cherryPick to skip specific migrations.


1 Answers

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.

like image 153
Andrei Damian-Fekete Avatar answered Oct 11 '22 20:10

Andrei Damian-Fekete