关于 mz-deploy
mz-deploy 是面向 Materialize 的声明式 SQL 项目工具,适用于通过 Git 管理数据库环境的团队。它结合离线校验和本地测试,并支持先暂存、再原子式发布。
主要功能
- 01离线编译并进行类型检查
- 02在本地 Materialize 容器中测试
- 03以声明方式管理基础设施
- 04暂存变更的视图和物化视图
- 05原子式发布部署
- 06配置 profile 和 SQL 变量
适用场景
- 01在 CI 中无数据库连接地校验 SQL 项目
- 02使用模拟依赖测试视图变更
- 03通过暂存流程部署数据库变更
- 04将协调后的变更发布到生产环境
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ materializeinc/ agent-skills --skill mz-deploy安装后在 Claude Code 中输入/mz-deploy确认已加载。
附带文件references/unit-tests.md
详细介绍
mz-deploy
mz-deploy 是面向 Materialize 的声明式 SQL 项目工具。项目是一个由 git 跟踪的目录,其中包含描述 Materialize 环境期望状态的 .sql 文件;mz-deploy 会编译这些文件、离线进行类型检查、在本地容器中测试,并通过先暂存再提升的原子生命周期部署更改。
brew install materializeinc/materialize/mz-deploy
运行前先了解
CLI 会自我说明,其帮助文本是权威信息来源。不要猜测命令名称、标志或参数顺序。
mz-deploy help— 按用途分组的所有命令。mz-deploy help <command>— 某个命令的详细用法指南:行为、每个标志、示例、错误恢复和退出代码。mz-deploy help profiles— 配置主题指南(配置文件、变量、后缀、文件覆盖、TLS)。
本技能介绍相关概念和工作流的大致结构,帮助你了解应该使用哪个命令。运行命令前,请先阅读该命令的 help,了解其标志。
请在项目根目录中运行命令,或传入 -d <path>。值得了解的全局选项:-p/--profile 用于选择连接配置文件,--output json 用于输出机器可读内容(大多数命令都支持,在 CI 中很有用),-v 用于启用详细调试,-q 用于抑制提示性输出。
项目布局
project.toml # project config: mz_version, dependencies, per-profile settings
profiles.toml # connection profiles (also resolved from ~/.mz)
.mzprofile # gitignored per-checkout default profile
types.lock # cached schemas of external dependencies, for offline type checking
target/ # gitignored local build cache (safe to delete; see `clean`)
models/
<database>/
<schema>.sql # schema mod file — schema-level statements (see below)
<schema>/
<object>.sql # one view, materialized view, table, source, sink, connection, or secret
clusters/<name>.sql # cluster definitions (+ their GRANTs)
roles/<name>.sql # role definitions
network-policies/<name>.sql
路径决定对象的完全限定名称:models/materialize/catalog/clusters.sql 中的 MV 名称为 materialize.catalog.clusters。架构修改文件 — 与 <schema>/ 目录并列的 <schema>.sql — 用于存放适用于整个架构的语句,例如 SET api = stable。
mz-deploy new <name> 会在新目录中搭建此结构;init 则会在当前目录中执行相同操作。
命令一览
| 分组 | 命令 |
|---|---|
| 入门 | new、init、profile(list/set/current)、setup、debug |
| 开发 | compile、clean、test、explain、dev、lsp、sql、mcp |
| 基础设施 | lock、apply、delete |
| 部署 | stage、wait、promote、abort、describe、list、log |
一次性引导设置:mz-deploy setup 会创建 _mz_deploy 跟踪数据库、其中的表、_mz_deploy_server 集群以及三个角色。启用 RBAC 时,必须由超级用户运行此命令,因为该命令会授予系统权限。之后的所有操作都可以由普通用户运行。
工作流
mz-deploy compile # parse, resolve dependencies, type-check offline
mz-deploy test # run unit tests in a local Materialize container
mz-deploy apply # converge infrastructure (see below)
mz-deploy stage # deploy changed views/MVs to suffixed staging schemas
mz-deploy wait <DEPLOY_ID> # watch clusters hydrate until ready
mz-deploy promote <DEPLOY_ID> # atomic swap into production
compile 无需数据库连接,因此适合在 CI 中于每次提交时运行。compile 成功即可保证 stage 和 apply 不会在 SQL 解析阶段失败。请注意,无论是否指定 --profile,都会验证每个配置文件变体,因此即使运行 compile --profile production,foo#staging.sql 中的语法错误仍会导致失败。
此外:list 会显示尚未提升的部署(类似 git branch),describe <ID> 会显示某个部署的详细信息,log 会显示提升历史(类似 git log),而 abort <ID> 会销毁暂存部署,但不会提升它。
核心概念
apply 管理基础设施;stage 管理视图。 apply 采用声明式、基于差异且幂等的方式,按依赖顺序收敛集群、角色、网络策略、密钥、连接、源和表。stage 负责视图和物化视图。stage 绝不会创建表和源——它们必须已存在,因此要先运行 apply。delete <type> <name> 是 apply 的逆操作:删除一个对象,不使用 CASCADE,并移除其项目文件。
部署 ID 和暂存后缀。 每次部署都会获得一个 ID,默认取当前提交 SHA 的前 7 个字符,用于为其架构和集群添加后缀(public → public_abc123)。暂存集群会从对应生产集群克隆配置,包括任何自动扩缩策略,因此暂存对象的填充方式与生产环境一致。暂存与生产环境并行运行,彼此隔离。
基于哈希检测变更。 stage 会将每个对象的 SQL 哈希与上次提升的快照进行比较,只部署发生变更的对象及其下游对象。未变更的对象不会重新创建。可使用 --redeploy-schema <db.schema> 或 --redeploy-all 覆盖此行为。
提升操作是原子且可恢复的。 promote 会在单个事务中对架构和集群执行 ALTER … SWAP,随后进行后续处理:创建延迟创建的接收器、应用替换 MV、将接收器重新指向新的生产对象,并删除旧资源。如果进程中途退出,重新运行相同命令会检测到交换后的状态并继续清理。
接收器延迟到 promote 时创建。 部署上线前,接收器不得开始生成数据,因此 stage 会记录它们,并由 promote 创建。
冲突检测以架构和集群为粒度。 由于整个架构会作为一个整体交换,两个部署只要触及相同的任何架构或集群就会冲突,即使它们修改的是其中不同的对象。先提升的部署会成功;后提升的部署会被拒绝,必须针对当前生产环境重新暂存。--force 会跳过检查,但这样做会删除另一个部署者的架构,因为架构是整体交换而非合并。仅当确实打算覆盖对方工作时才使用此选项。
稳定 API 架构。 默认情况下,变更对象会在暂存环境中重新创建,并交换整个架构。这会自动重新部署项目内的依赖对象,但会影响其他 mz-deploy 项目的使用者。在架构 mod 文件中添加 SET api = stable,即可将该架构标记为 API 边界:变更的 MV 会通过 ALTER MATERIALIZED VIEW … APPLY REPLACEMENT 原地更新,从而保留对象身份。任何项目中的下游使用者都无需重新部署。限制:稳定架构中只能包含物化视图,且替换 MV 发生变更时,不会将脏状态传播给其依赖对象。
类型检查离线进行。 compile 和 test 会从 types.lock 读取外部依赖架构。在 project.toml 中将外部对象声明为 dependencies = ["db.schema.table"],并运行 mz-deploy lock 来刷新该文件。通过 CREATE TABLE FROM SOURCE 创建的源表会自动发现,无需声明;apply tables 会自动重新生成锁定文件。
角色。 setup 会创建 materialize_deployer(stage、promote、abort)、materialize_developer(只读部署状态及 dev 覆盖层)和 materialize_monitor。每个用户必须且只能属于其中一个角色——同时持有多个角色会报错。部署、开发和监控应使用不同用户的独立配置文件。
配置文件和各配置文件的配置
配置文件是 profiles.toml 中的命名连接目标,查找顺序为 --profiles-dir、MZ_DEPLOY_PROFILES_DIR,然后是 ~/.mz。当前活动配置文件的查找顺序为 --profile、MZ_DEPLOY_PROFILE,然后是项目根目录中由 mz-deploy profile set 写入并被 Git 忽略的 .mzprofile。内置的 emulator 配置文件始终存在,因此无需任何配置即可使用本地 Materialize 模拟器。
密码支持 ${VAR} 替换,可通过 MZ_PROFILE_<NAME>_PASSWORD 覆盖。sslmode 遵循 PostgreSQL 的术语,环回主机默认为 prefer,其他主机默认为 require;对于 Materialize Cloud,请使用 verify-full。
配置文件的作用不只是选择主机。它还会在编译时选择:
profile_suffix(位于project.toml中)——追加到每个数据库和集群名称后,包括IN CLUSTER引用。分隔符需自行添加:"_staging",而不是"staging"。暂存后缀会逐层叠加(foo→foo_staging→foo_staging_a)。- SQL 变量——在
project.toml中使用[<profile>.variables]定义,可在任意.sql文件中使用 psql 语法引用::name(原始值)、:'name'(带引号的字符串)、:"name"(带引号的标识符)。引用未定义的变量会导致编译失败。 - 文件覆盖——活动配置文件对应的
name#<profile>.sql会替换name.sql。编译时会验证所有变体,不论当前使用的是哪一个,而且所有变体都必须具有相同的主语句类型。视图和物化视图不能使用文件覆盖——请改用 SQL 变量。
回滚
没有回滚命令。请在项目中撤销更改,然后提升结果:
git revert <commit>
mz-deploy stage
mz-deploy promote <DEPLOY_ID>
由于 promote 会以原子方式交换,回滚提升本身也是原子的——生产环境会在单个事务中切回。
单元测试
mz-deploy test 会运行与所测试视图写在同一个 .sql 文件中的测试,使用 EXECUTE UNIT TEST 和模拟依赖项。此语法为 mz-deploy 专用,未在其他地方记录——完整语法、示例和失败情形请参阅references/unit-tests.md。
注意事项
- **
stage要求 Git 工作区干净。**请提交更改、暂存更改,或传入--allow-dirty。 - 在 RBAC 下,
setup只需运行一次,但需要超级用户权限。 test和explain需要 Docker,并会在主机上共用一个名为mz-deploy-sandbox的容器。容器按名称而非镜像复用,因此在运行docker rm -f mz-deploy-sandbox之前,--docker-image不会生效。- **
delete不会级联删除。**如果存在依赖项,操作会失败,并保留项目文件。 - **
dev不会将目标设为生产集群。**请配置专用的开发集群。 - **配置文件中的
cluster选项会被忽略。**mz-deploy 会将每个连接固定到自己的内部_mz_deploy_server集群;如有需要,可通过标准的ALTER CLUSTER调整其大小。 - **
stage失败时会自动回滚。**传入--no-rollback可保留部分部署以便调试,然后使用abort清理。 - 过期的
target/缓存可能导致令人困惑的编译错误或类型错误。请运行mz-deploy clean。