flyway - 校验和概念的含义

Posted

技术标签:

【中文标题】flyway - 校验和概念的含义【英文标题】:flyway - The meaning of the concept of checksums 【发布时间】:2017-09-02 04:38:58 【问题描述】:

我正在学习Flyway迁移工具,对校验和的概念还不是很清楚。有人可以解释一下是什么吗?它是如何计算的,或者如何改变?

我明白修复命令重新计算校验和,我不明白它有什么不同。

谢谢!

【问题讨论】:

如果需要,您能否告诉您如何执行/运行修复命令。我在 IntelliJ 内部使用 flyway(不是来自任何 CLI) 【参考方案1】:

Flyway 中的校验和字段构成验证机制的一部分,确保迁移脚本在应用到数据库后未被更改。这将保证您的应用程序的所有实例都将具有相同的数据库结构(内容)。您可以关闭验证,但我不建议您这样做。回答你的问题:

什么是?

只需谷歌什么是校验和。 Wikipedia

如何计算?

对于 SQL 迁移,Flyway 使用 CRC32 类来计算校验和。具体代码见下文。

如何更改?

一旦您迁移的二进制内容被修改,迁移的校验和将被更改。如果您想在需要计算新版本迁移文件的校验和时更改数据库中的校验和字段,然后更改数据库中的值。但是,我不建议这样做。您不需要这样做,并且您想要更改它的事实可能表明您做错了什么。无论如何,校验和的计算代码非常简单(由 Flyway 源代码提供):

        /**
         * Calculates the checksum of this string.
         *
         * @param str The string to calculate the checksum for.
         * @return The crc-32 checksum of the bytes.
         */
        /* private -> for testing */
        static int calculateChecksum(Resource resource, String str) 
            final CRC32 crc32 = new CRC32();

            BufferedReader bufferedReader = new BufferedReader(new StringReader(str));
            try 
                String line;
                while ((line = bufferedReader.readLine()) != null) 
                    crc32.update(line.getBytes("UTF-8"));
                
             catch (IOException e) 
                String message = "Unable to calculate checksum";
                if (resource != null) 
                    message += " for " + resource.getLocation() + " (" + resource.getLocationOnDisk() + ")";
                
                throw new FlywayException(message, e);
            

            return (int) crc32.getValue();
        

【讨论】:

仅供参考,看起来算法发生了变化,他们在计算校验和之前删除了所有换行符:github.com/flyway/flyway/blob/… 仅供参考,当前校验和计算代码github.com/flyway/flyway/blob/flyway-6.5.5/flyway-core/src/main/…【参考方案2】:

为了计算任意文件的flyway校验和,我使用以下代码:

import java.util.*;
import org.flywaydb.core.internal.resource.filesystem.*;
import org.flywaydb.core.internal.resolver.*;
import java.nio.charset.*;

public class Program 

    public static void main( String[] args ) throws Exception

        String filename="/path/to/migration/V8_test.sql";
        FileSystemResource r = new FileSystemResource(null, filename,Charset.forName("UTF-8"));
        int cs = ChecksumCalculator.calculate(r);
        System.out.println(cs);
    

此代码的唯一依赖项是org.flywaydb:flyway-core:6.4.1

【讨论】:

在 8.1.0 中,FileSystemResource 的构造函数将不接受 null 作为第一个参数。【参考方案3】:

对于 8.10 版,@Eugene 的回答需要稍作改动:

get_flyway_checksum.java:

import java.util.*;
import org.flywaydb.core.internal.resource.filesystem.*;
import org.flywaydb.core.internal.resolver.*;
import org.flywaydb.core.internal.resource.*;
import org.flywaydb.core.api.Location;
import java.nio.charset.*;

public class Program 

    public static void main( String[] args ) throws Exception
        Location loc = null;
        String filepath = args[0];
        FileSystemResource r = new FileSystemResource(loc, filepath,Charset.forName("UTF-8"), false);
        int cs = ChecksumCalculator.calculate(r);
        System.out.println(cs);
    

获取校验和:

java -cp path to your flyway installation/lib/community/flyway-core-8.1.0.jar get_flyway_checksum.java filepath

【讨论】:

以上是关于flyway - 校验和概念的含义的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot整合Flyway

原因:org.flywaydb.core.api.FlywayException:验证失败。迁移 2 的迁移校验和不匹配

TTL/RS485/RS232串口通信中波特率|校验位|数据位|停止位的区别和含义

Flyway 可重复迁移随机运行

Flyway 始终执行可重复的迁移

flyway和可重复迁移的初始化