Flyway 分工方案(DBA 执行 + 应用只读校验)

## 一、方案核心目标

    1. 规避应用账号高权限风险:应用仅拥有数据库 SELECT/INSERT/UPDATE/DELETE(CRUD)权限,无 ALTER/CREATE/DROP 等 DDL 权限,杜绝应用误操作表结构。
    1. 规范 DDL 管理:由 DBA 统一负责 Flyway 脚本审核、执行,确保表结构变更合规、可追溯。
    1. 保障环境一致性:应用启动时通过 Flyway 只读校验,确保本地/测试/生产的脚本版本、表结构完全一致,避免"脚本漏执行、版本不匹配"导致的线上故障。
    1. 适配现有权限体系:无需调整数据库权限分配,仅通过 Flyway 配置区分"执行角色"和"校验角色"。

## 二、核心分工(明确责任边界)

### (一)DBA 团队(高权限角色)

核心职责:负责 Flyway 脚本的审核、迁移执行、版本管理、异常处理,拥有数据库 DDL 全权限(ALTER/CREATE/DROP/INDEX 等)。

具体分工:

    1. 脚本审核:审核开发提交的 Flyway 迁移脚本(命名、语法、性能、安全性),杜绝不合理 DDL(如无索引查询、全表更新、冗余字段)。
    1. 迁移执行:在测试/预发/生产环境,使用高权限账号执行 Flyway 迁移命令,更新表结构和 flyway_schema_history 表。
    1. 版本维护:维护数据库中 flyway_schema_history 表的完整性,监控版本变更记录,排查版本冲突。
    1. 异常处理:迁移失败、版本不匹配、脚本错误等问题,由 DBA 主导排查修复(如回滚脚本、调整迁移顺序)。
    1. 权限管理:负责分配应用账号的数据库权限(仅开放 CRUD),管控高权限账号的使用。

### (二)开发团队(脚本提供角色)

核心职责:按规范编写 Flyway 迁移脚本,提交审核,配合 DBA 测试脚本,确保脚本可正常执行。

具体分工:

    1. 脚本编写:根据业务需求,编写符合 Flyway 命名规范、SQL 规范的 DDL 脚本(建表、加字段、加索引等)。
    1. 本地测试:在本地开发环境,使用测试账号(模拟高权限)执行脚本,验证脚本正确性、兼容性。
    1. 提交审核:将脚本提交至代码仓库(如 Git),发起审核流程,同步给 DBA 审核。
    1. 配合验证:DBA 执行脚本后,开发验证业务功能是否正常,确保表结构变更不影响现有功能。

### (三)应用部署团队(只读校验角色)

核心职责:配置 Spring Boot 项目的 Flyway 只读模式,确保应用启动时完成版本校验,无异常后正常启动。

具体分工:

    1. 配置部署:在应用配置文件中,配置 Flyway 只读校验相关参数(禁止自动迁移、开启校验)。
    1. 启动监控:应用启动时,监控 Flyway 校验日志,若出现版本不匹配,及时反馈给 DBA 和开发团队。
    1. 环境同步:确保应用部署包中的 Flyway 脚本,与 DBA 执行的脚本完全一致(同版本、同内容)。

## 三、完整执行流程(从脚本编写到应用部署)

### 步骤 1:开发编写 Flyway 脚本

    1. 开发根据业务需求,编写 DDL 脚本(如建表、加字段),严格遵循以下规范:
    • 命名规范:V{版本号}__{描述}.sql(如 V1__create_user_table.sql、V2__add_user_phone_column.sql),版本号递增,无重复。
    • 语法规范:符合 MySQL 8.0 语法,避免使用非标准 SQL;注释使用 <!-- 注释内容 -->(适配 MyBatis 规范);更新语句必须带主键条件,禁止全表更新。
    • 性能规范:新增索引需评估性能,避免冗余索引;复杂 DDL 需附带 EXPLAIN 分析报告,确保无全表扫描。
    1. 开发在本地开发环境,使用测试高权限账号,执行脚本验证(如 flyway migrate),确保脚本可正常执行,无语法错误、无数据影响。

