【发布时间】:2016-03-18 16:19:23
【问题描述】:
持续交付
我正在使用 MySQL 数据库构建一个用于关系存储的应用程序。应用程序是为持续交付而设计的,为此,应用程序数据库必须就地升级。
基本方法
1. Application -> Transactional Statements -> DB -> Table View (Schema Version) -> Table
单个数据库用于所有应用程序版本。最新的 schema 版本定义了真实的表结构,以前的 schema 版本通过模拟以前的 schema 的表视图来支持。
2. Application -> Transactional Statements -> DB (Schema Version) -> Table
发布新架构时,会复制数据库并将架构更改应用于新数据库。启动流程后旧数据库上的事务将被跟踪并应用于新数据库。
升级完成后(并且所有应用程序部署都切换到新架构),旧数据库将被转储。
选项 1 是首选
选项 2 在技术上很简单,因为不需要修改活动数据库的架构。但是,如果数据库增长到相当大的规模,那么资源消耗将变得相当大;因此,这种方法可以支持的应用程序大小存在实际限制。
因此,选项 1 是首选,但它存在应用事务性 DDL 语句的问题。
事务性 DDL 语句策略
如何修改数据库表和相应的表视图而不会有数据损坏或应用程序访问数据库能力中断的风险?
我目前的想法是按如下方式处理更改:
- 应用创建和添加
- 创建新表
- 创建新列
- 应用列重命名
- 锁定表视图(以及扩展的基表)
- 重命名列
- 修改表视图以使用新的目标列名称
- 解锁表格视图
- 应用表重命名
- 锁定表视图(以及扩展的基表)
- 重命名基表
- 修改表视图以使用新的基表名称
- 解锁表格视图
从那里,将创建新的架构表视图,以便在部署下一次架构更改时可以使用相同的策略。
注意:任何已删除的列或表将在转换期间保留,但将重命名为附加 _deprecate 或其他一些标识后缀
问题
据我了解,事务性 DDL 语句在 MySQL 中是不可能的,因为这些语句会触发隐式提交。 这是正确的吗?
我在上面描述的选项 1 方法有效吗?
具体来说,我有两个担忧:
表锁导致应用程序中断。这里唯一的问题是单个表锁持续时间过长导致等待连接超时吗?如果是这样,这应该可以通过在应用程序暂存期间测试每个表锁定的持续时间来管理。
回滚我显然没有这种安排的自动回滚。但是,我所需要的只是对基表的任何修改都与对表视图的更改进行镜像。 是否可以在单个事务中同时对基表和表视图应用更改?如果不能,我只需要在部署架构更改之前进行非常彻底的测试。
【问题讨论】:
标签: mysql transactions database-schema ddl continuous-delivery