无锡网站建设收费,it培训,怎么在百度推广自己的公司,鄠邑建站 网站建设目录1 为什么使用数据库版本控制2 数据库版本管理工具选型#xff1a;Flyway、Liquibase、Bytebase、阿里 DMSFlywayLiquibaseBytebase阿里 DMS3 Flyway数据库版本管理研究3.1 参考资料3.2 Flyway概述3.3 Flyway原理3.4 Flyway版本和功能3.5 Flyway概念3.5.1 版本迁移#xf…
目录1 为什么使用数据库版本控制2 数据库版本管理工具选型Flyway、Liquibase、Bytebase、阿里 DMSFlywayLiquibaseBytebase阿里 DMS3 Flyway数据库版本管理研究3.1 参考资料3.2 Flyway概述3.3 Flyway原理3.4 Flyway版本和功能3.5 Flyway概念3.5.1 版本迁移Versioned migrations3.5.2 撤销迁移Undo migrations3.5.3 可重复迁移Repeatable migrations3.5.4 基于SQL迁移3.5.5 基于Java迁移3.5.6 迁移状态3.6 Flyway基础命令3.6.1 迁移migrate3.6.2 清理clean3.6.3 信息info3.6.4 验证validate3.6.5 撤销undo3.6.6 基线(baseline)3.6.7 修复repair3.6.8 检查check3.6.9 快照snapshot3.7 Flyway使用3.7.1 在命令行中使用安装修改配置使用创建基线flyway [options] baseline查看信息flyway [options] info验证flyway [options] validate执行迁移flyway [options] migrate修复flyway [options] repair清理数据库flyway [options] clean3.7.2 在项目中使用SpringBoot插件进行数据库版本管理使用要求在项目中引入flyway依赖修改配置文件SpringBoot配置说明添加迁移文件启动服务引入maven插件进行其他命令操作注意事项我可以在 Flyway 之外对数据库进行结构更改吗迁移失败后如何修复数据库3.8 Flyway支持的数据库3.9 Flyway国产数据库支持扩展3.10 生产应用总结3.11 其他技巧3.11.1 注入环境3.11.2 占位符默认占位符脚本配置文件3.12 错误汇总3.12.1 错误1原因解决方法方法1方法2当前采用方法33.12.2 错误2原因解决方法方法1方法2当前采用1 为什么使用数据库版本控制
解决我们在项目中管理数据库遇到的三个难题
通过工具规范升级脚本通过工具提升部署、升级速度解决现场人员执行脚本后不知道是否正确执行的问题
在我们大多数的项目中我们通过Git,SVN 等版本管理工具进行代码的版本管理促使团队成员紧密合作方便我们管理不同分支不同环境的代码追踪提交历史回退版本。但是我们的数据库一直没有进行版本管理依赖开发人员手动管理。下图是一个简单的项目环境示意。在项目持续到一定环节的时候就会出现很多问题我们很难理清楚例如
某台机器上的数据库处于什么状态某条脚本在某台机器上是否已应用生产中的快速修复的脚本是否已在之后的测试中应用如何设置一个新的数据库实例 数据库版本控制工具就是帮我们解决数据库管理混乱的工具 可以帮助我们
快速创建新的数据库实例始终清楚当前数据库处于什么版本状态以确定是方式将数据库当前版本升级到更新的版本
2 数据库版本管理工具选型Flyway、Liquibase、Bytebase、阿里 DMS
该章节参考文章https://zhuanlan.zhihu.com/p/559857853。
Flyway
Flyway (https://flywaydb.org)是一款开源的数据库版本管理工具Flyway 可以独立于应用实现管理并跟踪数据库变更支持数据库版本自动升级并且有一套默认的规约无需复杂的配置Migrations 可以写成 SQL 脚本也可以写在 Java 代码中不仅支持 Command Line 和 Java API还支持 Build 构建工具和 Spring Boot 等同时在分布式环境下能够安全可靠地升级数据库支持失败恢复等。
Liquibase
Liquibase (https://www.liquibase.org/) 是一个用于跟踪、管理和应用数据库变化的开源的数据库重构工具。它将所有数据库的变化包括结构和数据都保存在 changelog 文件中便于版本控制它的目标是提供一种数据库类型无关的解决方案通过执行 Schema 类型的文件进行变更。
Bytebase
Bytebase(https://www.bytebase.com/)是一款开源的数据库 DevOps 工具面向应用开发和 DBA管理 SchemaDDL 和数据DML的全生命周期。
阿里 DMS
DMS(https://www.aliyun.com/product/dms) 是一种集数据管理、结构管理、用户授权、安全审计、数据趋势、数据追踪、BI图表、性能与优化和服务器管理于一体的数据管理服务。
FlywayLiquibaseBytebase阿里DMS公司Red GateLiquibaseBytebase阿里第一个版本发布时间2010 年2006 年2021年2016年产品版本开源/商业版开源/商业版开源/商业版商用易用性Flyway CLI简单易用Liquibase CLI功能比较全但概念很多学习成本相对高易用的 UI界面功能比较多上手比较困难可观测性通过 Schema 变更记录 查看变更历史较强的可观测性通过界面直观的看到所有的变更情况完备的 GUI方式直观看到整个变更的流程和 SQL 详情所有的变更都是通过工单的方式流程清晰成熟度成熟成熟初期相对成熟功能侧重点数据库变更管理管理数据库的变更面向研发工程师和DBA 提供Schema及数据变更、版本管理审核流水线数据查询一站式数据库开发。数据资产管理支持的数据库支持所有国际主流关系型数据库支持所有国际主流关系型数据库 支持 NoSQL 数据库比如 mongodb现已支持 MySQL, PostgreSQL, TiDB, ClickHouse, Snowflake 以及 MongoDB 数据库支持大部分国际主流关系型数据库 支持 NoSQL 数据库比如 mongodb、Redis
可以看到四个产品工具都能实现数据库版本管理Flyway、Liquibase和Bytebase支持开源免费Flyway和Liquibase发布多年成熟稳定Bytebase虽然易用性很高但是面世不久可以等待其稳定发布几个版本之后再探索使用。 由于Flyway相对Liquibase简单易用因此本文首先探索Flyway的使用。
3 Flyway数据库版本管理研究
3.1 参考资料
本文主要根据官方文档结合网上其他经验和自己的试用经验编写。官方文档老版结构分明易于阅读适合入门。新版文档内容繁多可以在阅读老版文档后再阅读。 2023 年 2 月 2 日官方新版文档更新已经将老版文档的内容增加到了新版文档的第一章节现在新版文档已经更容易入门了。 实际上老版本的文档已经包含了Flyway的核心功能和原理讲解新版本文档感觉是为了推新的Flyway Desktop版本管理迁移脚本生成工具。官方对其定义如下 Flyway Desktop在 Flyway 之上提供了一个强大的 GUI可帮助您轻松地对数据库模式进行版本控制并为 SQL Server、PostgreSQL 和 Oracle 数据库生成迁移脚本。 Flyway Desktop 将数据库对象的定义保存到模式模型中。您可以进行版本控制并与团队成员共享对模式模型的更改以快速迭代新开发。 截止2023 年 1 月 31 日可见Flyway Desktop仅支持SQL Server、PostgreSQL 和 Oracle 数据库生成迁移脚本。支持可视化的迁移脚本生成和版本控制。
3.2 Flyway概述
Flyway 是一个开源的数据库迁移工具。它强烈支持简单性和约定优于配置。
它仅基于 7 个基本命令 Migrate、 Clean、 Info、 Validate、 Undo、 Baseline和 Repair。
迁移可以用SQL 支持特定于数据库的语法例如 PL/SQL、T-SQL 等或Java 用于高级数据转换编写。
它有一个命令行客户端。如果在 JVM 上官方建议使用Java API 在应用程序启动时迁移数据库。也可以使用Maven 插件 或Gradle 插件。
如果这还不够还有 适用于 Spring Boot、Dropwizard、Grails、Play、SBT、Ant、Griffon、Grunt、Ninja 等的插件
因为公司的产品和项目都是基于Spring Boot开发因此选项使用集成 Spring Boot插件的方式使用Flyway通过简单配置在服务启动运行前自动进行数据库迁移。
3.3 Flyway原理
最简单的场景是将Flyway指向一个空数据库时。 它将尝试定位其模式历史表。由于数据库是空的Flyway 不会找到它而是 创建它。会创建一个默认表名为flyway_schema_history的空表该表将用于跟踪数据库的状态。
紧接着 Flyway 将开始扫描文件系统或应用程序的类路径以进行迁移。它们可以用 Sql 或 Java 编写。
然后根据版本号对迁移进行排序并按顺序应用 随着每次迁移命令的应用模式历史表flyway_schema_history也会相应更新
有了元数据和初始状态那么Flyway是如何迁移到更新的版本的 再次执行迁移Flyway 将再次扫描文件系统或应用程序的类路径以进行迁移。根据模式历史表检查迁移。对版本号低于或等于标记为当前的版本的迁移进行忽略剩余的迁移暂时挂起扫描完成后对待应用的升级迁移按版本号排序并顺序执行。 迁移完成后模式历史表更新
就这样每次需要升级数据库版本时无论是结构定义 (DDL) 还是数据操作(DML)只需创建一个版本号高于当前版本的新迁移即可。下次 Flyway 启动时它会找到它并相应地升级数据库。
3.4 Flyway版本和功能
Flyway分为社区版、团队版和企业版。通过下表可知Flyway社区免费版支持的功能相对较少仅支持Flyway API/CLI 核心功能7大基本命令只支持6个不支持撤销undo命令。
版本社区版团队版企业版范围非常适合个人开发人员或寻求基本且可靠的框架来进行版本控制和自动部署数据库更改的非商业项目非常适合希望在开发和部署数据库更改期间改进协作并微调其流程的组织非常适合需要具有合规性控制的安全和自动化流程来开发、测试和部署数据库更改的大中型企业价格免费$597/年获取报价是否开源开源不开源不开源技术支持社区支持Redgate 支持Redgate 支持包含内容Flyway API/CLI 核心功能Flyway 桌面 GUI6 个基本命令Migrate、Clean、Info、Validate、Baseline 和 Repair支持当前数据库版本社区支持在社区版基础上增加试运行Dry run撤消迁移脚本遴选Cherry pick跳过迁移标记为已部署对象级版本控制**内置 Git 客户端支持较旧的数据库版本获得官方技术支持**标记的功能仅限 SQL Server、Oracle 和 PostgreSQL。 MySQL 即将推出在团队版基础上增加更改报告***漂移检测***SQL 代码标准检查**迁移脚本自动生成**模式比较**静态数据版本控制**数据对比**测试数据管理克隆支持扩展的数据库版本集**标记的功能仅限 SQL Server、Oracle 和 PostgreSQL。 MySQL 即将推出***标记的功能仅限SQL Server、Oracle、PostgreSQL、SQLite
Flyway发行版本说明截止2023年2月15日最新发行版本为9.14.12023-02-01。
3.5 Flyway概念
使用 Flyway对数据库的所有更改都称为迁移migrations。迁移可以是版本化的或可重复的versioned or repeatable。版本化迁移有两种形式常规和撤销regular and undo。
3.5.1 版本迁移Versioned migrations
最常见的迁移类型是版本化迁移。每个版本化的迁移都有一个版本、一个描述 和一个校验和。版本必须是唯一的。该描述纯粹是为了让您能够记住每次迁移的作用。校验和用于检测意外更改。版本化迁移仅按顺序应用一次。
版本化迁移通常用于
创建/更改/删除表/索引/外键/枚举/自定义数据类型/…参考数据更新用户数据更正
CREATE TABLE car (id INT(11) NOT NULL PRIMARY KEY,license_plate VARCHAR(64) NOT NULL,color VARCHAR(32) NOT NULL
);ALTER TABLE owner ADD driver_license_id VARCHAR(64);INSERT INTO brand (name) VALUES (DeLorean);3.5.2 撤销迁移Undo migrations
撤销迁移与常规版本化迁移相反。撤销迁移负责撤销具有相同版本的版本化迁移的影响。撤消迁移是可选的不需要运行常规版本化迁移。该功能需要团队版或企业版才能使用。开源社区版不能使用。 注意撤销迁移实际上是对应版本的迁移完整的相反操作是为了撤消整个版本化的迁移而编写的如果在没有 DDL 事务的情况下对数据库进行版本化迁移失败了这时候执行撤销迁移是不一定能够成功的。需要有适当的、经过良好测试的备份和恢复策略。 例如对应上面的版本迁移的撤销迁移应该如下
DELETE FROM brand WHERE nameDeLorean;ALTER TABLE owner DROP driver_license_id;DROP TABLE car;具体可参考https://flywaydb.org/documentation/tutorials/undo
3.5.3 可重复迁移Repeatable migrations
可重复迁移有描述和校验和但没有版本。不是只运行一次而是在每次校验和更改时重新应用它们。 这对于管理数据库对象非常有用其定义可以简单地在版本控制中的单个文件中维护。 它们通常用于
创建更新视图/过程/函数/包/…批量引用数据重新插入
例如
CREATE OR REPLACE VIEW blue_cars ASSELECT id, license_plate FROM cars WHERE colorblue;具体可参考https://flywaydb.org/documentation/tutorials/repeatable
3.5.4 基于SQL迁移
迁移通常是用SQL编写的。这使得入门和利用任何现有脚本、工具和技能变得容易。它使您能够访问数据库的全套功能并且无需了解任何中间转换层。
基于 SQL 的迁移通常用于
DDL 更改TABLES、VIEWS、TRIGGERS、SEQUENCES 等的 CREATE/ALTER/DROP 语句……简单的引用数据更改引用数据表中的CRUD简单的批量数据更改常规数据表中的 CRUD
SQL文件命名规范 为了被 Flyway 识别SQL 迁移必须符合以下命名模式 文件名由以下部分组成 前缀V用于版本化可配置、 U用于撤消可配置和 R用于可重复迁移可配置 版本带点或下划线的版本根据需要分隔多个部分不适用于可重复迁移 分隔符__两个下划线可配置 描述下划线或空格分隔单词 后缀.sql可配置
3.5.5 基于Java迁移
基于 Java 的迁移非常适合所有无法使用 SQL 轻松表达的更改。
这些通常是这样的
BLOB 和 CLOB 更改高级批量数据更改重新计算、高级格式更改……
3.5.6 迁移状态
执行info命令可以打印有关所有迁移的详细信息和状态信息。
状态值描述Pending此迁移尚未应用Success本次迁移成功Ignored运行时忽略此迁移migrateDeleted这是一个通过修复repair已被标记为已删除的迁移Available如果需要此撤销undo迁移已准备好应用Undone此版本化迁移成功但已被撤消Above Target此迁移尚未应用并且不会应用因为target设置为较低版本Baseline该数据库迁移的基线baselineBelow Baseline此迁移未应用于此数据库因为模式历史表具有更高版本的基线baselinedMissing此迁移成功且无法解决Failed (Missing)此迁移失败且无法解决Failed此迁移失败Failed (Future) 此迁移失败其版本高于架构历史表的当前版本Future本次迁移成功其版本高于架构历史表的当前版本Out of Order 此迁移成功但应用顺序不正确。重新运行整个迁移历史可能会产生不同的结果Outdated这是一个可重复迁移过时的迁移应该重新应用Superseded这是可重复迁移一个过时的迁移已被更新的迁移取代3.6 Flyway基础命令
3.6.1 迁移migrate
将模式迁移到最新版本。如果模式历史表不存在Flyway 将自动创建它。 迁移是 Flyway 工作流程的核心。它将扫描文件系统或您的类路径以查找可用的迁移。它将它们与已应用于数据库的迁移进行比较。如果发现任何差异它将迁移数据库以缩小差距。
Migrate 最好在应用程序启动时执行以避免数据库与代码预期之间的任何不兼容。
3.6.2 清理clean
删除配置模式中的所有对象表、视图、过程、触发器……。 按照 schemas 和 defaultSchema 属性指定的顺序清理模式。 Clean对开发和测试有很大的帮助。通过彻底清除配置的模式它将有效地为您提供一个全新的开始。所有对象表、视图、过程……都将被删除。
不能对您的生产数据库使用因此默认配置是禁止清理的如果开发测试需要使用该命令需要设置cleanDisabled属性为false。
3.6.3 信息info
打印有关所有迁移的详细信息和状态信息。 info命令让你知道数据库与迁移当前的状态。您可以一目了然的看到哪些迁移已经应用哪些迁移仍在等待中它们何时执行以及它们是否成功。
3.6.4 验证validate
根据在文件系统或类路径上可用的迁移来验证数据库模式历史表中已经应用的迁移信息。
验证可帮助您验证应用于数据库的迁移是否与本地可用的迁移相匹配。
这对于检测可能阻止您可靠地重新创建架构的意外更改非常有用。
执行迁移时通过存储校验和SQL 迁移的 CRC32来验证工作。验证机制检查本地迁移是否仍然具有与数据库中已执行的迁移相同的校验和。 该功能只是验证数据库中的模式历史表中的迁移历史信息是否与文件系统上的迁移文件是否匹配防止版本话迁移文件被篡改或者文件丢失。对于未应用的迁移也会做出错误提示。添加-ignoreMigrationPatterns*:pending配置可忽略待应用的迁移错误提示。该命令无法校验具体的迁移脚本中的SQL是否完全正确能否执行成功。 3.6.5 撤销undo
撤消最近应用的版本化迁移。该功能只有团队版和企业版可以使用社区版不支持。
如果target指定Flyway 将尝试以与应用顺序相反的顺序撤消版本化迁移直到它遇到一个版本低于目标的版本或者一个没有相应撤消迁移的版本。如果group处于活动状态Flyway 将尝试在单个事务中撤消所有这些迁移。
如果没有要撤消的版本化迁移则调用撤消无效。
可重复迁移没有撤消功能。在这种情况下应修改可重复迁移以包含所需的旧状态然后使用migrate重新应用。
重要笔记 请注意如果您的部署中有破坏性更改删除、删除、截断等您应该小心。撤消迁移假定整个迁移成功现在应该撤消。
这意味着在没有 DDL 事务的数据库上失败的版本化迁移可能需要不同的方法。这是因为迁移随时可能失败。如果您有 10 个语句则第 1、第 5、第 7 或第 10 个可能会失败而撤消迁移将撤消整个版本化的迁移因此在这种情况下无济于事。
3.6.6 基线(baseline)
基线用于通过在特定版本上对现有数据库进行基线化将 Flyway 引入现有数据库。这将导致Migrate忽略直到并包括基线版本的所有迁移。然后将照常应用较新的迁移。 基线是和基线迁移功能配合使用的社区版不支持基线迁移实际上这个基线在社区版中的意义不大。也就是在非空的数据库模式中第一次使用flyway强制必须先设置基线。 在非空的数据库模式上第一次使用Flyway 进行迁移时会提示设置基线。 执行baseline命令在默认模式上创建模式历史表创建基线记录。
重置基线 当您有许多迁移时可能需要重置基线在团队版和企业版中可以使用基线迁移功能设置新的基线。这将允许您减少处理大量脚本的开销其中许多脚本可能是旧的且不相关的。https://flywaydb.org/documentation/tutorials/baselineMigrations 实际上就是把某个版本之前积累的旧的迁移SQL进行整理汇总成一个迁移脚本。脚本命名以B为前缀版本号设置为汇总的最大的版本号比如汇总了V1.0.5之前的所有迁移则命名为B1.0.5__description_info.sql在新的数据库中进行版本迁移则直接执行B1.0.5__description_info.sql而不会去执行V1.0.1-V1.0.5这些SQL减小处理开销当累积的迁移版本太多的时候也更加方便管理。 3.6.7 修复repair
修复模式历史表。 修复是修复模式历史表问题的工具。它有几个主要用途
移除失败的迁移条目仅适用于不支持 DDL 事务的数据库将已应用迁移的校验和、描述和类型与可用迁移重新对齐将所有丢失的迁移标记为已删除(因此repair必须与迁移的路径相同)
3.6.8 检查check
check生成报告以增加对迁移的信心。社区版不支持。
3.6.9 快照snapshot
snapshot 将 flyway.url 中指定的数据库模式捕获到一个文件中。辅助检查的命令社区版不支持。
这可用于生成数据库当前状态的快照以用于 check.deployedSnapshot 或拍摄构建数据库的快照以用于 check.nextSnapshot。
3.7 Flyway使用
建议简单测试使用命令行易于理解。项目开发中使用SpringBoot插件服务启动时自动执行迁移保证代码与数据库版本一致性。参考https://documentation.red-gate.com/fd/usage-184127227.html
3.7.1 在命令行中使用
Flyway 命令行工具是一个独立的 Flyway 发行版。它在 Windows、macOS 和 Linux 上运行主要适用于希望从命令行迁移数据库而无需将 Flyway 集成到他们的应用程序或安装构建工具的用户。 在命令行中使用Flyway进行数据库版本迁移是最简单最容易理解的。下面使用命令行进行简单的使用讲解。
安装
访问https://documentation.red-gate.com/fd/command-line-184127404.html选择适合系统版本的安装包下载后解压即可使用。
修改配置
在安装路径的/conf路径下修改flyway.conf文件中的配置保存后直接生效。
配置文件配置参考 配置参数详解 我们可以在配置文件中设置默认的配置在命令行执行命令将按照默认配置执行。也可以在命令行执行命令时增加参数按照命令中的参数配置执行。
例如我们修改了flyway默认连接的数据库的flyway.url,flyway.user和flyway.password驱动flyway.driver可以不配置flyway会根据flyway.url中的信息自动设置默认值。 默认的SQL脚本路径配置flyway.locationsfilesystem:sql,在文件系统中安装路径下的sql文件夹下。 测试时可能需要使用clean 命令清空数据库便于测试需要将禁用clean设置为否flyway.cleanDisabledfalse。
使用
在命令行执行flyway [options] [command]命令即可。
例如执行迁移flyway -defaultSchemaflyway-cmd-test2 migrate。 其中-defaultSchemaflyway-cmd-test2指定操作的数据库模式在MariaDB中即操作flyway-cmd-test2数据库 由于是在非空的数据库中第一次执行迁移需要创建基线会提示创建基线。
创建基线flyway [options] baseline 查看信息flyway [options] info
执行迁移前可以先查看信息了解当前数据库和迁移的状态flyway info。可以看到有6个版本迁移和一个可重复迁移处于待执行状态。
验证flyway [options] validate
根据在文件系统或类路径上可用的迁移来验证数据库模式历史表中已经应用的迁移信息。 如果存在以下问题会产生错误信息
发现迁移名称、类型或校验和的差异已应用的版本不再在本地解析存在已准备好但尚未应用的迁移版本存在迁移失败的版本
执行迁移flyway [options] migrate
可以看到执行完6个版本的迁移当前版本是V1.0.6 执行完迁移后查看信息可以看到创建了基线6个版本迁移和1个可重复迁移都迁移成功。
修复flyway [options] repair
如果迁移执行失败或者是修改了已经应用的版本迁移文件或者删除了某个版本迁移文件执行迁移命令前会自动进行验证验证报错无法进行迁移这时候需要使用修复命令来解决这些问题。 例如故意将V1.0.6版本中的SQL改错执行迁移后会产生错误迁移历史。 我们将V1.0.6版本迁移SQL修改正确后执行迁移会提示错误信息。 这时候需要执行修复命令删除模式历史表中的错误迁移记录才能再次执行迁移命令。
如果我们故意将V1.0.5版本的迁移文件的版本改为V1.0.5.1执行info命令可以看到当前数据库迁移版本为1.0.6V1.0.5版本的文件丢失新增的1.0.5.1版本因为版本号小于当前版本因此忽略不执行。 执行迁移命令也会报相应错误 执行修复后再执行info可以看到1.0.5版本被标记为删除但是1.0.5.1版本依然是被忽略我们如果要正常使用迁移要么设置参数-ignoreMigrationPatterns*:ignored忽略ignored状态的迁移要么删掉相关迁移文件。 因此我们在使用过程中一定要注意已应用的版本迁移文件不能修改。 清理数据库flyway [options] clean
在开发测试中如果需要删除测试数据可直接运行clean命令清空数据库模式中的所有对象包括表、视图、过程、触发器等。再次执行迁移则可生成干净的数据库。
3.7.2 在项目中使用SpringBoot插件进行数据库版本管理
在项目开发中建议使用Flyway的SpringBoot插件这样在运行服务的时候会自动执行迁移保证代码和数据库版本的一致性。
使用要求
在使用Flyway进行数据库版本管理之后对于数据库变更就只能通过Flyway进行要注意以下事项
不能直接运行SQL命令或者通过管理工具去修改公共库的表结构已经发布的sql脚本不允许修改建议每个开发人员都有一个专用的开发数据库方便排除故障确保上传到公共库的迁移脚本都是可稳定迁移的
正确的表结构调整途径在flyway脚本配置路径下编写新的脚本启动程序来执行变更。 这样可以获得几个很大的好处 4. 脚本受Git版本管理控制可以方便的找到过去的历史 5. 脚本在程序启动的时候先加载保证代码与数据库版本一致 6. 所有表结构的历史变迁在管理目录中根据版本号和描述信息就能很好的追溯
当每个开发人员都有一个专用的开发数据库时数据库开发效果最好引用官方文档google机器翻译 点击访问官网文档了解详细说明 虽然可以将Flyway Desktop与由多个用户共享的单个 开发数据库一起使用但 Redgate 建议您为每个用户提供一个专用的开发数据库。 Redgate 发现共享数据库开发环境增加了人为错误限制了团队成员进行实验的能力并减少了开发过程早期的功能测试。 实际上社区版功能有限只能简单进行数据库版本管理在团队版和企业版各种额外功能的支持下Redgate 公司都很难解决共享数据库开发环境产生的人为错误在使用社区版的时候更应该每个开发人员使用专用的数据库进行开发测试验证迁移脚本没有问题后再上传到Git由持续集成环境去执行健康稳定的迁移。 在项目中引入flyway依赖
在pom文件中引入flyway-core 的依赖SpringBoot的依赖管理中已经有相关版本配置但是MySQL5.7在Flyway8以上版本已经不支持了所以我这里指定了7.7.3版本。在Flyway8.2.1以上版本MySQL的的适配已经独立拆分出来了需要额外引用flyway-mysql的依赖。 properties!-- flyway数据库版本管理工具--!-- mysql5.7适用7.7.38.2.1以上mysql需要引入flyway-mysql;当前springboot自动引入8.0.5适用mysql8MariaDB--flyway.version7.7.3/flyway.version/properties!-- flyway数据库版本管理 --dependencygroupIdorg.flywaydb/groupIdartifactIdflyway-core/artifactIdversion${flyway.version}/version/dependency修改配置文件
在配置文件中配置spring.flyway相关配置框架会自动获取数据库连接配置多数据源时会默认使用master数据库。
spring:flyway:encoding: UTF-8# 禁用clean命令生成环境一定要设置为true否则万一执行了clean命令会清空数据库clean-disabled: true# 迁移脚本的位置默认db/migration可配置locations: classpath:/db/migration/MySQL# 迁移脚本中占位符的前缀默认为${placeholder-prefix: $${# 迁移脚本中占位符的后缀默认为}placeholder-suffix: }# 数据库中已经存在表结构数据中使用flyway需要设置为true,且版本号要比1大baseline-on-migrate: trueSpringBoot配置说明
名称描述默认值spring.flyway.baseline-description应用基线时标记现有模式的说明。 Flyway Baseline spring.flyway.baseline-on-migrate迁移非空模式时是否自动调用基线。falsespring.flyway.baseline-version执行基线时用于标记现有模式的版本。1spring.flyway.batchSQL语句执行时是否批处理。需要 Flyway 团队。spring.flyway.cherry-pickFlyway 在迁移或撤消时应考虑的迁移。当为空时将考虑所有可用的迁移。需要 Flyway 团队。spring.flyway.clean-disabled是否禁用数据库清理。truespring.flyway.clean-on-validation-error验证错误时是否自动调用clean。falsespring.flyway.connect-retries尝试连接到数据库时的最大重试次数。0spring.flyway.connect-retries-interval尝试连接到数据库时重试之间的最长时间。如果未指定持续时间后缀将使用秒。120sspring.flyway.create-schemasFlyway 是否应尝试创建 schemas 属性中指定的模式。truespring.flyway.default-schemaFlyway 管理的默认模式名称区分大小写。spring.flyway.detect-encoding是否尝试自动检测 SQL 迁移文件编码。需要 Flyway 团队。spring.flyway.driver-class-nameJDBC 驱动程序的完全限定名称。默认情况下根据 URL 自动检测。spring.flyway.enabled是否开启flyway。truespring.flyway.encodingSQL 迁移的编码。UTF-8spring.flyway.error-overrides用于覆盖特定 SQL 状态和错误代码的内置错误处理规则。需要 Flyway 团队。spring.flyway.fail-on-missing-locations如果迁移脚本的位置不存在是否失败。falsespring.flyway.group应用时是否将所有待处理的迁移分组到同一个事务中。falsespring.flyway.ignore-migration-patterns验证迁移时忽略与此逗号分隔的模式列表匹配的迁移。需要 Flyway 团队。spring.flyway.init-sqls获取连接后立即执行初始化连接的 SQL 语句。spring.flyway.installed-by架构历史记录表中记录的用户名已应用迁移。spring.flyway.jdbc-properties.*要传递给 JDBC 驱动程序的属性。需要 Flyway 团队。spring.flyway.kerberos-config-fileKerberos 配置文件的路径。需要 Flyway 团队。spring.flyway.license-keyFlyway Teams 的许可证密钥。spring.flyway.locations迁移脚本的位置。可以包含特殊的“{vendor}”占位符以使用特定于供应商的位置。[classpath:db/migration]spring.flyway.lock-retry-count尝试获取锁时的最大重试次数。50spring.flyway.mixed是否允许在同一迁移中混合事务性和非事务性语句。falsespring.flyway.oracle-kerberos-cache-fileOracle Kerberos 缓存文件的路径。需要 Flyway 团队。spring.flyway.oracle-sqlplus是否启用对 Oracle SQL*Plus 命令的支持。需要 Flyway 团队。spring.flyway.oracle-sqlplus-warn遇到尚未支持的 Oracle SQL*Plus 语句时是否发出警告而不是错误。需要 Flyway 团队。spring.flyway.oracle-wallet-locationOracle Wallet 的位置用于自动登录数据库。需要 Flyway 团队。spring.flyway.out-of-order是否允许迁移乱序运行。falsespring.flyway.output-query-resultsFlyway 在执行迁移时是否应输出包含查询结果的表格。需要 Flyway 团队。spring.flyway.password要迁移的数据库的登录密码。spring.flyway.placeholder-prefix迁移脚本中占位符的前缀。${spring.flyway.placeholder-replacement在迁移脚本中执行占位符替换。truespring.flyway.placeholder-separator默认占位符的分隔符。:spring.flyway.placeholder-suffix迁移脚本中占位符的后缀。}spring.flyway.placeholders.[placeholder name]设置 sql 迁移脚本的占位符的替换值。spring.flyway.repeatable-sql-migration-prefix可重复 SQL 迁移的文件名前缀。Rspring.flyway.schemasFlyway 管理的方案名称区分大小写。spring.flyway.script-placeholder-prefix迁移脚本中占位符的前缀。FP__spring.flyway.script-placeholder-suffix迁移脚本中占位符的后缀。__spring.flyway.skip-default-callbacks是否跳过默认回调。如果为真则仅使用自定义回调。falsespring.flyway.skip-default-resolvers是否跳过默认解析器。如果为真则仅使用自定义解析器。falsespring.flyway.skip-executing-migrationsFlyway 是否应该跳过执行迁移的内容只更新模式历史表。需要 Flyway 团队。spring.flyway.sql-migration-prefixSQL 迁移的文件名前缀。Vspring.flyway.sql-migration-separatorSQL 迁移的文件名分隔符。__spring.flyway.sql-migration-suffixesSQL 迁移的文件名后缀。[.sql]spring.flyway.sql-server-kerberos-login-fileSQL Server Kerberos 登录文件的路径。需要 Flyway 团队。spring.flyway.stream执行时是否流式传输 SQL 迁移。需要 Flyway 团队。spring.flyway.tableFlyway 将使用的模式历史表的名称。flyway_schema_historyspring.flyway.tablespace创建模式历史表的表空间。使用不支持表空间的数据库时忽略。默认为 Flyway 使用的连接的默认表空间。spring.flyway.target应考虑迁移到的目标版本。spring.flyway.url要迁移的数据库的 JDBC url。如果未设置则使用主要配置的数据源。spring.flyway.user要迁移的数据库的登录用户。spring.flyway.validate-migration-naming是否验证脚本不遵守正确命名约定的迁移和回调。falsespring.flyway.validate-on-migrate执行迁移时是否自动调用验证。true
添加迁移文件
在配置的迁移文件路径下创建各个版本的迁移文件。 启动服务
在idea中启动服务可以看到Flyway在连接数据库后验证需要执行三个迁移在迁移之前该数据库模式为空。并依次执行了三个迁移。
三个迁移成功执行 最终服务正常运行 在对应的数据库模式中可以看到模式历史表中的迁移历史记录
引入maven插件进行其他命令操作
由于SpringBoot插件只是在服务启动的时候根据配置验证并执行迁移无法进行其他操作如果想执行其他命令可以与Flyway命令行工具或者maven插件配合使用。
在pom文件中添加flyway-maven-plugin的插件更新依赖后在maven插件中即可看到Flyway的插件。点击即可执行相关命令操作。 buildpluginsplugingroupIdorg.flywaydb/groupIdartifactIdflyway-maven-plugin/artifactIdversion${flyway.version}/versionconfigurationurljdbc:mysql://192.168.16.211:3306/flyway-test/urlusertest/userpasswordtest123456/passworddrivercom.mysql.cj.jdbc.Driver/driverschemasflyway-test/schemaslocations!-- 迁移的sql的位置 --locationfilesystem:/yqsm-boot-module-system/src/main/resources/db/migration/MySQL/location!--locationclasspath:/db/migration/MySQL/location--/locations/configuration/plugin/plugins/build注意事项
我可以在 Flyway 之外对数据库进行结构更改吗
不能。能够依赖数据库中的元数据并进行可靠迁移的先决条件之一是所有数据库更改都由 Flyway 进行。没有例外。这种可靠性的代价是纪律。临时更改在这里没有空间因为它们实际上会破坏您的信心。如果之前已经手动添加过即使是添加索引这样简单的事情也可能会导致迁移失败。
迁移失败后如何修复数据库
如果您的数据库支持 DDL 事务Flyway 会为您完成工作。
如果您的数据库没有请遵循以下步骤
手动撤消迁移的更改调用修复命令修复失败的迁移再试一次
3.8 Flyway支持的数据库
Flyway官方文档表明其支持市面上常见的主流关系型数据库
Aurora MySQLAurora PostgreSQLAzure SynapseCockroachDBDB2DerbyFirebirdGoogle BigQueryGoogle Cloud Spanner (Beta)H2HSQLDBInformixMariaDBMySQLOraclePercona XtraDB ClusterPostgreSQLRedshiftSAP HANA (Including SAP HANA Cloud)SingleStoreDBSnowflakeSQLiteSQL ServerSybase ASETestContainers TiDB (Titanium DB)TimescaleDBYugabyteDB 但是有个很明显的缺点社区版只支持发布5年内的数据库版本团队版只支持发布10年内的数据库版本。像在项目中使用MySQL5.7版本在Flyway8以后社区版已经不再支持只能使用老版本。当我们的产品适配多个数据库使用不同版本时同时使用多个flyway版本会很混乱。 3.9 Flyway国产数据库支持扩展
官方鼓励为 Flyway 贡献数据库兼容性 https://documentation.red-gate.com/fd/contributing-database-compatibility-to-flyway-184127558.html
由于我们经常使用国产数据库对达梦、神通等国产数据库如何适配 可以参考以下几篇文章 flyway-4.2适配DM8数据库https://blog.csdn.net/babyzhongheng/article/details/115176744 数据管理工具flyway版本6.4.4新增达梦数据库适配https://blog.csdn.net/u012440725/article/details/124733837
3.10 生产应用总结
可以看到仅有少数几篇关于达梦数据库的适配适配达梦数据库对flyway源码改动不少而且受到flyway版本于相关国产数据库版本限制想要实现对国产数据库的适配难度和工作量还是很大的。
因此我们在使用MySQL、MariaDB、Oracle、Postgresql等国际主流数据库时可以使用flyway社区版来规范记录我们的数据库变动可以快速创建干净的数据库实例可以在生产环境中快速定位当前数据库的版本状态了解升级脚本是否正常运行。
3.11 其他技巧
3.11.1 注入环境
使用数据库时您通常会遇到不同的环境例如开发、测试或生产。在这些环境中的每一个中您可能希望执行不同的迁移这可以通过占位符和shouldExecute脚本配置参数来实现。参考官方文档 官方shouldExecute配置可能需要高版本才能支持在我们为了使用低版本数据库而不得已降低flyway版本时可能不支持该方法。我认为既然是不同环境使用不同的迁移脚本直接不同环境配置不同的脚本路径即可直接通过不同的路径提供相应环境的脚本简单易用。 3.11.2 占位符
可通过环境变量、配置参数或者api设置占位符的值。
默认占位符
Flyway 还提供默认占位符其值会自动填充 ${flyway:defaultSchema} Flyway 的默认模式 ${flyway:user} Flyway 将用于连接数据库的用户 ${flyway:database} 来自连接 url 的数据库名称 ${flyway:timestamp} Flyway解析脚本的时间格式为’yyyy-MM-dd HH:mm:ss’ ${flyway:filename} 当前脚本的文件名 ${flyway:workingDirectory} 由“user.dir”系统属性定义的用户工作目录 ${flyway:table} Flyway 模式历史表的名称
脚本配置文件
可以在每个脚本的基础上配置 SQL 迁移。
这是通过在与迁移相同的文件夹中创建脚本配置文件来实现的。 脚本配置文件名必须与迁移文件名匹配并添加.conf 后缀。 脚本配置文件不需要在主配置或命令行中明确列出。
例如一个迁移文件sql/V2__my_script.sql会有一个脚本配置文件sql/V2__my_script.sql.conf。
脚本配置文件具有来自其他配置 Flyway 方式的选项的子集例如flyway.conf。
3.12 错误汇总
3.12.1 错误1
Flyway Teams Edition or MySQL upgrade required: MySQL 5.7 is no longer supported by Flyway Community Edition, but still supported by Flyway Teams Edition.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name flywayInitializer defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.license.FlywayEditionUpgradeRequiredException: Flyway Teams Edition or MySQL upgrade required: MySQL 5.7 is no longer supported by Flyway Community Edition, but still supported by Flyway Teams Edition.
原因
当前Flyway社区版(我使用的是flyway-core 8.0.5)不再支持MySQL 5.7团队收费版本才支持。
解决方法
方法1
使用收费的团队版没钱一般不采用。
方法2当前采用
降低flyway-core的版本参考文章https://zhuanlan.zhihu.com/p/543779230指定flyway-core的版本为7.7.3即可。
方法3
提高MySQL的版本当前使用版本8.0.5Flyway社区版支持MySQL 8。 注意Flyway 8.2.1及以后版本不再直接支持MySQL需要单独引用flyway-mysql插件。
3.12.2 错误2
No value provided for placeholder: ${xxx}. Check your configuration!
Caused by: org.flywaydb.core.api.FlywayException: Unable to parse statement in db/migration/MySQL/V1.0.1__init_table.sql at line 2131 col 1. See https://rd.gt/3ipi7Pm for more information: No value provided for placeholder: ${填值规则编码}. Check your configuration!原因
没有为占位符${xxx}提供值。 检查你的配置原因是SQL脚本中字符串中存在${填值规则编码}被误认为是占位符。
解决方法
方法1
将spring.flyway.placeholder-replacement设置为false不替换sql脚本中的占位符。 关掉后可能会影响功能。建议使用方法2.
方法2当前采用
自定义设置占位符前缀,可避免与通用的默认前缀${引起歧义 spring.flyway.placeholder-prefix $${