### 步骤 2:脚本提交与 DBA 审核

    1. 开发将编写好的 Flyway 脚本,提交至代码仓库(如 Git),放置在项目 src/main/resources/db/migration 目录下,提交时备注脚本用途、影响范围。
    1. 开发发起脚本审核流程,通知 DBA 进行审核,提交材料包括:脚本文件、本地测试报告、EXPLAIN 分析报告(复杂脚本)。
    1. DBA 审核脚本:重点检查语法正确性、权限安全性、性能合理性、版本号规范性,审核通过则进入下一步;审核不通过,反馈问题给开发,开发修改后重新提交。

### 步骤 3:DBA 执行脚本迁移(按环境顺序)

    1. 环境执行顺序:测试环境 → 预发环境 → 生产环境,确保低环境验证无问题后,再执行高环境。
    1. 执行方式(两种可选,推荐方式 1):

方式 1:使用 Flyway 命令行(高权限账号)

  • 下载 Flyway 命令行工具,配置数据库连接(高权限账号、密码、URL)。

  • 执行命令:flyway migrate -locations=files:///脚本存放路径(如本地路径、代码仓库路径),执行完成后,检查 flyway_schema_history 表,确认版本已记录、执行状态为 SUCCESS。

方式 2:使用数据库客户端(高权限账号)

  • DBA 直接在数据库客户端(如 Navicat、DBeaver),复制 Flyway 脚本,手动执行,执行完成后,手动更新 flyway_schema_history 表(记录版本、脚本名称、执行时间、状态)。
    1. 执行后验证:DBA 执行脚本后,通知开发在对应环境验证业务功能,确认表结构变更正常,无异常。

### 步骤 4:应用配置与部署(只读校验)

  1. 应用部署团队,在 Spring Boot 项目的配置文件(application.yml 或 application.properties)中,配置 Flyway 只读校验参数,核心配置如下(两种格式可选):

格式 1:application.yml

```yaml

spring:

flyway:

enabled: true # 开启 Flyway(必须开启,否则不校验)

validate-on-migrate: true # 核心:启动时校验版本,不执行迁移

clean-disabled: true # 禁止清理数据库(必开,防止误删数据)

baseline-on-migrate: false # 禁止自动基线(避免创建默认基线版本)

locations: classpath:db/migration # 脚本存放路径(与开发提交的路径一致)

url: jdbc:mysql://数据库地址:端口/数据库名 # 应用数据库连接(只读/CRUD 权限)

user: 应用账号 # 仅拥有 CRUD 权限,无 DDL 权限

password: 应用密码

```

格式 2:application.properties

```properties

spring.flyway.enabled=true

spring.flyway.validate-on-migrate=true

spring.flyway.clean-disabled=true

spring.flyway.baseline-on-migrate=false

spring.flyway.locations=classpath:db/migration

spring.flyway.url=jdbc:mysql://数据库地址:端口/数据库名

spring.flyway.user=应用账号

spring.flyway.password=应用密码

```

  1. 应用部署:将配置好的应用包,部署到对应环境(测试/预发/生产),启动应用。

  2. 校验结果:

  • 校验通过:应用正常启动,Flyway 日志显示"Validation successful",表示应用脚本与数据库版本一致。

  • 校验失败:应用启动报错,日志显示"Validation failed",提示版本不匹配/脚本缺失,部署团队立即反馈给 DBA 和开发,排查问题(如 DBA 未执行对应版本脚本、应用脚本与 DBA 执行脚本不一致),解决后重新部署。

### 步骤 5:后期维护与异常处理

  1. 版本维护:DBA 定期检查 flyway_schema_history 表,清理无效版本记录,监控版本变更趋势;开发提交新脚本时,确保版本号连续,无跳跃、无重复。

  2. 异常处理场景:

  • 脚本执行失败:DBA 立即停止迁移,排查失败原因(语法错误、权限问题、数据冲突),修复后重新执行;若已执行部分脚本,需根据实际情况回滚(如执行回滚脚本 V{版本号}__undo_xxx.sql)。

  • 版本不匹配:应用启动校验失败,确认应用脚本与 DBA 执行的脚本版本是否一致,若应用脚本缺失,补充脚本后重新部署;若 DBA 未执行对应版本,DBA 补执行脚本后,重新启动应用。

  • 权限异常:若应用账号误获得 DDL 权限,DBA 立即回收权限;若 DBA 执行脚本时权限不足,联系数据库管理员提升权限。

## 四、关键规范(必须严格遵守)

