关于 atlas-mysql
这是面向 Atlas MySQL 和 MariaDB 模式管理的专项技能,供处理数据库结构与迁移的 Agent 使用。内容补充通用 Atlas 工作流之外的引擎行为、边缘情况、恢复和测试指引。
主要功能
- 01模式范围与开发数据库指南
- 02用户、角色和权限指南
- 03HCL 模式与对象参考
- 04迁移失败恢复指南
- 05lint、模式和迁移测试
适用场景
- 01选择 MySQL 服务器或模式范围
- 02审查会重建表或阻塞表的变更
- 03恢复部分执行的迁移
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ariga/ atlas --skill atlas-mysql安装后在 Claude Code 中输入/atlas-mysql确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/custom-rules.mddev-database.mdhcl.mdmigrations.mdobjects.mdsecurity.mdtesting.md详细介绍
MySQL 的 Atlas
Atlas 管理架构时,MySQL 和 MariaDB 有哪些特定之处。atlas 技能涵盖工作流和命令;本技能涵盖 MySQL 特有的规则、边缘情况和解答。MariaDB 的不同之处也会在此介绍。不涵盖 TiDB、PlanetScale 和 SingleStore 等兼容 MySQL 的引擎。
文件
本技能由 SKILL.md 和 references/ 下的七个参考文件组成,每个文件均可通过
https://atlasgo.io/skills/atlas-mysql/references/<name> 获取。任务需要时,请阅读相应参考文件:
| 文件 | 阅读内容 |
|---|---|
references/dev-database.md | 开发数据库 URL 及其适用范围、atlas tool docker、docker 块、字符集和排序规则、RDS、Cloud SQL、Azure、MariaDB、连接 URL |
references/security.md | 用户和角色、主机、GRANT 和 REVOKE、密码、角色激活 |
references/objects.md | 哪些对象需要登录、枚举和集合、外键索引、检查约束、生成列、函数和触发器、规范化定义、MariaDB |
references/hcl.md | 用 HCL 编写架构:NOT NULL 默认值、默认值和 ON UPDATE、AUTO_INCREMENT、类型、索引、引擎、分区、视图、例程、种子数据 |
references/migrations.md | MY* lint 发现的问题、表复制、部分失败及恢复、分隔符、锁、修订表、基线 |
references/testing.md | 测试每项变更:架构测试、使用种子行的迁移测试、CI |
references/custom-rules.md | 当没有分析器能覆盖某项检查时,如何用 HCL 规则语言编写自定义 lint 规则:谓词、运算符、各 MySQL 对象公开的内容、示例 |
要求
需要安装 atlas 技能,并与本技能放在同一目录(../atlas/SKILL.md)。如果缺少该文件,请下载
https://atlasgo.io/skills/atlas/SKILL.md 到 ../atlas/SKILL.md,并将其 Files 部分列出的每个参考文件下载到
../atlas/references/<name>。
规则
- 先使用
atlas whoami检查登录状态。如果显示未登录,请让用户运行atlas login: 未登录时,Atlas 无法看到视图、触发器、存储过程、函数、分区、用户和授权。 没有账户的用户可以通过atlas login开始免费试用。 - 根据架构包含的内容选择 URL 作用域:
- 在 MySQL 中,架构就是数据库。架构作用域的 URL 路径中包含数据库:Atlas 管理该数据库,并写入未限定名称的语句(
users)。服务器作用域的 URL 路径中不含数据库:Atlas 涵盖所有数据库,并为每条语句添加限定名称(app.users)。 - 用户和角色属于服务器,因此管理它们需要使用服务器作用域。管理多个数据库以及跨数据库外键也需要服务器作用域。
- 在服务器作用域下,期望状态中未声明的数据库会被计划执行
DROP DATABASE。 - 开发数据库 URL 使用与目标相同的作用域:
docker://mysql/8/dev或docker://mysql/8。
- 在 MySQL 中,架构就是数据库。架构作用域的 URL 路径中包含数据库:Atlas 管理该数据库,并写入未限定名称的语句(
- 开发数据库应使用目标数据库的版本和设置:字符集、排序规则、
lower_case_table_names、sql_mode和explicit_defaults_for_timestamp。docker块会固定镜像(image = "mysql:8.4"),并使用目标数据库的设置启动服务器(command)。对于 MariaDB,请使用 MariaDB 开发数据库。在 RDS 上,创建 IAM 用户(IDENTIFIED WITH AWSAuthenticationPlugin)的迁移需要使用带有该插件模拟实现的开发镜像(references/dev-database.md)。切勿将dev指向真实环境的数据库。 - 在每个
schema块中声明charset和collate。否则,期望状态会采用开发服务器的默认值;MySQL 8 的默认值为utf8mb4_0900_ai_ci。如果目标使用其他默认值,架构作用域的计划会因modify schema错误而失败(references/dev-database.md)。 - 管理用户和角色需要使用服务器作用域,并设置
mode { roles = true }。MySQL 没有external属性,因此未声明的账户会被计划删除,包括 Atlas 用于连接的用户:声明该用户,检查首个计划中是否包含其他账户,并在skip差异策略中设置drop_user和drop_role,以避免计划删除操作。授予的角色只有在执行SET DEFAULT ROLE后才会生效(references/security.md)。 - MySQL 和 MariaDB 不支持事务性 DDL:每条 DDL 语句都会单独提交,因此迁移文件或计划若在中途失败,会停留在只应用了一部分的状态,
--tx-mode也无法避免这种情况。请保持文件精简,并在应用前进行测试(规则 9)。如需恢复,请修复失败的语句及其后的语句,然后运行atlas migrate hash;或者使用atlas migrate down撤销已应用的语句(references/migrations.md)。 - 对大型表应用更改前,务必检查每条
MY1*lint 发现:这些更改可能会复制或重建表,也可能阻止写入。请在末尾添加 enum 和 set 值,优先使用VIRTUAL生成列,并检查engine编辑(references/migrations.md)。 - 始终使用开发数据库 URL 生成计划。如果未指定,Atlas 会比较 MySQL 改写后的定义(例如
_utf8mb4引导符),并可能计划删除 MySQL 为外键创建的索引(references/objects.md)。 - 养成在报告完成前测试每项更改的习惯。运行
atlas schema validate;为新增或修改的每个函数、过程、触发器、视图、生成列或检查约束添加一个test "schema"用例;为每个移动或转换数据的迁移添加一个包含预置行的test "migrate"用例。使用atlas schema test和atlas migrate test运行测试(references/testing.md)。 - 如果没有内置分析器能覆盖某项检查,请使用 HCL 规则语言编写自定义 lint 规则;对于用户提出的约定(例如允许使用的字符集或确定性函数)也应如此。规则可以检查 Atlas 检查的任意对象的任意属性,lint 会对每项更改强制执行该规则(
references/custom-rules.md)。
快速解答
| 问题 | 解答 |
|---|---|
| 用于应用迁移的本地 MySQL 数据库 | atlas tool docker --url "docker://mysql/8/myapp" --name my-db 会打印其 URL;atlas tool docker kill --name my-db 会停止它(references/dev-database.md) |
modify schema "..." is not allowed when migration plan is scoped to one schema | 开发数据库的字符集、排序规则或注释与目标不同(references/dev-database.md) |
| 每个表都显示字符集或排序规则变更 | 开发服务器的默认值影响了期望状态:在架构中声明这些值,或使开发服务器与目标保持一致(references/dev-database.md) |
差异仅体现在 _latin1 或 _utf8mb4 上的漂移 | 通过 command 使用目标的字符集启动开发服务器(references/dev-database.md) |
| 表名总是显示为已更改 | 开发服务器的 lower_case_table_names 与目标不同(references/dev-database.md,服务器版本和设置) |
计划删除其他数据库(DROP DATABASE) | 服务器范围涵盖所有数据库:使用 --schema 限制运行范围,或使用架构范围(references/dev-database.md) |
Error 1046: No database selected | 通过服务器范围的 URL 应用架构范围的计划(references/dev-database.md) |
cannot use HCL with more than 1 schema when dev-url is limited to schema | 使用服务器范围的开发 URL:docker://mysql/8(references/dev-database.md) |
迁移在中途失败,而 migrate status 显示 (last one partially) | MySQL 保留了失败前的语句:修复其余部分并运行 atlas migrate hash,或使用 atlas migrate down 撤销它们(references/migrations.md) |
| 重命名显示为删除和新增 | 使用 renamed_from 声明重命名,否则数据会丢失(references/hcl.md) |
Lint 报告 MY1* 检查项 | 此变更会复制或重建表,或阻止写入。若要避免复制,可在手写文件中强制使用 ALGORITHM=INSTANT,或使用在线架构变更工具(references/migrations.md,表复制) |
Error 1553 (HY000): Cannot drop index ...: needed in a foreign key constraint | 使用开发 URL 创建计划,或声明外键的索引(references/objects.md) |
| 检查或计划中始终不显示外键 | 该表使用 MyISAM,它会忽略外键:请使用 InnoDB(references/objects.md) |
Error 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA ... | 设置 deterministic 或 data_access,或启用 log_bin_trust_function_creators(references/objects.md) |
删除枚举值失败,或使行变成 '' | 严格 sql_mode 会因行中存在该值而报错,非严格模式则会将其置空:请先更新这些行(references/objects.md) |
Error 1826 或 Error 3822,约束名称重复 | 外键和检查约束名称在数据库内唯一,而非在表内唯一(references/objects.md) |
Error 1059 (42000): Identifier name ... is too long | 名称最长为 64 个字符:请明确指定索引或约束名称(references/objects.md) |
在 RDS 上,DEFINER 子句报 Error 1227 (42000): Access denied | 从迁移文件中移除 DEFINER 子句(references/objects.md) |
加载视图时出现 Error 1146 (42S02): Table ... doesn't exist | 该视图读取了另一个数据库:在开发 baseline 中创建它,或使用服务器范围(references/objects.md) |
IDENTIFIED WITH mysql_native_password 在开发数据库上失败 | MySQL 8.4 会禁用此插件,9.0 会将其移除:请使用与目标版本相同的版本运行开发数据库(references/dev-database.md) |
时间戳出现 Error 1067: Invalid default value | 使用 sql("current_timestamp(6)") 编写默认值,并与列的精度一致(references/hcl.md) |
列未经要求就变成了 NOT NULL | 除非设置 null = true,否则 HCL 列均为 NOT NULL(references/hcl.md) |
ERROR 1170 (42000): BLOB/TEXT column ... used in key specification without a key length | 为索引部分设置 prefix(references/hcl.md) |
| 计划删除架构未声明的用户或角色 | 声明它们,或使用 drop_user 和 drop_role 跳过删除(references/security.md) |
| 已授予的角色不起作用 | 在 MySQL 上,运行 SET DEFAULT ROLE ALL TO 'user'@'host',或启用 activate_all_roles_on_login。在 MariaDB 上,用户只有一个默认角色:SET DEFAULT ROLE <role> FOR 'user'@'host'(references/security.md) |
创建 RDS IAM 用户的迁移出现 Error 1524 (HY000): Plugin 'AWSAuthenticationPlugin' is not loaded | 使用该插件的模拟版本构建开发镜像,并通过 atlas tool docker --env <env> 从该镜像启动本地数据库(references/dev-database.md,开发数据库上的 RDS IAM 用户) |
invalid port ":..." after host | 对密码进行百分号编码,或使用 urlescape 构建 URL(references/dev-database.md) |
server does not allow insecure connections, client must use SSL/TLS | 在 URL 中添加 ?tls=true(references/dev-database.md) |
| 同一服务器上的数据库始终无法并行应用 | 它们共享默认锁名称:为每个目标设置 lock_name(references/migrations.md) |
文档
- MySQL HCL 参考:https://atlasgo.io/hcl/mysql;MariaDB 参考:https://atlasgo.io/hcl/mariadb
- 开发数据库:https://atlasgo.io/concepts/dev-database
- 安全性:https://atlasgo.io/guides/mysql/security-declarative, https://atlasgo.io/guides/mysql/security-versioned
- Lint 检查:https://atlasgo.io/lint/analyzers
- 各数据库指南:https://atlasgo.io/databases
评论
支持 Markdown