Flyway 是一种强大的数据库迁移工具,它能在多个环境中自动执行数据库版本控制,确保数据库的结构(schema)和数据(如初始化数据)的一致性和可维护性。Flyway 的迁移执行过程包括多个步骤,从检测迁移文件,到执行 SQL 语句,再到更新数据库的版本记录。Flyway 可以与多种数据库系统(如 MySQL、PostgreSQL、Oracle 等)集成,并支持 Java 项目中的自动化数据库管理。
一、Flyway 的基本原理
Flyway 通过管理 数据库版本迁移文件 来实现数据库的版本控制。迁移文件通常以 SQL 语句的形式编写,用来定义数据库 schema 的更改(如创建表、修改表、插入数据等)。Flyway 通过读取这些迁移文件,将它们依次应用到数据库中,保证数据库在不同环境中的一致性。
Flyway 在执行迁移时,维护一个特殊的表(通常命名为 flyway_schema_history
),用于记录已应用的迁移文件。这使得 Flyway 能够根据文件版本号确定哪些迁移已经执行过,哪些是新的需要执行的。
二、Flyway 迁移执行的详细过程
Flyway 执行迁移时,遵循以下步骤:
1. 连接数据库
首先,Flyway 需要与目标数据库建立连接。数据库连接的配置信息通常在应用的配置文件(如 application.yml
或 flyway.conf
)中定义,Flyway 会根据这些配置来连接数据库。
示例配置:
spring:datasource:url: jdbc:mysql://localhost:3306/mydbusername: rootpassword: rootpassworddriver-class-name: com.mysql.cj.jdbc.Driver
Flyway 使用这些配置连接到数据库,准备进行迁移操作。
2. 检查并创建历史表(flyway_schema_history)
连接数据库后,Flyway 会检查是否存在 flyway_schema_history
表。该表用于记录每次迁移的执行状态和历史信息。如果表不存在,Flyway 会自动创建这个表。
flyway_schema_history
表的结构:
CREATE TABLE flyway_schema_history (installed_rank INT NOT NULL,version VARCHAR(50),description VARCHAR(200),type VARCHAR(20),script VARCHAR(1000) NOT NULL,checksum INT,installed_by VARCHAR(100) NOT NULL,installed_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,execution_time INT NOT NULL,success BOOL NOT NULL
);
- installed_rank:迁移执行的顺序号。
- version:迁移的版本号(对应迁移文件中的版本号)。
- description:迁移文件的描述。
- type:迁移文件的类型(如 SQL、JDBC)。
- script:迁移文件的名称。
- checksum:迁移文件的校验和(用于确保文件没有被篡改)。
- success:表示该迁移是否成功执行。
3. 检测待执行的迁移文件
Flyway 在应用启动时,会扫描指定目录下的迁移文件(如 db/migration
),并根据迁移文件的命名规则识别不同的迁移版本。每个迁移文件的命名格式通常是:
V<Version>__<Description>.sql
- V:表示版本迁移文件。
- :版本号(如
1
,1.1
,2
等),Flyway 根据这个版本号确定执行顺序。 - :简要描述迁移内容的文本。
Flyway 会将这些文件与 flyway_schema_history
表中的记录进行对比,判断哪些迁移已经执行,哪些迁移需要执行。
4. 校验迁移文件
Flyway 会对每个迁移文件计算校验和(checksum),并与 flyway_schema_history
表中已有记录的校验和进行对比。这样做的目的是确保迁移文件没有被修改或破坏。
- 校验和一致:如果校验和一致,Flyway 会跳过该迁移文件,继续检查下一个文件。
- 校验和不一致:如果校验和不一致,Flyway 会报错并停止迁移操作,因为这意味着迁移文件被修改,可能会影响数据库的正确性。
5. 执行迁移文件
Flyway 根据迁移文件的版本号依次执行未应用的迁移文件。每个迁移文件中的 SQL 语句会被逐条执行。Flyway 通过 JDBC 与数据库交互,并确保在事务内执行(某些数据库除外,如 MySQL 对 DDL 操作不支持事务)。
迁移文件示例:
-- V1__Create_users_table.sql
CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100) NOT NULL,email VARCHAR(100) UNIQUE NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
6. 更新历史记录
每个迁移文件成功执行后,Flyway 会将相关信息写入 flyway_schema_history
表中,包括迁移的版本号、描述、执行时间等信息。这一步至关重要,确保 Flyway 了解已经执行过的迁移,避免重复执行。
插入历史记录的 SQL:
INSERT INTO flyway_schema_history (installed_rank, version, description, type, script, checksum, installed_by, execution_time, success)
VALUES (1, '1', 'Create_users_table', 'SQL', 'V1__Create_users_table.sql', 123456789, 'admin', 200, TRUE);
7. 处理迁移失败
如果某个迁移文件执行过程中发生错误,Flyway 会停止后续迁移,并将该迁移标记为失败。Flyway 不会回滚已经成功执行的迁移文件,但它会记录失败的迁移,并提示开发者进行修复。
开发者可以通过 Flyway 提供的 repair
命令修复失败的迁移历史,允许重新执行失败的迁移文件。
flyway repair
该命令会清除失败的迁移记录,使 Flyway 能够重新尝试执行该迁移文件。
三、Flyway 的执行命令
Flyway 提供了一系列命令,帮助开发者管理数据库的迁移过程。常用的命令有:
1. migrate
这是最常用的 Flyway 命令,执行所有待执行的迁移文件。
flyway migrate
Flyway 会扫描指定的迁移目录,执行所有新的迁移文件。
2. clean
该命令会删除所有已存在的表和数据,包括 flyway_schema_history
表,彻底清理数据库。慎用,通常用于开发或测试环境的清理操作。
flyway clean
3. info
该命令用于查看 Flyway 当前的迁移状态,包括哪些迁移已经执行,哪些尚未执行,以及迁移的成功或失败状态。
flyway info
4. validate
该命令用于校验已执行的迁移文件是否仍然有效,包括校验迁移文件的校验和。
flyway validate
5. repair
当某些迁移文件失败时,repair
命令可以用于修复 flyway_schema_history
表,使 Flyway 能够重新执行失败的迁移。
flyway repair
四、Flyway 的常见配置
除了执行命令,Flyway 还允许开发者通过配置文件(如 flyway.conf
或 application.yml
)进行各种高级设置。
常见配置项:
flyway:url: jdbc:mysql://localhost:3306/mydbuser: rootpassword: rootpasswordlocations: classpath:db/migrationbaseline-on-migrate: trueclean-on-validation-error: false
- url:数据库连接 URL。
- user:数据库用户名。
- password:数据库密码。
- locations:迁移文件存放的路径(可以是文件系统或类路径下的目录)。
- baseline-on-migrate:如果数据库已存在 schema,可以通过
baseline
标记为一个初始版本。 - clean-on-validation-error:当校验迁移文件失败时,是否自动清理数据库。
五、Flyway 的执行策略和优化
- 增量式迁移:Flyway 通过增量式迁移方式管理数据库的版本变更,不会重复执行已经应用的迁移文件,因此迁移操作的执行效率较高。
- 回滚策略:Flyway 默认不支持自动回滚,但可以通过编写
Undo
迁移文件实现手动回滚。需要在实际项目中根据需要实现安全的
回滚机制。
3. 并行化执行:对于多节点的分布式系统,可以通过 Flyway 的锁机制确保迁移操作只在一个节点上执行,避免并发执行带来的冲突。
六、总结
Flyway 的迁移执行过程非常透明,遵循明确的版本管理规则,确保每个版本的数据库变更都有详细的记录和执行步骤。通过维护 flyway_schema_history
表,Flyway 能够跟踪和管理所有的迁移文件,避免重复执行或遗漏变更。Flyway 提供的各种命令和配置也让开发者在管理数据库 schema 时更加灵活,适用于开发、测试和生产环境。