### 1. 脚本规范

  • 版本号:按递增顺序编排(如 V1、V2、V3),禁止跳跃(如跳过 V2 直接用 V3)、禁止重复。

  • 内容:仅包含 DDL 语句(建表、加字段、加索引、删字段等),禁止包含 DML 语句(INSERT/UPDATE/DELETE);若需执行 DML,单独提交 DML 脚本,由 DBA 单独执行。

  • 兼容性:脚本需兼容 MySQL 8.0 版本,避免使用数据库特有语法,确保测试/预发/生产环境脚本可通用。

### 2. 权限规范

  • 应用账号:仅开放 SELECT/INSERT/UPDATE/DELETE 权限,禁止授予 ALTER/CREATE/DROP/INDEX 等 DDL 权限。

  • DBA 高权限账号:仅由 DBA 团队持有,禁止泄露给开发、部署人员;定期更换密码,管控使用记录。

### 3. 环境规范

  • 所有环境(开发、测试、预发、生产)的 Flyway 脚本必须保持一致,禁止不同环境使用不同版本的脚本。

  • 迁移执行必须按"测试→预发→生产"顺序,禁止跳过低环境直接在生产执行脚本。

### 4. 日志规范

  • DBA 执行脚本后,保存执行日志(包括执行时间、脚本名称、版本号、执行结果),便于后续排查。

  • 应用部署后,保存 Flyway 校验日志,若出现异常,及时提供日志给 DBA 和开发团队。

## 五、工具与辅助说明

  1. Flyway 工具:推荐使用 Flyway Community 版本(免费),支持命令行执行、配置文件配置,满足日常迁移和校验需求。

  2. 代码仓库:推荐使用 GitLab/GitHub,对 Flyway 脚本进行版本控制,支持审核流程、版本回溯。

  3. 监控工具:可集成 Prometheus + Grafana,监控 Flyway 版本状态、迁移执行情况,出现异常及时告警。

  4. 回滚方案:建议为每一个 DDL 脚本,编写对应的回滚脚本(命名格式:U{版本号}__{描述}.sql),由 DBA 保存,若迁移失败,可快速回滚。

### 补充:Flyway 命令行执行脚本模板(DBA 专用)

1. 命令行执行模板(通用版,适配所有环境)

(1)基础迁移命令(执行未执行的脚本)

```bash

配置数据库连接(高权限账号),执行指定路径下的 Flyway 脚本

flyway migrate \

-url=jdbc:mysql://数据库地址:端口/数据库名?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true \

-user=高权限账号 \

-password=高权限密码 \

-locations=files:///本地脚本存放路径(如:/home/dba/flyway-scripts) \

-cleanDisabled=true \

-validateOnMigrate=true

```

(2)指定版本执行(仅执行某一个版本脚本)

```bash

flyway migrate \

-url=jdbc:mysql://数据库地址:端口/数据库名?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true \

-user=高权限账号 \

-password=高权限密码 \

-locations=files:///本地脚本存放路径 \

-target=V2 # 指定执行到 V2 版本(仅执行 V2 及之前未执行的脚本)

```

(3)查看版本状态(检查已执行/未执行脚本)

```bash

flyway info \

-url=jdbc:mysql://数据库地址:端口/数据库名?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true \

-user=高权限账号 \

-password=高权限密码 \

-locations=files:///本地脚本存放路径

```

2. 命令行参数说明(关键必看)

  • url:数据库连接地址,需拼接 SSL、时区等必要参数,避免连接失败。

  • user/password:数据库高权限账号(需拥有 ALTER/CREATE 等 DDL 权限)。

  • locations:脚本存放路径,files:/// 后接本地绝对路径(如 Windows 路径:files:///D:/flyway-scripts)。

  • cleanDisabled=true:禁止清理数据库,必加,防止误删数据。

  • validateOnMigrate=true:执行迁移前先校验版本,避免版本冲突。

  • target:指定迁移目标版本,适用于分批次执行脚本场景。

### 补充:Flyway 回滚脚本示例(适配 MySQL 8.0)

回滚脚本命名规范:U{版本号}__{描述}.sql(U 代表 Undo,与对应迁移脚本版本一致),仅支持 Flyway Pro/Enterprise 版本直接执行;Community 版本可手动执行回滚脚本。

示例 1:建表脚本的回滚(对应迁移脚本 V1__create_user_table.sql)

