mirrord DB 分支 Schema Migrations 完全指南:让分支数据库带着你的迁移就绪

发布时间:2026/10/13 9:42:59
mirrord DB 分支 Schema Migrations 完全指南:让分支数据库带着你的迁移就绪
开发工具云原生CLI【免费下载链接】mirrordRun any process, on your machine or in an AI agents environment, as if it were a pod in your Kubernetes cluster: real env vars, DNS, network, traffic.项目地址https://gitcode.com/gh_mirrors/mi/mirrord点击查看免费下载本篇技术指南围绕 mirrord 的 DB 分支DB Branching功能深入讲解其migrations配置字段如何在分支数据库创建时自动运行 Flyway、Liquibase 或自定义容器迁移让分支一诞生就具备你的代码所期望的 Schema。读完本文你将掌握三种迁移 flavor 的完整配置语法、迁移历史表的携带方式、迁移 Job 的环境注入与管理员管控机制以及迁移失败时的集群排查手段。为什么需要 Schema MigrationsDB 分支在克隆时会携带源数据库当时的 Schema或按copy.mode的不同完全不携带任何 Schema。但无论哪种方式分支都不会包含只存在于你工作区、尚未应用到源数据库的迁移文件。这会造成一个典型问题你的代码依赖新表、新列而分支数据库还是旧 Schema开发与验证无从谈起。migrations字段正是为了弥合这个缺口mirrord 会在分支创建完成后自动对分支运行你的 Schema 迁移使分支以你的代码所期望的 Schema 状态就绪。该字段适用于 MySQL、MariaDB、PostgreSQL、CockroachDB 与 MSSQL 五种数据库引擎。关于 DB 分支的一般概念与完整字段列表参见 DB Branching 概览。各能力的最低版本要求能力mirrord CLIOperatorHelm chartSchema migrationsFlyway、本地path3.230.03.182.03.182.0MariaDB 分支上的迁移3.235.03.186.03.186.0镜像内置 Flywaylocations、containerflavor3.238.03.187.03.187.0继承目标环境containerflavor3.238.03.191.03.191.0Liquibase 迁移liquibaseflavor3.257.03.207.03.207.0Liquibase 支持、container 与镜像内置 Flyway flavor 的演进也可以在仓库 CHANGELOG.md 中查到对应条目。工作原理一次迁移的完整生命周期当你的会话启动一个带migrations配置的分支时流程分三步克隆阶段Operator 创建分支数据库 Pod并按copy.mode把源 Schema/数据克隆进分支。此阶段不涉及迁移。迁移阶段一旦分支数据库可以接受连接Operator 就在其旁边以一次性 Kubernetes Job的形式运行你的迁移。Job 使用分支自己的管理员凭据连接分支——永远不会连接源数据库。就绪判定只有 Job 成功分支才会变为 ready你的会话才针对已完整迁移的分支启动。若 Job 失败会话中止mirrord 直接打印 Job 的日志输出——你的应用绝不会运行在半迁移的 Schema 上。当一个会话复用一个已有分支且迁移集合发生了变化时Operator 会为增量delta运行新的 Job。某个迁移与已应用的迁移冲突例如编辑了已应用的 Flyway 文件或 Liquibase changeset只会让当前会话失败分支仍可供其他会话使用。flavor字段决定 Job 运行什么按你的迁移文件存放位置来选择你的迁移文件...使用位于你正在工作的仓库中的 Flyway SQL 文件flavor: flywaypath打包进 CI 发布的镜像中的 Flyway SQL 文件flavor: flywayimagelocations位于你正在工作的仓库中的 Liquibase changelogflavor: liquibasepath打包进 CI 发布的镜像中的 Liquibase changelogflavor: liquibaseimagesearch_path属于应用自身工具链的一部分打包进镜像的迁移脚本或框架 CLIflavor: container使用migrations有两个前提约束分支的name字段必须设置。这一点在配置层有硬性校验——database_branches.rs 中的verify方法会在database.name缺失时直接报错feature.db_branches[].migrations requires feature.db_branches[].name to be set.。分支的creation_timeout_secs覆盖整个启动过程克隆源库、拉取迁移镜像、运行迁移都算在内。如果迁移很慢或迁移镜像很大请调大该值。把迁移历史携带到分支上copy: { mode: schema }只复制表定义、不复制行——包括你的迁移工具记录已应用迁移的历史表。要让迁移历史也上分支需要把历史表列在tables下使其定义与数据一起被复制。Flyway 的历史表{ copy: { mode: schema, tables: { flyway_schema_history: {} } } }Liquibase 维护两张表两张都必须带过来{ copy: { mode: schema, tables: { DATABASECHANGELOG: {}, DATABASECHANGELOGLOCK: {} } } }Flyway 迁移设置flavor: flyway即可运行带版本号的 SQL 文件V1__create_users.sql、V2__add_orders.sql……。Flyway 会在分支内部的一张flyway_schema_history表中记录已应用的迁移因此重复运行只会应用新增的部分。注意与copy.mode的交互Flyway 拒绝迁移一个已有对象但没有flyway_schema_history表的 Schema。因此若源数据库本身不是Flyway 管理的请使用copy: { mode: empty }让迁移从零构建分支 Schema若源数据库是 Flyway 管理的all会把历史表的数据连同其他内容一起带过来Job 只需应用你更新的文件schema则需要特殊配置来携带历史表。字段说明字段描述path迁移文件的本地目录相对于你的工作目录解析。与locations互斥。locationsimage内存放迁移文件的 Flyway locations适用于 SQL 已打包进镜像的场景。与path互斥且要求设置image。image迁移运行镜像。与path搭配时可选默认flyway/flyway:12与locations搭配时必填。path与locations必须且只能设置其一。这一互斥与必选关系在配置层有专门校验verify_file_sourcedatabase_branches.rs会拒绝两者都设或两者都不设的配置并在用locations时强制要求image。从本地目录运行使用path时mirrord 会把目录上传压缩后上限 1 MiBJob 用标准 Flyway 镜像对目录运行。适合迁移文件就在你当前仓库里的场景{ feature: { db_branches: [ { type: pg, version: 17, name: users-database-name, connection: { url: DATABASE_URL }, migrations: { flavor: flyway, path: ./migrations } } ] } }上传环节的实现细节Operator 客户端把本地目录打成gzipped tardatabase_branches.rs 中的read_migration_archive设置了LIMIT 1024 * 1024即 1 MiB 上限且打包是确定性的——相同的迁移总是产生相同的字节见build_migration_archivedatabase_branches.rs。超出上限会以MigrationsTooLarge错误拒绝。从迁移镜像运行使用locations时什么都不上传SQL 已经打包在迁移镜像里通常由 CI 发布Job 运行该镜像并把 Flyway 指向镜像内的路径。适合你的部署流水线本来就用这种镜像迁移共享数据库、预览应运行完全相同的产物的场景{ migrations: { flavor: flyway, image: registry.example.com/my-migrations:latest, locations: [filesystem:/flyway/sql] } }locations支持多个条目会被拼接进FLYWAY_LOCATIONS环境变量。Liquibase 迁移设置flavor: liquibase即可运行 Liquibase changelog支持 XML、YAML、JSON 或格式化 SQL。Liquibase 在分支内部的DATABASECHANGELOG表中记录已应用的 changeset重复运行只应用新增部分。与 Flyway 扫描目录不同Liquibase 从单个根 changelog出发因此changelog_file必填。字段说明字段描述changelog_file根 changelog 文件在搜索根目录内解析。会被记录进DATABASECHANGELOG所以修改它会重新运行所有 changeset。pathchangelog 文件的本地目录相对于工作目录解析。与search_path互斥。search_pathimage内的 Liquibase 搜索路径。与path互斥且要求设置image。image迁移运行镜像。与path搭配时可选默认liquibase/liquibase:4.33与search_path搭配时必填。path与search_path必须且只能设置其一。驱动兼容性提醒Liquibase 4.33 自带了 PostgreSQL、MariaDB 与 SQL Server 驱动自定义image必须自带与你方言匹配的驱动且 MySQL 分支通过jdbc:mariadb://连接。与copy.mode的交互同 Flyway 一致源库非 Liquibase 管理时用copy: { mode: empty }让 changelog 从零建 Schema源库是 Liquibase 管理时all会把两张历史表一起带过来schema则需要特殊配置。从本地目录运行使用path时mirrord 上传目录压缩后上限 1 MiBJob 运行标准 Liquibase 镜像。changelog_file指明目录内的根 changeloginclude/includeAll路径都相对它解析{ feature: { db_branches: [ { type: pg, version: 17, name: users-database-name, connection: { url: DATABASE_URL }, migrations: { flavor: liquibase, path: ./changelog, changelog_file: db.changelog-master.xml } } ] } }从迁移镜像运行使用search_path时什么都不上传changelog 已打包进镜像Job 运行该镜像并把 Liquibase 指向镜像内路径{ migrations: { flavor: liquibase, image: registry.example.com/my-migrations:latest, search_path: [/liquibase/changelog], changelog_file: db.changelog-master.xml } }search_path支持多个条目拼接进LIQUIBASE_SEARCH_PATHLiquibase 会依次在每个条目下查找changelog_file。Container 迁移运行你自己的镜像设置flavor: container会把你自己的镜像作为迁移 Job 运行。这适合迁移并非独立 SQL 文件、而是应用自身工具链一部分的场景——例如应用镜像的 setup 脚本运行框架的迁移命令{ migrations: { flavor: container, image: registry.example.com/my-app:latest, command: [bundle, exec, rake, db:migrate] } }字段说明字段描述image迁移容器的完整镜像引用含 tag。command可选Entrypoint 命令覆盖。不设置时运行镜像自身的 entrypoint。args可选Entrypoint 参数覆盖。env可选容器的额外环境变量。同名的条目会覆盖继承值。容器在迁移成功时必须以退出码 0 结束任何其他退出码都会使 Job以及你的会话失败错误信息就是容器的日志。command与args就是 Kubernetes 容器的command/args所以 Pod spec 能运行的任何形式都可以——只要它在镜像内存在container flavor 不从你的机器上传任何东西。常见形态command: [/app/bin/migrate]command: [sh, -c, /app/bin/migrate /app/bin/seed]用串联多个脚本让第一个失败就中断整条链并使 Job 失败。Job 运行在你的应用环境中Container 迁移 Job 会自动继承目标容器的env与envFromConfigMap 和 Secret。这一点很关键当迁移命令要启动整个应用Rails 的rake db:migrate、Django 的manage.py migrate且应用需要完整配置才能启动时Job 获得与应用自身 Pod 完全相同的环境无需把任何东西复制进migrations.env。基于 Secret 的值保持为 Kubernetes 引用Operator 从不读取它们。继承环境中包含应用真实的数据库连接值所以 Operator 会做重定向分支connection中命名的每个变量在 Job 上都被设置为分支的值优先级高于继承值。你的迁移工具读取它惯用的变量上面 Rails 例子的DATABASE_URL就会落在分支上——通过 mirrord 已知的每个变量源数据库都不可达。无法识别连接变量的情况如果 Operator 无法判断哪些变量携带连接——connection通过secret、gcp_secret_manager或aws_secrets_manager源声明且未提供env_var_name——迁移会直接失败并报错而不是带着源连接跑在环境里。解决办法给源加env_var_name、改用基于 env 的连接参数或让集群管理员关闭migrationEnv.inherit。多容器目标Job 从目标路径命名的容器继承deployment/app/container/main。未指定容器时使用定义了某个声明连接变量的容器回退到第一个容器——这样排在你应用前面的 sidecar 不会捐献它的环境。五层环境合并Job 的环境合并五层同名出现时胜出顺序最强在前为你的migrations.env 注入的MIRRORD_DB_* 分支重定向的连接变量 管理员的migrationEnv 继承的目标环境。因此migrations.env中的条目是逃生舱任何不应作用于迁移的继承值或管理员值都可以用它覆盖例如强制指定RAILS_ENV。管理员对 Job 环境的管控集群管理员可按数据库类型——以及按分支配置 profile——通过 Operator Helm values 中的migrationEnv调整此行为mysqlBranchConfig: dbPod: migrationEnv: inherit: true # 默认值设为 false 时 Job 只有 MIRRORD_DB_* 和 migrations.env env: - name: RAILS_ENV value: development - name: API_KEY valueFrom: secretKeyRef: name: migration-secrets key: api-key envFrom: - configMapRef: name: shared-migration-config字段描述inheritJob 是否继承目标容器的env/envFrom。默认true。env每个迁移 Job 的额外变量使用普通 Kubernetesenv形态——valueFrom可用所以 Secret 值留在集群内。同名条目覆盖继承值但绝不覆盖分支重定向的连接变量。envFrom额外的 ConfigMap/Secret 引用追加在目标自身之后因此冲突时它们的键胜出。这适合提供每个迁移都需要但目标不携带的值或配合inherit: false给 Job 一个完全由管理员策划的环境而不是应用的。从你的容器访问分支Operator 会把分支连接以环境变量形式注入容器变量值MIRRORD_DB_HOST分支数据库主机。MIRRORD_DB_PORT分支数据库端口。MIRRORD_DB_USER分支引擎的默认管理员用户。MIRRORD_DB_PASSWORD分支的 root 密码。分支无密码时省略。MIRRORD_DB_NAME分支数据库名。大多数工具用不到它们应用惯用的连接变量已被继承并重定向到分支。MIRRORD_DB_*是给显式接线用的当继承不够时组合你的工具读取的变量在env、command或args中使用 Kubernetes 的$(VAR)展开——例如env: { DATABASE_URL: mysql://$(MIRRORD_DB_USER):$(MIRRORD_DB_PASSWORD)$(MIRRORD_DB_HOST):$(MIRRORD_DB_PORT)/$(MIRRORD_DB_NAME) }。这不需要改动镜像。在脚本中从环境读取psql -h $MIRRORD_DB_HOST ...或改db_setup.sh让它优先使用MIRRORD_DB_*。注意这些是分支的凭据刻意不是源数据库的——Job 需要分支的管理员权限且绝不能碰共享数据库。这一注入机制同样定义在 CRD 层branch_database.rs。在 CI 中组合配置预览流水线通常会在准备配置时决定镜像 tag 和命令——mirrord 最终收到的是一个普通配置例如{ migrations: { flavor: container, image: registry.example.com/my-app:build-1234, command: [bin/migrate] } }如何填充这些值完全由流水线决定此外mirrord 配置文件还支持 Tera 模板化可以直接从环境中读取这些值。迁移失败时怎么办迁移失败会中止你的会话mirrord 打印的错误就是 Job 自身的日志输出——一条 Flyway 错误或你的容器以非零退出码退出前写下的任何内容。要在集群中进一步排查分支资源记录了结果kubectl get branchdatabases -n namespace查看status.migrationsphase以及失败时的错误文本。这个字段还作为 CRD 的打印列暴露branch_database.rs。Job 命名为mirrord-migrations-branch-uid-generationkubectl logs job/name可查看完整运行包括成功的。你可能遇到的失败类型某条迁移有 SQL 错误修好文件新会话会重跑它复用分支上编辑了已应用的 Flyway 文件或 Liquibase changeset校验和冲突——只让你的会话失败镜像被管理员的allowedImages列表拒绝镜像拉取失败被中断的 Liquibase 迁移遗留的DATABASECHANGELOGLOCK行仍被持有container迁移的连接变量 Operator 无法重定向见上文Job 运行在你的应用环境中。限制迁移镜像集群管理员可以通过 Operator Helm values 中每种数据库的dbPod.allowedImages列表限制可接受的镜像。该列表适用于用户提供的每一个迁移镜像——containerflavor 的image以及flyway/liquibaseflavor 上的任何migrations.image覆盖无论迁移文件是上传的还是打包在镜像里——与它对分支数据库镜像的限制方式相同。不允许的镜像会在任何东西运行之前就以明确的错误失败。flavor 的默认镜像不会参与该列表匹配dbPod.migrationImages.tool.registry控制这些默认镜像从哪里来。小结migrations字段把数据库迁移这一步完整地接入了 DB 分支的生命周期分支克隆完成后由 Operator 以一次性 Kubernetes Job 运行迁移成功才就绪失败即中止会话并给出 Job 日志。Flywaypath/locations、Liquibasepath/search_path与 container 三种 flavor 覆盖了从仓库内 SQL 文件到镜像内置迁移再到应用自身工具链的全部场景copy.mode与历史表的配合决定了迁移能否增量执行MIRRORD_DB_*注入、五层环境合并与管理员的migrationEnv/allowedImages则提供了从开发到集群治理的完整控制面。配置字段的互斥校验、1 MiB 上传上限、确定性的打包算法与 CRD 层的MigrationsSpec结构都可以在 database_branches.rs、branch_database.rs 与 database_branches.rs 中继续深挖。赞分享开发工具云原生CLI【免费下载链接】mirrordRun any process, on your machine or in an AI agents environment, as if it were a pod in your Kubernetes cluster: real env vars, DNS, network, traffic.项目地址https://gitcode.com/gh_mirrors/mi/mirrord点击查看免费下载相关推荐mirrord Google Cloud Spanner 数据库分支DB Branching配置指南mirrord Google Cloud Spanner 数据库分支DB Branching配置指南 本篇技术指南以 mirrord 的 db_branch开发工具云原生CLImirrord Redis 数据库分支DB Branching实战指南远程分支、本地分支与 TLS 配置全解mirrord Redis 数据库分支DB Branching实战指南远程分支、本地分支与 TLS 配置全解 导读 本文面向使用 mirrord 的开发者开发工具云原生CLImirrord ClickHouse 数据库分支DB Branching配置与实战指南mirrord ClickHouse 数据库分支DB Branching配置与实战指南 导读 本文介绍 mirrord 的 ClickHouse 数据库分开发工具云原生CLI上一篇技术适配器为你的业务场景定制Vanna AI部署方案下一篇高性能地理空间索引系统H3-Py Python绑定架构深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考