数据库架构变更 | MySQL 事务性 DDL 语句

DB Schema Alteration | MySQL Transactional DDL Statements

持续交付

我正在构建一个带有 MySQL 数据库的应用程序,用于关系存储。该应用程序被设计为持续交付,为此,应用程序数据库必须就地升级。

基本方法

1. Application -> Transactional Statements -> DB -> Table View (Schema Version) -> Table

单个数据库用于所有应用程序版本。最新的模式版本定义了真实的 table 结构,通过模拟以前模式的 table 视图支持以前的模式版本。

2. Application -> Transactional Statements -> DB (Schema Version) -> Table

发布新模式时,将复制数据库并将模式更改应用于新数据库。启动流程后旧数据库上的事务将被跟踪并应用于新数据库。

升级完成后(所有应用程序部署都已切换到新架构),旧数据库将被转储。

首选选项 1

选项 2 在技术上很简单,因为不需要修改活动数据库的架构。但是,如果数据库增长到相当大的规模,那么资源消耗将变得巨大;因此,这种方法可以支持的应用程序大小存在实际限制。

因此,选项 1 更可取,但它提出了应用事务性 DDL 语句的问题。

事务性 DDL 语句策略

如何修改数据库 Table 和相应的 Table 视图而不冒数据损坏或应用程序访问数据库的能力中断的风险?

我目前的想法是按如下方式处理更改:

  1. Apply creations and additions
    1. create new tables
    2. create new columns
  2. Apply column renaming
    1. Lock table view (and, by extension, the base tables)
    2. Rename column
    3. Modify table view to use the new target column name
    4. Unlock table view
  3. Apply table renaming
    1. Lock table view (and, by extension, the base tables)
    2. Rename base table
    3. Modify table view to use new base table name
    4. Unlock table view

从那里开始,将创建新架构 table 视图,以便在部署下一个架构更改时可以使用相同的策略。

注意:任何已删除的列或 tables 将在转换期间保留,但将重命名为追加 _deprecate 或其他一些标识后缀

问题

据我了解,事务性 DDL 语句在 MySQL 中 不可能 ,因为这些语句将触发隐式提交。 这是正确的吗?

我上面描述的选项 1 方法行得通吗?

具体来说,我有两个顾虑:

  1. Table 导致应用程序中断的锁。 这里唯一的问题是单个 table 锁持续时间太长以至于等待连接超时?如果是这样,这应该可以通过在应用程序暂存期间测试每个 table 锁定的持续时间来管理。

  2. 回滚 我显然没有这种安排的自动回滚。但是,我所需要的只是通过对 table 视图的更改来镜像对基础 table 的任何修改。 是否可以在单个事务中对基础 table 和 table 视图应用更改? 如果不能,我将不得不在之前进行非常彻底的测试部署架构更改。

MySQL 不支持事务性 DDL,而且可能永远不会。

不过您可以使用 different 数据库。

您可以使用 liquibase 并手动处理您的 rollbacks