迁移脚本(V1__create_user_table.sql)

```sql

-- 创建用户表

CREATE TABLE `user` (

`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',

`name` varchar(50) NOT NULL COMMENT '用户名',

`phone` varchar(11) DEFAULT NULL COMMENT '手机号',

`status` tinyint DEFAULT 1 COMMENT '状态:1正常,0禁用',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

```

回滚脚本(U1__drop_user_table.sql)

```sql

-- 回滚:删除用户表(与迁移脚本操作相反)

DROP TABLE IF EXISTS `user`;

```

示例 2:加字段脚本的回滚(对应迁移脚本 V2__add_user_email_column.sql)

迁移脚本(V2__add_user_email_column.sql)

```sql

-- 给用户表新增邮箱字段

ALTER TABLE `user`

ADD COLUMN `email` varchar(100) DEFAULT NULL COMMENT '邮箱' AFTER `phone`;

```

回滚脚本(U2__drop_user_email_column.sql)

```sql

-- 回滚:删除用户表邮箱字段(与迁移脚本操作相反)

ALTER TABLE `user`

DROP COLUMN IF EXISTS `email`;

```

示例 3:加索引脚本的回滚(对应迁移脚本 V3__create_user_phone_index.sql)

迁移脚本(V3__create_user_phone_index.sql)

```sql

-- 给用户表手机号字段加普通索引

CREATE INDEX idx_user_phone ON `user`(`phone`);

```

回滚脚本(U3__drop_user_phone_index.sql)

```sql

-- 回滚:删除用户表手机号索引(与迁移脚本操作相反)

DROP INDEX IF EXISTS idx_user_phone ON `user`;

```

回滚脚本注意事项

  1. 回滚脚本需与对应迁移脚本"反向操作",确保回滚后表结构恢复到迁移前状态。

  2. 所有回滚脚本需加 IF EXISTS 语句,避免回滚时因对象不存在报错。

  3. Flyway Community 版本不支持自动回滚,DBA 需手动执行回滚脚本;Pro/Enterprise 版本可通过 flyway undo 命令自动执行。

  4. 回滚脚本需与迁移脚本一同提交代码仓库,由 DBA 统一管理,避免遗漏。

## 六、方案优势

  1. 安全可控:应用无 DDL 权限,杜绝应用误操作表结构,降低线上故障风险。

  2. 规范有序:DDL 脚本由 DBA 统一审核、执行,确保表结构变更合规、可追溯,避免"一人一脚本"导致的混乱。

  3. 环境一致:应用启动时校验版本,确保本地/测试/生产脚本、表结构完全一致,解决"本地能跑、生产报错"的问题。

  4. 分工清晰:DBA、开发、部署团队各司其职,责任明确,减少沟通成本,提升协作效率。

## 七、注意事项

  1. 脚本提交前,开发必须本地测试,避免提交无效脚本,增加 DBA 审核和执行成本。

  2. DBA 执行脚本前,需备份对应数据库/表,避免脚本执行失败导致数据丢失。

  3. 应用部署前,需确认 DBA 已在对应环境执行完所有对应版本的脚本,避免校验失败。

  4. 若需新增 Flyway 脚本版本,需提前通知 DBA,避免 DBA 遗漏执行。

相关推荐
小短腿的代码世界4 小时前
Qt布局系统源码深度解析:QLayout如何操控你的界面——从QBoxLayout到QGridLayout的底层引擎揭秘
开发语言·数据库·qt
青云计划4 小时前
数据库的ID的另一种选择-雪花算法
数据库·算法
YL200404264 小时前
MySQL-进阶篇-视图/存储过程/触发器
数据库·mysql
qq_401700414 小时前
Qt 中使用 SQLite 数据库以及数据库连接池的设计与实现
数据库·qt·sqlite
arronKler4 小时前
数据库性能优化三:程序操作优化
数据库·oracle
墨着染霜华4 小时前
MySQL字符串数字筛选与转换 + Java Integer/Long数值长度避坑指南
java·数据库·mysql
2401_850491654 小时前
Bootstrap和OpenLayers结合开发的示例
jvm·数据库·python
Royzst4 小时前
集合进阶(Map集合)
java·前端·数据库
Java识堂4 小时前
MongoDB架构详解
数据库·mongodb·架构